LOGBOOK

HELP

Quiz Entry - updated: 2026.07.14

What are callee-saved vs caller-saved registers in x86-64?

Callee-saved registers (%rbx, %rbp, %r12–%r15) must be preserved by any function that uses them; caller-saved registers may be freely overwritten, so the caller must save anything it still needs.

The convention partitions the registers to settle "who is responsible for preserving what" across a call, preventing two functions from silently clobbering each other.

Category Registers Responsibility
Callee-saved %rbx, %rbp, %r12–%r15 the callee must save/restore if it uses them
Caller-saved %rax, %rcx, %rdx, %rsi, %rdi, %r8–%r11 the caller must save them before a call if needed after
Special %rsp the stack pointer (always preserved)

Why it matters, concretely:

void caller() {
    long x = compute();    // suppose x lives in %rbx (callee-saved)
    other_function();      // %rbx is guaranteed intact across this call
    use(x);                // x is still valid
}

If x had been in a caller-saved register like %rax, other_function() would have been free to overwrite it.

foo:
    pushq %rbx        # save callee-saved regs the function will use
    pushq %r12
    ...               # body
    popq  %r12        # restore before returning
    popq  %rbx
    ret

Reverse-engineering tip: values placed in callee-saved registers are usually locals the function needs to keep across its own calls.

Go deeper:

From Quiz: REVE1 / The Processor Interface | Updated: Jul 14, 2026