Assembly
x86-64 Registers and Calling Convention
Register Architecture
General purpose registers (64-bit):
- rax — Accumulator, return values, syscall numbers
- rbx — Base (callee-saved)
- rcx — Counter, 4th function argument
- rdx — Data, 3rd function argument
- rsi — Source index, 2nd function argument
- rdi — Destination index, 1st function argument
- rbp — Base pointer (callee-saved)
- rsp — Stack pointer (callee-saved)
- r8-r15 — Additional general purpose (r8, r9 for args 5-6; r12-r15 callee-saved)
Register subsets — each wider register contains the narrower ones:
text
rax (64-bit)
└─ eax (lower 32 bits)
└─ ax (lower 16 bits)
├─ ah (upper 8 bits of ax)
└─ al (lower 8 bits)Linux x64 Calling Convention
Function arguments (first 6 in registers, 7+ passed on stack, right-to-left):
rdi— First argumentrsi— Second argumentrdx— Third argumentrcx— Fourth argumentr8— Fifth argumentr9— Sixth argument
Return value: always in rax.
Register preservation:
- Caller-saved (can be destroyed by the called function):
rax, rcx, rdx, rsi, rdi, r8, r9, r10, r11— caller must save these beforecallif the values are needed after - Callee-saved (must be preserved by the called function):
rbx, r12, r13, r14, r15, rbp, rsp— the function must push/pop these if it uses them
System Calls
- Use the
syscallinstruction (notint 0x80) rax= syscall number- Arguments in
rdi, rsi, rdx, r10, r8, r9— noter10instead ofrcx, sincercxis clobbered by thesyscallinstruction itself - Return value in
rax
Example of opening the file:
asm
mov rax, 2 ; syscall number: sys_open
mov rdi, [rsp + 16] ; arg1: filename (pointer from argv[1])
xor rsi, rsi ; arg2: flags = 0 (O_RDONLY)
syscall ; rax = fd (>= 0) or negative errno
test rax, rax ; set flags: SF=1 if fd is negative
jl open_error ; jump if rax < 0 (error)Common syscalls:
| Syscall | Number |
|---|---|
sys_read | 0 |
sys_write | 1 |
sys_open | 2 |
sys_close | 3 |
sys_exit | 60 |