Calling Convention
কলিং কনভেনশন
ফাংশন কল করার সময় argument কোন register/stack-এ যায়, return value কোথায়, কে কোন register বাঁচায় — সব হার্ডওয়্যার-নিয়ম না, compiler-লেখকদের মধ্যে সম্মত software চুক্তি।
also: ABI, System V ABI
System V AMD64 (Linux/macOS x86-64): প্রথম ৬টা integer/pointer
argument rdi, rsi, rdx, rcx, r8, r9-এ (এই ক্রমে), বাকি stack-এ।
Float xmm0–xmm7-এ, স্বতন্ত্র counter। Return value rax
(integer) বা xmm0 (float)।
দুই ভাগ, দুই দায়িত্ব:
- Caller-saved (
rax, rcx, rdx, rsi, rdi, r8–r11) — call-এর পর মান অবিশ্বস্ত, দরকার হলে caller নিজেই আগে বাঁচায়। - Callee-saved (
rbx, rbp, r12–r15) — callee ব্যবহারের আগে বাঁচায়, ফেরার আগে restore করে।
এই ভাগ কেন — “সব সবসময় বাঁচাও” করলে প্রতিটা call-এ অপ্রয়োজনীয় push/pop হতো। ভাগ করলে শুধু প্রয়োজনীয়টাই save হয়।
Hardware এটা এনফোর্স করে না। rdi অন্য যেকোনো
general-purpose register-এর মতোই — CPU জানে না এতে “argument”
আছে। এই কারণেই ভিন্ন compiler (gcc/clang), এমনকি ভিন্ন ভাষায়
(extern "C" দিয়ে Rust, ctypes দিয়ে Python) লেখা কোড একে অপরকে
call করতে পারে — শুধু একই লিখিত চুক্তি মানে বলে।
Convention ভাঙলে (compiler bug) hardware কোনো error দেয় না — silent ভুল ফলাফল অথবা দূরবর্তী crash।
Platform-ভেদে ভিন্ন convention — Windows x64-এ প্রথম int arg
rcx (rdi না), আর caller-কে ৩২ byte “shadow space” রাখতে হয়।
একই x86-64 hardware, দুইটা সম্পূর্ণ অসামঞ্জস্যপূর্ণ চুক্তি।