Quiz Entry - updated: 2026.07.14
What does a typical function prologue and epilogue look like in x86-64?
The prologue sets up the function's stack frame (save %rbp, point it at the frame, reserve locals); the epilogue tears it back down before ret.
Every non-trivial function brackets its body with this setup/teardown so that the stack is left exactly as it was found.
With a frame pointer:
func:
push %rbp # save caller's frame pointer
mov %rsp, %rbp # establish this frame's base
sub $32, %rsp # reserve space for locals
... # function body
leave # == mov %rbp,%rsp ; pop %rbp
ret
Without a frame pointer (optimized): the compiler often skips %rbp entirely and just adjusts %rsp:
func:
sub $24, %rsp # reserve locals
...
add $24, %rsp # release them
ret
Alignment subtlety: %rsp must be 16-byte aligned before a call. Since call itself pushes an 8-byte return address, a function begins with %rsp at 8 mod 16 — which is why local-space allocations are sized to restore 16-byte alignment before the next call.
Go deeper:
Call stack (Wikipedia) — stack frames, frame pointers, and the save/restore bracketing.