这个页面应该基本上把它包起来。
使用cdecl你会喜欢
; I'm not comfortable with AT&T syntax, but it's not relevant here
; void *processData(void *firstParam, void *secondParam)
proc processData
push ebp
mov ebp,esp
mov eax,[dword ptr ss:ebp + 8] ; firstParam
mov edx,[dword ptr ss:ebp + 12] ; secondParam
; do something with the data and put the result into EAX
mov esp,ebp
pop ebp
ret
endp processData
你调用它就像
lea eax,[ds:bufferOfSecondParam]
push eax
lea eax,[ds:bufferOfFirstParam]
push eax
call processData
add esp,8
; Here you can do with the return value anything you want
首先,您需要决定要使用的调用约定。例如,Win32 使用一个名为stdcall的cdecl变体,其中被调用者负责清理堆栈——这实现起来不太方便,并且不允许使用可变参数。
[SS:EBP + 8]指向第一个参数,因为
- 参数从右到左传递到堆栈([SS:EBP + 12]指向第二个参数)
- DWORDS 是 4 个字节
- [SS:EBP + 0]指向在创建堆栈帧时保存的上一个EBP
- [SS:EBP + 4]指向ret时读入EIP的返回地址