Pseudo document
The real document is at:
The definitions of Assembly language, Assembler and Netwide Assembler
- 🤔 What is "assembly"?
- Assembly is a set of such many native languages 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.
- 🤔 How about "assembler" and "disassembler"?
-
An assembler is a low-level compiler that is used to take down the script in order to compile it into machine code directly.
Therefore, the computer can understand it and execute the script by itself.
On the other hand, a disassembler is a compiler which disassemble (compile machine code description into assembly) a file.
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 a standalone Assembler for Newbie to learn, despite its high difficulty;
- 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:
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:
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:
Copy
sudo yum -y update && sudo yum install nasm
Check off whether NASM is downloaded:
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:
Copy
nvim main.nasm
Then type: (This step needs who5673-nasm or coc-nasm)
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:
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:
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): Windows 32-bitwin64: Windows 64-bitmacho32 (legacy alias: macho): Mach-O i386 MacOS X and variants (32-bit)macho64: Mach-O x86_64 MacOS X and variants (64-bit)elf32 (legacy alias: elf): x86 Linux distros (32-bit)elf64: x86-64 Linux distros (64-bit)bin: 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 a raw binary file. For instance: (ATTENTION: THIS IS THE COMMAND FOR x86-64 PROCESSOR MODE)
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,...):
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:
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
rsidoes not need square brackets to make it be an address. For instance:
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.
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
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
Integer to Hexdecimal
Take down an integer:
Digits taken down: /21