5.1.16 · D1C Programming

Foundations — Stack frames — how function calls work at the memory level

2,365 words11 min readBack to topic

0. What is "memory" even? (the strip)

Before any of the fancy words, you need ONE picture: computer memory is a very long row of numbered boxes. Each box holds one byte (a small number), and each box has an address — its house number.

Figure — Stack frames — how function calls work at the memory level

Why do we need addresses at all? Because to come back to a variable — or to a line of code — you must be able to name where it lives. That single need (naming a location) is the seed of the whole topic. You'll meet addresses again in depth in Pointers and addresses in C.


1. The register — a box the CPU keeps in its pocket

Main memory (the long strip) is far away and slowish. The CPU keeps a handful of ultra-fast boxes inside itself called registers. There are only a few, each with a name.


2. The stack — a strip you only touch at one end

Take the memory strip and agree on a rule: we only ever add or remove slots at one end. That disciplined strip is the stack.

Figure — Stack frames — how function calls work at the memory level

3. The stack pointer — the marker on the top

Now give the "top of stack" a name. is a register holding the address of the current top slot.


4. Function, call, and the return address

Here is the problem that forces the next symbol into existence: when the CPU jumps into a function, how does it remember the line to jump back to?

Figure — Stack frames — how function calls work at the memory level

5. The stack frame — one function's private desk

Bundle together everything ONE call needs, and you have its frame.


6. The base pointer — a nail in the desk

keeps moving (every push during the function shifts it). So addressing "my third local" as "SP minus something" is a moving target. Fix a second marker that stays put for the whole call: the base/frame pointer .

Figure — Stack frames — how function calls work at the memory level

7. Prologue & epilogue — the fixed opening and closing moves


Putting the symbols in order (prerequisite map)

Read this map bottom-up. The leftmost roots are the raw ideas from section 0 (memory boxes and addresses). They feed into the stack (a disciplined strip), which needs two register markers — (top) and (fixed base). Those markers, plus the return address, are exactly what a stack frame bundles together, and the prologue/epilogue rituals are what every function performs on that frame. Follow any arrow: it means "you need the earlier idea to understand the later one."

memory strip of numbered boxes

address = a box number

slot = w bytes taped together

stack = one-end-only strip

register = fast box in CPU

LIFO from nested calls

SP marks top of stack

return address

stack frame per call

BP nails frame base

prologue and epilogue

Stack Frames topic


  • Frames live on the stack; longer-lived data lives elsewhere — see Heap vs Stack memory.
  • Overwrite a return address on the stack and you can hijack control — Buffer overflow & return-address smashing.
  • Deep nesting is Recursion; the raw addresses are Pointers and addresses in C.

Equipment checklist

Cover the right side and answer aloud.

A byte is...
one storage box in memory holding a small number.
An address is...
the house-number (an integer) identifying a memory box; bigger = further along.
A slot is...
a fixed run of w adjacent bytes/boxes treated as one unit (e.g. 4 bytes for an int).
A register is...
a fast named storage box inside the CPU (e.g. SP, BP, LR).
The stack is...
a memory region you only add to / remove from at one end.
"push" does what to SP (downward stack)?
decreases SP by one slot size w, then writes the value there.
"pop" does what to SP?
reads at SP, then increases SP by w — logically discarding the top slot.
LIFO stands for and comes from...
Last In, First Out; it comes from function lifetimes nesting perfectly.
The stack pointer SP holds...
the address of the current top of the stack.
The base pointer BP holds...
a fixed reference address inside the current frame, for constant-offset access.
A return address is...
the address of the instruction to run after the called function finishes.
What does x86 CALL do?
jumps into the function and pushes the return address onto the stack.
What does x86 RET do?
pops the saved return address and jumps back to it.
What do ARM BL / RISC-V JAL do?
jump into the function and put the return address in a register (LR), not the stack.
A stack frame contains...
one call's locals, arguments, saved registers, and the return address.
addr(local_k) = ... and why?
BP − offset; locals sit below BP because the stack grows to lower addresses.
addr(arg_k) = ... and why?
BP + offset; args were pushed before BP, so they sit at higher addresses.
Why save the caller's BP on entry?
BP is a single shared register; saving/restoring lets the caller keep its own frame.
Prologue does...
save old BP, set BP = SP, carve local space (SP −= N).
Epilogue does...
SP = BP, restore old BP, RET.