| A Convention | 參數入堆疊順序 | 清除堆疊者 | 支援可變參數 |
| C (cdecl) | 右至左 | 呼叫者 | 是 |
| Syscall | 左至右 | 被呼叫者 | 否 |
| Stdcall (Win32 標準) | 右至左 | 被呼叫者 | 否 (除非 VARARG) |
| Pascal | 左至右 | 被呼叫者 | 否 |
| Basic/Fortran | 左至右 | 呼叫者 | 是 |
Win32 組語預設 .model flat, stdcall。wsprintf 例外採 C 慣例,呼叫後需 add esp, n*4。
堆疊幀佈局與參數存取
呼叫前 ESP = X
PUSH 參數3, 參數2, 參數1 → ESP = X-12
CALL → 推回傳位址 → ESP = X-16
進入副程式:
PUSH EBP → ESP = X-20
MOV EBP, ESP ; EBP 成堆疊幀基址
[EBP+8] = 參數1
[EBP+12] = 參數2
[EBP+16] = 參數3
[EBP-4] = 局部變數1
[EBP-8] = 局部變數2
標準副程式樣板 (手寫版)
MyProc PROC
PUSH EBP
MOV EBP, ESP
SUB ESP, 8 ; 配置 2 個 DWORD 局部變數
MOV EAX, [EBP+8]
SUB EAX, [EBP+12] ; 參數1 - 參數2
ADD ESP, 8 ; 釋放局部變數
POP EBP
RET 12 ; 彈出 3 個參數 (3*4)
MyProc ENDP
386 專用指令簡化:ENTER / LEAVE
MyProc PROC
ENTER 8, 0 ; 相當於 PUSH EBP / MOV EBP,ESP / SUB ESP,8
MOV EAX, [EBP+8]
SUB EAX, [EBP+12]
LEAVE ; 相當於 MOV ESP,EBP / POP EBP
RET 12
MyProc ENDP
MASM32 高階巨集自動化
MyProc PROC Var1:DWORD, Var2:DWORD
LOCAL lVar1:DWORD, lVar2:DWORD
MOV EAX, Var1
SUB EAX, Var2
RET
MyProc ENDP
; 呼叫端
MyProc PROTO :DWORD, :DWORD
INVOKE MyProc, x, y ; 自動 PUSH 參數、檢查型別/個數、CALL
編譯器自動展開 ENTER/LEAVE、計算 RET n、將 Var1 轉為 [EBP+8]。PROTO 宣告讓 INVOKE 能編譯期檢查參數,避免堆疊不平衡導致崩潰。
- 上一篇文章: 組合指令與機器碼互轉實戰:OPCODE 查表法完整教學
- 下一篇文章: 組合語言與 C 語言模組混合連結實戰:COFF/PE 格式深度剖析
Copyright ©
程式碼之家 All Rights Reserved