5.1.16 · HinglishC Programming

Stack frames — how function calls work at the memory level

2,320 words11 min readRead in English

5.1.16 · Coding › C Programming


WHY does this mechanism exist?


HOW a frame is built — step by step (the calling convention)

Exact steps platform par depend karte hain, lekin conceptually har call yeh karta hai:

CALLER:                          CALLEE (the called function):
  1. push arguments              4. push old BP (save caller's frame ref)
     (or load into registers)    5. BP = SP  (BP now marks this frame's base)
  2. CALL f  -> saves the         6. SP -= N  (carve N bytes for local vars)
     return address               7. ... do work, locals at [BP - offset] ...
  3. (execution jumps to f)       8. SP = BP        (drop locals)
                                  9. pop old BP     (restore caller's BP)
                                 10. RET -> uses return address, jumps back
Figure — Stack frames — how function calls work at the memory level

Worked Example 1 — tracing nested calls

int add(int a, int b) {   // frame: a, b, return addr, saved BP
    int s = a + b;        // local s
    return s;
}
int main(void) {
    int x = add(2, 3);    // main's frame holds x
    return 0;
}

Trace (downward stack, x86-style where return addr is pushed):

Event Stack (top = bottom of table)
main mein [ x ]
args push karo [ x ][ 3 ][ 2 ]Kyun? callee ko values chahiye
CALL add [ x ][3][2][ retaddr ]Kyun? taaki add jaane kahan return karna hai
add prologue [ x ][3][2][retaddr][ saved BP ][ s ]Kyun? caller frame save karo + local carve karo
add 5 return karta hai jo kuch add ne add kiya use pop karo → SP args ke baad wapas; result 5 ek register mein
main store karta hai x = 5

Worked Example 2 — recursion piles frames

int fact(int n) {
    if (n <= 1) return 1;        // base case
    return n * fact(n - 1);      // each call = a NEW frame
}

fact(3) call karne par sabse gehri point par teen live frames bante hain:

fact(3): n=3, waiting on fact(2)
fact(2): n=2, waiting on fact(1)
fact(1): n=1  -> returns 1   (deepest, returns FIRST)

Worked Example 3 — the classic dangling-pointer bug

int *bad(void) {
    int local = 42;
    return &local;   // BUG: returns address of a local
}


Recall Feynman: explain to a 12-year-old

Socho tum homework kar rahe ho. Jab tum ek worksheet shuru karte ho, ek fresh scratch paper lete ho aur likhte ho "iske baad, page 5 par wapas jao." Tum us par apna rough work likhte ho. Agar woh worksheet tumhe ek mini worksheet karne ko kahe, tum ek aur scratch sheet uske upar lete ho. Jab mini wali khatam karo, use matorte ho aur neeche wali par wapas jaate ho. Scratch sheets ki yeh pile stack hai, har sheet ek frame hai, aur "page 5 par wapas jao" wali note return address hai. Tum hamesha pehle top wali sheet khatam karte ho aur matorte ho.


Flashcards

Stack frame kya hota hai?
Ek active function call ka stack memory ka block: uski locals, saved registers, return address, aur aksar uske arguments.
x86 vs ARM par return address kaise save hoti hai?
x86 CALL use stack par push karta hai; ARM BL (branch-and-link) use link register (LR) mein store karta hai, LR ko stack par sirf tab spill karta hai jab function aur call kare.
x86/ARM par stack higher ya lower addresses ki taraf grow karta hai?
Lower addresses ki taraf (har push stack pointer ko decrease karta hai).
Jab SP already hai, toh frame/base pointer (BP) kyun chahiye?
SP execution ke dauran move karta hai (jaise args push karte waqt); BP fixed rehta hai taaki locals ko constant offsets jaise [BP-8] se address kiya ja sake.
Callee ko caller ka BP save aur restore kyun karna padta hai?
BP ek shared register hai; ise save/restore karne se har frame apne locals anchor kar sakta hai bina caller ke frame ka track khoye.
Kisi function se &local return karna bug kyun hai?
Local ek frame mein rehti hai jo return par destroy ho jaati hai; pointer reclaimed memory mein dangle karta hai (undefined behavior).
Recursion har variable ki alag copies kyun rakhti hai?
Har call ek fresh frame banata hai, isliye har call ke locals alag memory mein hote hain.
Stack overflow kab hota hai?
Bahut zyaada nested/recursive frames (ya bade locals) stack region khatam kar dete hain frames free hone se pehle.
Frames ko kaunsa discipline free karta hai, aur yeh kitna cheap hai?
LIFO; freeing bas SP ko wapas reset karna hai — O(1), koi per-variable deletion nahi.
Arguments BP ke relative kahan hote hain vs locals (downward stack)?
Args/return-address BP ke UPAR hote hain (BP+offset); locals BP ke NEECHE hote hain (BP-offset).

Connections

  • Pointers and addresses in C&local kyun dangerous hai yeh directly frame lifetime se juda hai.
  • Recursion — har recursive call = ek naya frame; base case pile ko grow hone se rokta hai.
  • Heap vs Stack memory — heap (malloc) calls se zyaada jeeta hai; stack return par auto-free ho jaata hai.
  • Calling conventions (cdecl, stdcall) — args kaun push/clean karta hai, register vs stack passing.
  • Buffer overflow & return-address smashing — security exploits jo saved return address overwrite karte hain.
  • Assembly: push, pop, call, ret, BL — actual instructions jo frames manage karte hain.

Concept Map

needs private scratch desk

stored on

grows and shrinks by

matches

contains

contains

contains

top tracked by

base tracked by

addresses locals via

on x86 pushed by

on ARM stored in

spilled to stack when

Function call

Stack frame

Call stack

LIFO discipline

Nested lifetimes

Return address

Local variables

Arguments

Stack pointer

Base pointer

Constant offsets

CALL pushes to stack

Link register

Function calls another