Quiz Entry - updated: 2026.07.14
Which registers must be preserved across function calls (callee-saved vs. caller-saved)?
Callee-saved registers (%rbx, %rbp, %r12–%r15) must survive a call — the called function saves and restores them; caller-saved registers may be freely clobbered.
* Callee-saved registers (%rbx, %rbp, %r12-%r15) must be preserved by the called function; caller-saved ones may be clobbered, so the caller saves what it still needs. *
The calling convention splits the registers so that the caller and callee don't both try to use the same one and corrupt each other. The deal is:
| Callee-saved (survive a call) | Caller-saved (may be clobbered) |
|---|---|
| %rbx, %rbp | %rax (return value) |
| %r12, %r13, %r14, %r15 | %rcx, %rdx, %rsi, %rdi |
| %rsp (the stack pointer) | %r8–%r11 |
What it means in practice:
- Callee-saved: if a function wants to use
%rbx, it mustpushit on entry andpopit before returning, leaving it as it found it. - Caller-saved: if you have a value in
%raxthat you need after a call, you must save it first, because the callee is allowed to trash it.
my_func:
push %rbx # save callee-saved register
mov %rdi, %rbx # now safe to use %rbx
call other_func # %rbx is preserved across this call
mov %rbx, %rax
pop %rbx # restore before returning
ret
Go deeper:
x86 calling conventions (Wikipedia) — the callee-saved vs caller-saved register split of the System V ABI.