x86-64
registers, the calling convention, and the instructions i actually type. intel/nasm order throughout: op dst, src.
jump to: registers · calling convention · instructions · addressing · conditions
registers
64 32 16 8 role (sysv)
rax eax ax al return value
rdi edi di dil arg 1
rsi esi si sil arg 2
rdx edx dx dl arg 3 (also 2nd return)
rcx ecx cx cl arg 4
r8 r8d r8w r8b arg 5
r9 r9d r9w r9b arg 6
r10 r10d r10w r10b scratch
r11 r11d r11w r11b scratch
rbx ebx bx bl callee-saved
rbp ebp bp bpl frame pointer (callee-saved)
rsp esp sp spl stack pointer
r12 r12d r12w r12b callee-saved
r13 r13d r13w r13b callee-saved
r14 r14d r14w r14b callee-saved
r15 r15d r15w r15b callee-saved
rip--; instruction pointer;rflags--; status flags (ZF, SF, CF, OF, ...)xmm0–xmm15--; 128-bit sse registers for floats/vectors- legacy
ah, bh, ch, dhalias the high byte of the first four
calling convention (sysv amd64)
linux and macos. windows x64 differs (rcx, rdx, r8, r9).
- integer/pointer args, in order:
rdi, rsi, rdx, rcx, r8, r9--; the rest go on the stack, pushed right-to-left - float args:
xmm0–xmm7 - return value:
rax(rdx:raxfor 128-bit); floats inxmm0 - callee-saved (you must restore):
rbx, rbp, rsp, r12, r13, r14, r15 - caller-saved (scratch):
rax, rcx, rdx, rsi, rdi, r8, r9, r10, r11 - stack must be 16-byte aligned at the
call; leaf functions get a 128-byte red zone belowrsp - note: syscalls differ --; number in
rax, args inrdi, rsi, rdx, r10, r8, r9(see interrupts)
common instructions
- data:
movcopy,movzx/movsxzero/sign-extend,leaaddress math,xchgswap - stack:
push,pop,call,ret,leave - arithmetic:
add,sub,inc,dec,neg,imul/idiv(signed),mul/div(unsigned) - bits:
and,or,xor,not,shl/sal,shr,sar,rol/ror - compare:
cmp a, bsets flags fora − b;test a, bsets flags fora & b - control:
jmp, conditionaljcc(below),call/ret,syscall,nop
; int add(int a, int b) { return a + b; } (sysv)
add:
lea eax, [rdi + rsi] ; a in edi, b in esi -> eax
ret
addressing modes
- immediate --;
mov rax, 5 - register --;
mov rax, rbx - memory --;
mov rax, [rbx] - base + displacement --;
[rbx + 8] - base + index*scale + disp --;
[rbx + rcx*4 + 8], scale ∈ {1, 2, 4, 8} - rip-relative --;
[rel label](nasm) or[rip + label]
conditions (jcc after cmp)
- equal:
je/jz; not equal:jne/jnz - signed:
jg(>),jge(≥),jl(<),jle(≤) - unsigned:
ja(>),jae(≥),jb(<),jbe(≤) - flags:
js/jns(sign),jo/jno(overflow),jc/jnc(carry)