Calling conventions and ABI
5.1.10· Hardware › Instruction Set Architecture (ISA)
WHAT is an ABI vs a Calling Convention?
HOW arguments and return values travel
System V AMD64 ABI (Linux/macOS x86-64) ko apna concrete model maante hue:
The Stack, aur "who saves what" problem
DERIVATION: first principles se function call banana
Hamare paas koi call semantics nahi hai — sirf hai: registers, memory, ek stack pointer rsp, aur ek instruction pointer rip. Chalo convention invent karte hain.
Step 1 — Callee ko pata kaise chalega wapas kahan return karna hai?
Yeh step kyun? Callee khatam hota hai aur caller ki next instruction resume karni hoti hai. Isliye caller ko return address kahi record karna hoga jahan callee dhundh sake. Decision: ise stack par push karo. call instruction exactly yahi karta hai:
Step 2 — Arguments kahan hain? Yeh step kyun? Callee ka code pehle likha jaata hai, kisi specific caller ko jaane bina, isliye location convention se fixed honi chahiye, caller ki marzi se nahi. Decision: rdi, rsi, … in order.
Step 3 — Callee ko apna scratch/local space kaise milega?
Yeh step kyun? Locals ko aisi memory chahiye jo function ke dauran survive kare aur caller ke frame se collide na kare. Decision: stack frame neeche ki taraf banana ke liye rsp se subtract karo:
Step 4 — Answer return karna aur cleanup karna.
Yeh step kyun? Caller result ek fixed jagah (rax) mein expect karta hai aur stack restore expect karta hai. Decision:
jahan ret ≡ pop rip.
Yahi hai poori convention — derived, memorized nahi.
Worked Example 1 — assembly mein ek call padhna
Source:
int add3(int a, int b, int c) { return a + b + c; }
int main() { return add3(10, 20, 30); }Call ke liye assembly:
main:
mov edi, 10 ; a → rdi (Kyun? 1st int arg)
mov esi, 20 ; b → rsi (Kyun? 2nd int arg)
mov edx, 30 ; c → rdx (Kyun? 3rd int arg)
call add3 ; Kyun? return addr push karta hai, jump karta hai
ret ; result already in eax, use return kar do
add3:
lea eax, [rdi+rsi] ; Kyun? pehle do add karo, return reg rax mein rakho
add eax, edx ; Kyun? teesra add karo
ret ; Kyun? return address pop karo, main resume karoStack use kyun nahi? Sirf 3 args hain (≤ 6) aur koi locals nahi — sab kuch registers mein rehta hai. Fast.
Worked Example 2 — stack par argument spilling
long f(long a,long b,long c,long d,long e,long f,long g) { return g; }Yeh kyun important hai: 7 args > 6 registers. Args 1–6 → rdi…r9; arg g (7th) stack par pass hota hai.
; caller pehle g push karta hai (right-to-left)
mov rdi,... ; a ... f ke liye r9 tak
mov rax,[rsp+8] ; callee stack se g padhta hai (return addr ke upar)
ret[rsp+8] kyun? Entry par rsp return address par point karta hai; 7th arg thik uske upar hota hai.
Worked Example 3 — callee-saved register discipline
long g(long x){ long s=0; for(long i=0;i<x;i++) s+=i; return s; }g:
push rbx ; Kyun? hum rbx (callee-saved) use KARNA chahte hain → save karna zaroori hai
xor rbx, rbx ; s = 0
...
mov rax, rbx ; s return karo
pop rbx ; Kyun? return se pehle caller ka rbx restore karo
retKyun takleef uthao? rbx callee-saved hai: caller ko trust hai ki call ke baad yeh unchanged hai. Yeh promise todna caller ko silently corrupt kar deta hai.
Recall Feynman: ek 12-saal ke bacche ko samjhao
Do bacche ek Lego spaceship banate hain, lekin dono alag-alag kamron mein alag-alag hissa banate hain. Woh sirf tab connect kar sakte hain jab pehle se agree kar lein: "Connector left se 3rd bump par lagega." Calling convention computer functions ke liye wahi agreement hai — numbers kis slot mein jaayenge, aur kaun se Lego pieces tum wapas toot-phoot ke bina dene ka promise karte ho. ABI poora rulebook hai, jisme har brick ki size bhi include hai. Agar ek baccha alag rulebook use kare, toh spaceship toot jaata hai, chahe dono halves "sahi" bhi hon.
Flashcards
Calling convention kya hota hai?
ABI, calling convention se kaise alag hai?
ABI vs API?
SysV AMD64 mein pehle 6 integer args kaun se registers se pass hote hain?
Integer return value kahan rakha jaata hai (SysV AMD64)?
Caller-saved vs callee-saved?
SysV AMD64 mein callee-saved registers kaun se hain?
call instruction primitive level par kya karta hai?
ret kya karta hai?
Function entry par stack alignment rule (SysV AMD64)?
Registers ko caller/callee-saved mein split kyun karte hain ek rule ki jagah?
7th integer argument kahan jaata hai?
Connections
- Stack and Stack Frames
- Registers and Register File
- System Calls and Syscall Interface
- Linkers and Object File Format
- Recursion and Activation Records
- x86-64 vs ARM64 AAPCS
- Name Mangling in C++