5.1.16 · D1 · Coding › C Programming › Stack frames — how function calls work at the memory level
Ek running program memory ki ek single strip rakhta hai jise stack kehte hain, aur har function call us par ek naya chhota sa block carve karta hai jo us call ki private cheezein hold karta hai. Kyunki calls hamesha reverse order mein khatam hoti hain jis order mein shuru hui thi, us strip mein sirf ek hi end par add ya trim hota hai — isliye bookkeeping utni hi simple hai jitni ek marker ko upar-neeche slide karna.
Parent topic mein jo bhi hai woh sirf yahi picture hai jisme names lage hue hain. Neeche hum un saare names ko earn karte hain, ek ek karke.
Kisi bhi fancy word se pehle, aapko EK picture chahiye: computer memory ek bahut lambi numbered boxes ki row hoti hai. Har box ek byte (ek chhota number) hold karta hai, aur har box ka ek address hota hai — uska ghar ka number.
Definition Memory & address
Byte : ek storage box, ek chhota number hold karta hai.
Address : ek box ka ghar-number. Bas ek integer, jaise 0x7ffe4a10. Bada number = strip mein aage ki taraf.
Jab hum kehte hain "kisi address par x store karo", matlab hai: ek box chuno, usme value likho, uska number yaad rakho.
Addresses ki zaroorat hi kyun hai? Kyunki kisi variable par — ya code ki kisi line par — wapas aane ke liye aapko naam pata hona chahiye kahan rahta hai woh . Woh ek zaroorat (location ko naam dena) is poore topic ka beej hai. Addresses aapko dobara depth mein milenge Pointers and addresses in C mein.
Definition Slot — boxes ka ek group jise hum ek unit maante hain
Ek single value jaise int ko aksar kai bytes chahiye hoti hain (aam taur par 4). Hum aise ek fixed-size chunk ko slot kehte hain, aur hum uske byte size ke liye w likhte hain. Toh ek slot bas w adjacent boxes ki ek run hai jise hum saath push ya pop karte hain. Jab bhi koi baad wala section "one slot" kahe, section 0 ke w numbered boxes ko side by side tape kiya hua imagine karo.
Main memory (lambi strip) door hai aur thodi slow bhi. CPU apne andar kuch ultra-fast boxes rakhta hai jinhein registers kehte hain. Yeh sirf kuch hi hote hain, har ek ka ek naam hota hai.
CPU ke andar rehne wala ek named storage box. Ise padhna/likhna near-instant hota hai. Jo examples hamare kaam ke hain: stack pointer , base pointer , link register , aur return value hold karne wala box.
Intuition Registers yahan kyun matter karte hain
Stack memory mein hoti hai (woh door wali strip), lekin CPU stack ka top kahan hai yeh ek register se track karta hai. Toh ek register aapki unglee ki tarah kaam karta hai jo page par rakhi ho — woh page store nahi karta, bas us par jagah mark karta hai.
Memory strip lo aur ek rule pe agree karo: hum slots sirf ek end par add ya remove karein. Woh disciplined strip hi stack hai.
Definition Stack, push, pop
Stack : memory ka ek region jo one-end-only rule ke saath use hota hai.
push : active end par ek naya slot reserve karo aur usme value dalo.
pop : active end ka slot hatao.
Active end ko top of the stack kehte hain — haalaanki, jaise figure dikhata hai, real CPUs par woh "top" asal mein sabse chhota address hota hai jo use mein hai.
Intuition Sirf ek end kyun? → LIFO
Kyunki function calls perfectly nest hoti hain: agar main ne f ko call kiya, aur f ne g ko call kiya, toh g zaroor f se pehle khatam hoga, jo main se pehle khatam hoga. Sabse aakhir mein shuru hone wali cheez sabse pehle khatam hoti hai — Last In, First Out (LIFO). Ek one-end strip is pattern ki exact shape hai. Yahi gehri wajah hai ki topic ek stack use karta hai na ki koi list jis mein se beech se delete karo. (Nesting ke baare mein aur Recursion mein.)
Common mistake "Stack ek tower ki tarah upar badhta hai."
Kyun sahi lagta hai: hum ise upar badhta draw karte hain aur "push" sunne mein aisa lagta hai jaise upar pile kar rahe hain. Fix yeh hai: x86/ARM par har push address kam karta hai — woh lower numbers ki taraf badhta hai. Same idea, ulti picture. Figure s02 dekho: arrow address axis par neeche ki taraf point karta hai.
Ab "top of stack" ko ek naam do. S P ek register hai jo current top slot ka address hold karta hai.
Intuition Yahi cleanup ka poora jadoo kyun hai
Ek saath das slots hatane ke liye, aap unhe erase nahi karte — bas S P mein 10 w wapas add kar do. Marker unhe jump karke past ho jaata hai aur woh gone maane jaate hain. Woh ek move hi kaafi hai "local variables ek function ke return hote hi gayab ho jaate hain" ki wajah ke liye.
Definition Function & call
Function : code ka ek named block jise aap demand par run kar sako, usse inputs (arguments ) de kar aur output (return value ) vapas lo.
Call : us block par jump karne ka act; jab woh khatam ho, execution call ke baad wali line se resume karni chahiye.
Yahan woh problem hai jo agla symbol existence mein laati hai: jab CPU kisi function mein jump karta hai, toh woh yaad kaise rakhta hai ki wapas kis line par jaana hai?
Definition Return address
Us instruction ka address jo called function khatam hone ke baad run hogi. Jump se pehle ise kahin save karna zaroori hai.
Definition Chaar instruction names jo aap dekhenge
Yeh machine instructions hain — CPU ke sabse chhote built-in commands. Is topic mein do CPU families aati hain: x86/x64 (desktops/laptops) aur ARM/RISC-V (phones, Raspberry Pi, kai chips).
CALL (x86): function mein jump karo AUR automatically return address stack par push karo.
RET (x86): woh saved return address pop karo aur usi par wapas jump karo — CALL ka undo.
BL ("branch and link", ARM): function mein jump karo lekin return address stack par nahi, ek register (LR) mein rakho.
JAL ("jump and link", RISC-V): ARM ka BL alag naam se — same "jump, save return address in a register" idea.
Poora instruction set Assembly: push, pop, call, ret, BL mein hai; is page ke liye sirf ek-line meaning kaafi hai.
Intuition Return address save karne ke do tarike (parent x86 vs ARM kyun dikhata hai)
x86/x64 : CALL return address ko stack par push karta hai , aur RET use wapas pop karta hai.
ARM/RISC-V : BL / JAL use pehle ek special register mein rakhta hai — link register (LR) — . Woh stack tak tabhi pahunchti hai jab woh function kisi doosre function ko call kare aur LR overwrite ho jaye.
Same goal (yaad rakhna kahan return karna hai), alag pehla hop. Kaun sa method use hoga uske platform rules Calling conventions (cdecl, stdcall) mein hain.
Common mistake "Return address hamesha stack par push hoti hai."
Kyun sahi lagta hai: x86 par CALL literally ise push karta hai. Fix yeh hai: RISC chips jaise ARM (BL) aur RISC-V (JAL) ise pehle LR mein park karte hain; zaroorat padne par hi woh stack par spill hoti hai.
Ek call ko jo kuch bhi chahiye woh saath bundlo, aur aapko uska frame milta hai.
Definition Stack frame (activation record)
Stack memory ka woh block jo ek single active call ka hota hai. Isme us call ki local variables , uske arguments (ya jahan se pass hue the), return address , aur saved registers hote hain.
Socho ki har call ek fresh scratch paper ka sheet uthati hai. Sheets stack ke active end par pile hoti hain. Jab call khatam hoti hai, uska sheet crumple ho jaata hai (SP wapas jump karta hai) aur neeche wala sheet — caller ka — dobara expose ho jaata hai.
S P chalti rehti hai (function ke dauran har push ise shift karta hai). Toh "meri teesri local" ko "SP minus kuch" ke roop mein address karna ek moving target hai. Ek doosra marker fix karo jo poori call ke liye wahan rahe: base/frame pointer B P .
B P
Ek register jo current frame ke andar ek fixed reference address hold karta hai, entry par ek baar set hota hai. Locals aur arguments phir constant offsets se iske through pahunche jaate hain, chahe S P kahin bhi ho.
B P kyun save karein?
B P shared hardware hai — sirf ek hota hai. Jab aapka function start hota hai, us register mein abhi bhi caller ki keel hai. Toh function ka sabse pehla kaam hai old B P ko push karna (save karna) aur B P = S P set karna (apni keel gaadna). Exit par woh old B P restore karta hai, taaki caller apni desk bilkul waisi hi paye jaise chhodi thi.
Definition Prologue / epilogue
Prologue : function ki shuruat mein setup code — old B P save karo, naya B P set karo, locals ke liye jagah banao (S P ← S P − N ).
Epilogue : end mein teardown — locals hatao (S P ← B P ), old B P restore karo, RET.
Yeh "scratch sheet uthao" aur "use crumple karo" wale steps hain, konkrete roop mein.
Yeh map bottom-up padho. Sabse baayi roots section 0 ki raw ideas hain (memory boxes aur addresses). Woh stack ko feed karte hain (ek disciplined strip), jise do register markers chahiye — S P (top) aur B P (fixed base). Woh markers, plus return address, exactly woh hain jo ek stack frame bundle karta hai, aur prologue/epilogue rituals woh hain jo har function us frame par perform karta hai. Koi bhi arrow follow karo: iska matlab hai "baad wali cheez samajhne ke liye pehle wali zaroorat hai."
memory strip of numbered boxes
slot = w bytes taped together
stack = one-end-only strip
register = fast box in CPU
Frames stack par rehti hain; zyada time rehne wala data kahin aur rehta hai — Heap vs Stack memory dekho.
Stack par ek return address overwrite karo aur aap control hijack kar sakte ho — Buffer overflow & return-address smashing .
Deep nesting Recursion hai; raw addresses Pointers and addresses in C hain.
Right side cover karo aur zor se jawab do.
A byte is... memory mein ek storage box jo ek chhota number hold karta hai.
An address is... ghar-number (ek integer) jo ek memory box identify karta hai; bada = aage ki taraf.
A slot is... w adjacent bytes/boxes ka ek fixed run jise ek unit maana jaata hai (jaise int ke liye 4 bytes).
A register is... CPU ke andar ek fast named storage box (jaise SP, BP, LR).
The stack is... memory ka ek region jisme sirf ek end par add ya remove hota hai.
"push" does what to SP (downward stack)? SP ko ek slot size w se decrease karta hai, phir wahan value likhta hai.
"pop" does what to SP? SP par padhta hai, phir SP ko w se increase karta hai — logically top slot discard karta hai.
LIFO stands for and comes from... Last In, First Out; yeh function lifetimes ke perfectly nest hone se aata hai.
The stack pointer SP holds... stack ke current top ka address.
The base pointer BP holds... current frame ke andar ek fixed reference address, constant-offset access ke liye.
A return address is... us instruction ka address jo called function khatam hone ke baad run hogi.
What does x86 CALL do? function mein jump karta hai aur return address stack par push karta hai.
What does x86 RET do? saved return address pop karke usi par wapas jump karta hai.
What do ARM BL / RISC-V JAL do? function mein jump karte hain aur return address ek register (LR) mein rakhte hain, stack par nahi.
A stack frame contains... ek call ki locals, arguments, saved registers, aur return address.
addr(local_k) = ... and why? BP − offset; locals BP ke neeche baithe hain kyunki stack lower addresses ki taraf badhti hai.
addr(arg_k) = ... and why? BP + offset; args BP se pehle push hue the, isliye woh higher addresses par hain.
Why save the caller's BP on entry? BP ek single shared register hai; save/restore karne se caller apna frame rakhe rehta hai.
Prologue does... old BP save karo, BP = SP set karo, local space banao (SP −= N).
Epilogue does... SP = BP, old BP restore karo, RET.