5.1.10 · HinglishInstruction Set Architecture (ISA)

Calling conventions and ABI

1,899 words9 min readRead in English

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 retpop 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 karo

Stack 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
    ret

Kyun 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?
Woh contract ki machine code mein function call kaise hota hai — argument passing, return value location, register preservation, stack layout.
ABI, calling convention se kaise alag hai?
ABI poora binary contract hai (calling convention + data sizes/alignment + struct layout + object format + syscall interface); calling convention iska ek hissa hai.
ABI vs API?
API source-level hai (names/signatures); ABI binary-level hai (compilation ke baad survive karta hai, alag-alag compile kiye objects ko link karne deta hai).
SysV AMD64 mein pehle 6 integer args kaun se registers se pass hote hain?
rdi, rsi, rdx, rcx, r8, r9.
Integer return value kahan rakha jaata hai (SysV AMD64)?
rax mein (128-bit ke liye rdx:rax).
Caller-saved vs callee-saved?
Caller-saved (volatile): callee clobber kar sakta hai, caller zarorat ho toh save kare. Callee-saved (non-volatile): callee ko return se pehle restore karna zaroori hai.
SysV AMD64 mein callee-saved registers kaun se hain?
rbx, rbp, r12, r13, r14, r15, rsp.
call instruction primitive level par kya karta hai?
Return address (next rip) ko stack par push karta hai, phir target par jmp karta hai.
ret kya karta hai?
Return address ko stack se pop karke rip mein daalta hai (caller resume karta hai).
Function entry par stack alignment rule (SysV AMD64)?
rsp ≡ 8 (mod 16) entry par, kyunki call se pehle rsp 16-byte aligned hona chahiye.
Registers ko caller/callee-saved mein split kyun karte hain ek rule ki jagah?
Total save/restore memory traffic minimize hoti hai — har side sirf wohi registers save karta hai jo actually at risk hain.
7th integer argument kahan jaata hai?
Stack par, return address ke thik upar; callee ise entry par [rsp+8] par padhta hai.

Connections

Concept Map

subset of

adds sizes layout syscalls

survives compilation as

enables

instance of

first 6 args in

extras spill to

result via

defines

defines

complements

Calling convention

ABI

API source level

Arg registers rdi rsi rdx rcx r8 r9

Stack overflow args

Return value in rax

Caller-saved volatile

Callee-saved

Cross-compiler linking

System V AMD64 ABI