Quiz Entry - updated: 2026.07.14
How does the compiler handle local variables in assembly?
Locals live on the stack, addressed relative to %rbp or %rsp — unless the optimizer can keep them entirely in registers.
A local variable is just a named slot in the function's stack frame. The compiler assigns each one an offset and reads/writes it there:
long foo(long x) {
long a = x + 1;
long b = a * 2;
return b;
}
foo:
push %rbp
mov %rsp, %rbp
sub $16, %rsp
lea 1(%rdi), %rax # a = x + 1
mov %rax, -8(%rbp) # store a
mov -8(%rbp), %rax # reload a
add %rax, %rax # b = a * 2
mov %rax, -16(%rbp) # store b
mov -16(%rbp), %rax # return b
leave
ret
With optimization, the same function needs no stack at all — both locals stay in registers:
foo:
lea 1(%rdi), %rax # a = x + 1
add %rax, %rax # b = a * 2 (already in return register)
ret
Reverse-engineering tip: seeing values constantly spilled to -N(%rbp) is a hallmark of unoptimized (-O0) code; tight register-only code means the optimizer ran.
Go deeper:
Call stack (Wikipedia) — locals as frame slots addressed relative to the frame pointer.