函數調用約定規範:
| 約定 | 架構 | 參數位置 | 棧清理 | 名稱修飾 (MSVC) | 用途 |
|---|---|---|---|---|---|
cdecl | x86 | 棧 (右→左) | 調用者 | _func | C/C++ 默認、可變參數 |
stdcall | x86 | 棧 (右→左) | 被調用者 | _func@N | Win32 API、COM |
fastcall | x86 | 前 2 參 ECX/EDX,其餘棧 | 被調用者 | @func@N | 舊版優化 |
thiscall | x86 | this 在 ECX,其餘棧 | 被調用者 | 類內部編碼 | C++ 非靜態成員函數 |
vectorcall | x86/x64 | 前 4 整數/6 浮點寄存器 | 被調用者 | func@@Y...Z | SIMD 密集、數學庫 |
| Microsoft x64 | x64 | 前 4: RCX,RDX,R8,R9 (整數/指針) XMM0-XMM3 (浮點) | 調用者 (影子空間 32B) | 無前綴 PE/COFF 導出名 | Windows x64 唯一約定 |
| System V AMD64 ABI | x64 | 前 6: RDI,RSI,RDX,RCX,R8,R9 XMM0-XMM7 | 調用者 (紅區 128B) | 無前綴 ELF 導出名 | Linux/macOS/BSD x64 |
// 原型
void func(int a, double b, char* c, float d, long long e, int f);
// 調用點彙編 (MSVC 輸出)
mov rcx, 1 ; a (整數 1)
movsd xmm0, 2.5 ; b (浮點 2)
lea rdx, str ; c (指釥 3)
movss xmm1, 3.14 ; d (浮點 4)
mov r8, 100 ; e (整數 5)
mov r9, 200 ; f (整數 6)
call func
; 調用者負責分配 32 字節影子空間 (home space)
; 被調用者可選擇將寄存器參數存入影子空間
func PROC
; 序言
push rbp
mov rbp, rsp
sub rsp, 48h ; 局部變量 + 對齊 16B
; 可選:保存寄存器參數到影子空間
mov [rbp+10h], rcx ; a
movsd [rbp+18h], xmm0 ; b
mov [rbp+20h], rdx ; c
movss [rbp+28h], xmm1 ; d
mov [rbp+30h], r8 ; e
mov [rbp+38h], r9 ; f
; 函數體...
; 尾聲
add rsp, 48h
pop rbp
ret
func ENDP
va_start)。call 前 RSP % 16 == 8)。| 類型大小 | 傳遞方式 | 示例 |
|---|---|---|
| ≤ 8 字節 (整數/指針) | RAX | int, void*, std::unique_ptr |
| ≤ 8 字節 (浮點) | XMM0 | float, double |
| 9-16 字節 | RAX:RDX (整數) / XMM0:XMM1 (浮點) | std::pair |
| > 16 字節 或 非平凡拷貝 | 調用者分配內存,傳遞隱藏指針作第 1 參數 (RCX) | std::vector, std::string (SSO 除外) |