Foundationপ্রথম নীতি থেকে
LEVEL 3 · Assembly Language

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 xmm0xmm7-এ, স্বতন্ত্র counter। Return value rax (integer) বা xmm0 (float)।

দুই ভাগ, দুই দায়িত্ব:

  • Caller-saved (rax, rcx, rdx, rsi, rdi, r8r11) — call-এর পর মান অবিশ্বস্ত, দরকার হলে caller নিজেই আগে বাঁচায়।
  • Callee-saved (rbx, rbp, r12r15) — 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, দুইটা সম্পূর্ণ অসামঞ্জস্যপূর্ণ চুক্তি।