Pseudo document
(The real document is at https://nasm.us/doc/nasmdoc0.html
The definitions of Assembly language, Assembler and Netwide Assembler
- Assembly is a set of such much Assemblers that is used to take down the script so that you can control the hardware things in the computer like Central Processing Unit, Remote Access Memory, storage, registers and a lot more about things in a computer.
-
An Assembler is a low-level language that is used to take down the script in order to compile it into machine code.
Therefore, the computer can understand it and execute the script by itself.
Please note that the computer cannot understand any languages with the exception of only two numbers: 0 and 1
Some standout Assemblers for instance:
- AT&T Syntax: GNU Assembler (GAS), Clang/Low-level Virtual Machine's built-in Assembler...;
- Intel syntax: Microsoft Assembler (MASM), Flat Assembler (FASM),...
-
Netwide Assembler is an Assembler that use Intel Syntax for taking down the script. It has some features like:
- Can run on multiple platfroms 📂;
- Compile directly into machine code; 💻
- Super fast 🚀;
- Run natively in the local computer, a good language for programming drivers, bootloaders, and...WebAssembly? (Seriously, I am learning how to build a compiler in order to compile NASM into WASM, even though it has not done yet);
- 👉 It is an easy Assembler for Newbie to learn, although it has a high difficulty for people to learn;
- Fun fact: Netwide Assembler is also a Kali Tool. You can check it here
⚠️ NOTE: It is recommended to learn how to program C language before programming this one, as I might use C syntax in order to perform the Netwide Assembler command for everyone to understand.
Establishment for Netwide Assembler language
Due to the high difficulty of installing this thing on Windows and MacOS, I will tell you how to do it on those platform later
Install Netwide Assembler compiler:
On Linux, Windows Subsystem for Linux or msys2
:
For Ubuntu, Debian, Kali, Mint,...(Debian-based):
Update apt
, then install nasm
compiler:
sh Shell
Copy
sudo apt update && sudo apt install nasm
For MSYS2, Arch Linux or Linux distro that uses pacman-package-manager (Arch-based):
Update pacman
, then install nasm
compiler:
sh Shell
Copy
sudo pacman -Syu && sudo pacman --sync nasm
For Red Hat Linux or the Linux distro that uses yum
package manager (RPM-based):
Update yum
, then install nasm
compiler:
sh Shell
Copy
sudo yum -y update && sudo yum install nasm
Check off whether NASM is downloaded:
sh Shell
Copy
nasm --version # It should output "NASM version <version>"
ndisasm -v # -- It should output "NDISASM version <version>"
Set up a new Intergrated Develop Environment in order to take down Netwide Assembler script easier
Please see my contents about Visual Studio Code, CoC and Neovim
Create your first Netwide Assembler source code
We will use Neovim for example to open a file. However, you can also open it using Vim or VS Code:
sh Shell
Copy
nvim main.nasm
Then type:
Plaintext
Copy
printHello
or ph, pH,...
anything that relates to snippet printHello
.
nvim-cmp
will appear the snippet printHello
for you.
It should output this script after choosing that snippet:
NASM
Copy
%macro exit 1
mov rax, 60
mov rdi, %1
syscall
%endmacro
%macro getstr 2
mov rax, 1
mov rdi, 1
mov rsi, %1
mov rdx, %2
syscall
%endmacro
section .data
example db 0x1b, "[1;38;2;255;165;0m", "Hello world", 0x1b, "[0m", 0xA
length equ $-example
section .text
global _start
_start:
getstr example, length
exit 0
Then use nasm
to compile your Netwide Assembler file:
sh Shell
Copy
nasm -f elf64 main.nasm -o main.o # Compile NASM file into an object file using specified format
ld main.o -o main # Link the object file to the binary, then make a binary file
Attention: You need to choose right format type in order to make the binary work.
According to nasm -hf
instructions, we have some format like this:
win32 (legacy alias: win)
: For Windows 32-bitwin64
: For Windows 64-bitmacho32 (legacy alias: macho)
: For Mach-O i386 MacOS X and variants (32-bit)macho64
: For Mach-O x86_64 MacOS X and variants (64-bit)elf32 (legacy alias: elf)
: For x86 Linux distros (32-bit)elf64
: For x86-64 Linux distros (64-bit)bin
: For flat RAW binary file. You should not use over 16-bit Netwide Assembler syntax for this type as BIOS real-mode cannot load greater than or equal to 32-bit registers.
Disassemble a RAW binary file (.bin, .hex) using ndisasm
Create an raw binary file. For instance: (ATTENTION: THIS IS THE COMMAND FOR x86-64 PROCESSOR MODE)
sh Shell
Copy
echo -ne '\x48\xb8\x01\x00\x00\x00\x00\x00\x00\x00\x48\xbf\x01\x00\x00\x00\x00\x00\x00\x00\x48\xbe\x00\x10\x60\x00\x00\x00\x00\x00\x48\xba\x0c\x00\x00\x00\x00\x00\x00\x00\x0f\x05\x48\xb8\x3c\x00\x00\x00\x00\x00\x00\x00\x48\x31\xff\x0f\x05' > main.bin
Disassemble a RAW binary file (not real binary files like rm, cp, ls,...
):
sh Shell
Copy
ndisasm -b 64 main.bin # You can use -b 16, 32, 64 if you want to use other preprocessors
If you use 64-bit preprocessor, it should output those texts like this (can be different from different processor modes).
ndisasm's Disassembly result
Copy
00000000 48B8010000000000 mov rax,0x1
-0000
0000000A 48BF010000000000 mov rdi,0x1
-0000
00000014 48BE001060000000 mov rsi,0x601000
-0000
0000001E 48BA0C0000000000 mov rdx,0xc
-0000
00000028 0F05 syscall
0000002A 48B83C0000000000 mov rax,0x3c
-0000
00000034 4831FF xor rdi,rdi
00000037 0F05 syscall
Get started with Netwide Assembler
Not like mid-level and high-level programming languages, NASM is a low-level one and it is much harder to find
documents for learning it. Moreover, before programming this language, you need to know some skills about basic
things to deal with the CPU and compiler.
For more information about the nasm
compiler, please go to the real document page.
However, don't worry if you have learnt many languages with the exeption of C. I also have an alternative one. This is the example clipboard that I will use:
Hello
Copy
int main(void) {
return 0;
}
1. Hexdecimal number and address
Hexdecimal is really important to deal with the data and initialize a value into things like:
- Register: Things in the CPU that can be writen or overwritten a value like hexdecimal integers in order to make an interrupt like you want.
- Memory address: Used as an address to save an array of ASCII characters. This is the only method that helps you print strings.
Memory syntax example in NASM withdefault abs
:[0x601000]
:absolute;[rel msg]
: relative label example address named msg;[msg]
: Label memory address that is defined- NOTE: Some registers like
rsi
does not need square brackets to make it be an address. For instance:
NASM
Copy
; I will tell you how to use the `mov`, `section .data` and `db` commands later mov rsi, msg section .data msg db "Hello world", 0xa, 0x0
- Immediate: An array of ASCII characters that is saved into a label which is an alias of something like integer value and memory address.
NASM
Copy
; I will tell you how to use the `mov` command later
mov ax, 0x5307 ; (16-bit) APM Basic Input/Output System (BIOS) function: Set power state
mov bx, 0x0001 ; (16-bit) Device ID: All devices
mov cx, 0x0003 ; (16-bit) Power State: Off
int 0x15 ; (16-bit) APM Interrupt
NASM
Copy
msg db "Example string", 0xa, 0x0 ; db: Define byte a character or an array of characters, each character takes 1 byte (8-bit)
len equ $-msg ; Calculates the length of the array by subtracting current address by msg label offset
; equ: Define a constant