1.17 - Calling Conventions (Linux)

X86 (32-bit, Linux)

Cdecl (default)

  • Arguments: pushed on the stack right to left
  • Return value: EAX
  • Stack cleanup: caller (add esp, N)
  • Callee-saved registers: EBX, ESI, EDI, EBP
  • Caller-saved registers: EAX, ECX, EDX

Stack layout (before call):

[esp]   argN (last pushed, lowest address)
[esp+4] argN-1
...
[esp+4*(n-1)] arg1

Example:

push 3        ; arg2
push 2        ; arg1
call func
add esp, 8    ; caller cleans up

Linux Syscalls (int 0x80)

  • Syscall number: EAX
  • Arguments: 1 → EBX 2 → ECX 3 → EDX 4 → ESI 5 → EDI 6 → EBP
  • Return value: EAX

Example:

mov eax, 1      ; sys_exit
mov ebx, 0      ; status
int 0x80

x86-64 (Linux, System V AMD64 ABI)

Function Calls

  • Arguments (register order): 1 → RDI 2 → RSI 3 → RDX 4 → RCX 5 → R8 6 → R9 Remaining args: stack (right to left)
  • Return value: RAX
  • Stack cleanup: caller
  • Stack alignment: stack pointer (RSP) must be 16-byte aligned at the call instruction
  • Callee-saved registers: RBX, RBP, R12R15, RSP
  • Caller-saved registers: RAX, RCX, RDX, RSI, RDI, R8R11

Stack layout (at call entry):

[RSP]      return address
[RSP+8]    possible spill slots for extra args

Example:

mov rdi, 2     ; arg1
mov rsi, 3     ; arg2
call func
; result in RAX

Linux Syscalls (x86-64, Syscall instruction)

  • Syscall number: RAX
  • Arguments: 1 → RDI 2 → RSI 3 → RDX 4 → R10 5 → R8 6 → R9
  • Return value: RAX

Example:

mov rax, 60    ; sys_exit
mov rdi, 0     ; status
syscall

Quick Reference Table

PlatformFunction args orderSyscall args orderReturnNotes
x86stack (LeftRight)EBX, ECX, EDX, ESI, EDI, EBPEAXCaller cleans stack
x86-64 SysVRDI, RSI, RDX, RCX, R8, R9RDI, RSI, RDX, R10, R8, R9RAXStack 16-byte aligned

Tips for Reversing

  • On 32-bit, look for pushes before calls; on 64-bit, look for register moves into RDI, RSI, etc.
  • If you see int 0x80, you’re in 32-bit syscall land. If you see syscall, you’re in 64-bit.
  • If the stack is adjusted to maintain 16-byte alignment (sub rsp, 8), that’s a sign you’re in x86-64 System V ABI.
  • Preserved (callee-saved) registers usually hold values across calls; volatile (caller-saved) can be trashed by function calls.

Resources