x86 and x64 Assembly from Scratch
Contents
- 1 π― Objective
- 2 1. Why Learn Assembly for Exploitation?
- 3 2. Architecture Overview: x86 vs x64
- 4 3. Register Classifications
- 5 4. Instruction Types and Syntax (Intel Style)
- 6 5. Addressing Modes and Operand Types
- 7 6. Memory Layout and Stack Anatomy
- 8 7. Calling Conventions
- 9 8. Function Prologue and Epilogue
- 10 9. Flags Register (EFLAGS/RFLAGS)
- 11 10. Interrupts and Syscalls
- 12 11. Loop and String Instructions
- 13 12. Writing Inline Assembly in C
- 14 13. Compiling and Running Pure Assembly
- 15 14. Reverse Engineering and Disassembly
- 16 15. Tools and Emulators
- 17 β Summary
π― Objective
To gain a deep, foundational understanding of how x86 and x64 assembly work, from CPU registers and calling conventions to memory addressing and function calls. This is critical for exploit developers who need precise control over memory, registers, and the instruction pointer.

1. Why Learn Assembly for Exploitation?
Exploit developers operate close to the metal β at the point where programming languages are compiled into instructions the CPU can directly understand. Memory corruptions, ROP chains, shellcode, and low-level payloads require understanding register state, stack layout, and control flow.
In exploit development:
- You overwrite
EIP
orRIP
- You pivot the stack (
ESP
orRSP
) - You inject shellcode and need to place arguments in registers or memory
- You must understand how values are passed and returned at the assembly level
2. Architecture Overview: x86 vs x64
2.1 x86 (32-bit)
- 4-byte registers (e.g.,
eax
,ebx
) - 4GB virtual address space
- Arguments passed via stack
- Used in legacy applications or 32-bit systems
2.2 x64 (64-bit)
- 8-byte registers (
rax
,rbx
) - 64-bit pointers, more addressable memory (up to 18 exabytes)
- First 4 arguments passed in registers (Windows:
rcx
,rdx
,r8
,r9
) - Return values in
rax
2.3 Register Subdivisions
Example (x64):
Register: rax (64-bit)
βββ eax (32-bit)
β βββ ax (16-bit)
β βββ ah (8-bit high)
β βββ al (8-bit low)
3. Register Classifications
Class | Registers (x86/x64) | Description |
---|---|---|
General-purpose | eax , ebx , ecx , edx / rax … | Arithmetic, logic, data movement |
Stack-related | esp , ebp / rsp , rbp | Stack pointer/base pointer |
Instruction | eip / rip | Holds address of next instruction |
Flags | eflags / rflags | Status indicators (ZF, CF, SF) |
Segment | cs , ds , es , ss , fs , gs | Rare in userland, used in kernel |
SIMD/FPU | xmm0βxmm15 , st0βst7 , mm0βmm7 | Vector ops, floating point, MMX |
4. Instruction Types and Syntax (Intel Style)
4.1 Syntax Format
instruction destination, source
4.2 Common Instructions
Category | Example | Meaning |
---|---|---|
Data Move | mov eax, ebx | Copy ebx to eax |
Arithmetic | add eax, 4 | eax += 4 |
Logical | and eax, 0xFF | Clear all but lower byte |
Shift | shr eax, 1 | Shift right (divide by 2) |
Stack | push ebp , pop eax | Push/pull stack values |
Control | call , ret , jmp , je , jne | Control flow |
5. Addressing Modes and Operand Types
5.1 Addressing Types
Mode | Syntax | Example |
---|---|---|
Immediate | Value constant | mov eax, 1 |
Register | CPU register | mov eax, ebx |
Direct Memory | Absolute addr | mov eax, [0x12345678] |
Indirect Memory | Register ptr | mov eax, [ebx] |
Indexed | Base + index | mov eax, [ebp+4] |
5.2 Operand Sizes
BYTE PTR [mem]
: 8-bitWORD PTR [mem]
: 16-bitDWORD PTR [mem]
: 32-bitQWORD PTR [mem]
: 64-bit
6. Memory Layout and Stack Anatomy
Typical process memory layout:
0xFFFFFFFF β Stack Top (grows down)
|
| Stack (local vars, return addr)
|
| Heap (malloc/calloc/free - grows up)
|
| BSS (uninitialized globals)
|
| Data (initialized globals)
|
| Text (code, .text segment - executable)
0x00000000 β Null page
7. Calling Conventions
7.1 cdecl (x86 Linux default)
- Arguments pushed right-to-left
- Return value in
eax
- Caller cleans stack
7.2 stdcall (Windows APIs)
- Callee cleans stack
7.3 fastcall (Microsoft optimized)
- Some args in registers (e.g.,
ecx
,edx
)
7.4 System V AMD64 ABI (Linux x64)
Argument | Register |
---|---|
arg1 | rdi |
arg2 | rsi |
arg3 | rdx |
arg4 | rcx |
arg5 | r8 |
arg6 | r9 |
- Return:
rax
7.5 Windows x64 Calling Convention
Argument | Register |
---|---|
arg1 | rcx |
arg2 | rdx |
arg3 | r8 |
arg4 | r9 |
8. Function Prologue and Epilogue
x86 Example
push ebp
mov ebp, esp
sub esp, XX ; allocate space
...
mov esp, ebp
pop ebp
ret
Why It Matters
- Stack frames are key for local variables
- Exploits often overwrite saved
EIP
/RIP
on stack
9. Flags Register (EFLAGS/RFLAGS)
Flag | Meaning |
---|---|
ZF (Zero Flag) | Set if result is 0 |
CF (Carry Flag) | Set if carry occurred |
SF (Sign Flag) | Set if negative |
OF (Overflow) | Set if signed overflow |
PF (Parity) | Set if result has even parity |
Used with:
cmp
,test
,je
,jg
,jl
,jne
,jz
,jnz
10. Interrupts and Syscalls
Linux (x86):
mov eax, 1 ; syscall number: exit
mov ebx, 0 ; exit code
int 0x80 ; software interrupt
Linux (x64):
mov rax, 60 ; syscall: exit
mov rdi, 0 ; exit code
syscall
11. Loop and String Instructions
Looping
mov ecx, 10
loop_label:
; code
loop loop_label ; decrements ecx, jumps if ecx != 0
String Instructions (with REP prefix)
movsb
,movsw
,movsd
cmpsb
,stosb
,scasb
,lodsb
rep
,repe
,repne
12. Writing Inline Assembly in C
int a = 5, b = 3, result;
__asm__(
"movl %1, %%eax;"
"addl %2, %%eax;"
"movl %%eax, %0;"
: "=r"(result)
: "r"(a), "r"(b)
: "%eax"
);
13. Compiling and Running Pure Assembly
hello.asm (NASM + Linux)
section .data
msg db "Hello!", 0xA
len equ $ - msg
section .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, len
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
nasm -f elf hello.asm
ld -m elf_i386 hello.o -o hello
./hello
14. Reverse Engineering and Disassembly
Use objdump
, Ghidra
, or radare2
:
objdump -d binary
gdb ./binary
Look for:
- Function prologue:
push ebp; mov ebp, esp
- Function calls:
call 0x08048400
- Stack usage:
mov eax, [ebp+0x8]
15. Tools and Emulators
Tool | Use | Link |
---|---|---|
NASM | Write x86 ASM | |
GDB + Pwndbg | Debugging | |
x64dbg | Windows reversing | |
Godbolt | C to Assembly | |
Ghidra | Disassembler | |
Radare2 | RE suite | |
Online x86 Emulator | Run x86 code in browser |
β Summary
- Assembly allows direct control of CPU and memory.
- Key registers (
eax
,esp
,eip
) are critical for understanding control flow and payload placement. - Stack frames, calling conventions, and memory addressing are the basis of buffer overflows and ROP chains.
- Tools like NASM, GDB, x64dbg, and Ghidra will help analyze and write exploits.
0 Comments
Oldest