首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 函數調用約定匯編分析:cdecl 與 stdcall 參數傳遞、棧平衡、返回值

     編輯:關於C++

測試代碼結構

struct tagTest { int n1; long n2; DWORD n3; };

long funtest1(tagTest p1, int p2, LPCTSTR lpszP3);        // cdecl (默認)
long __stdcall funtest2(tagTest p1, int p2, LPCTSTR lpszP3); // stdcall

1. cdecl 調用約定 (默認)

調用方匯編

; 參數從右向左入棧
push offset string_addr        ; 第3參數 LPCTSTR
mov edx, [i2]; push edx        ; 第2參數 int
sub esp, 0Ch                   ; 為結構體預留 12 字節
mov eax, esp
mov ecx, [tag1]; mov [eax], ecx       ; 複製 n1
mov edx, [ebp-10h]; mov [eax+4], edx  ; 複製 n2
mov ecx, [ebp-0Ch]; mov [eax+8], ecx  ; 複製 n3
call funtest1
add esp, 14h                   ; 調用方清棧 (3參數 + 結構體 = 20 字節)
mov [ixx], eax                 ; 返回值在 eax

被調方匯編

funtest1:
push ebp
mov ebp, esp
push ecx              ; 局部變量空間
mov dword ptr [p1], 3         ; p1.n1 = 3
mov eax, [lpszP3]; mov [lpszxx], eax
mov ecx, [p2]; mov [ebp+10h], ecx  ; p1.n3 = p2
mov eax, 12Ch         ; 返回值 300
mov esp, ebp
pop ebp
ret                   ; 只彈出返回地址,不清參數棧

2. stdcall 調用約定

調用方匯編

; 參數壓棧順序相同 (右→左)
push offset string_addr
mov eax, [i2]; push eax
sub esp, 0Ch; ... 複製結構體 ...
call funtest2
mov [ixx], eax
; 無 add esp 指令!被調方負責清棧

被調方匯編

funtest2:
push ebp
mov ebp, esp
push ecx
... 函數體同 cdecl ...
mov eax, 12Ch
mov esp, ebp
pop ebp
ret 14h             ; 返回並清棧 20 字節 (0x14)

核心差異總結

特性cdeclstdcall
參數壓棧順序右→左右→左
棧清理責任調用方被調方
可變參數支持支持不支持
函數名修飾_FuncName_FuncName@N
典型用途C/C++ 默認Windows API、COM

結構體參數傳遞細節

  • 調用方用 sub esp, size 預留空間,再逐成員 mov 複製。
  • 被調方直接以固定偏移訪問參數([ebp+8] 之後)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved