【发布时间】:2020-02-15 15:16:38
【问题描述】:
我相信我了解 STDCALL 和 CDECL 之间的区别,但我想知道是否可以在这段代码中找到一些说明。
我了解在 STDCALL 中 CALLEE 负责清理堆栈,并且我了解在 CDECL 中 CALLER 负责清理堆栈。
我也明白“清理堆栈”基本上意味着重新设置堆栈指针,但我想我的 困惑 出现在 esp 的值被移动到的这行代码中ebp,基指针。如果该功能正在发生,那与“清理堆栈”是否相同?或者它必须是专门进入 ESP 的东西?
这是我正在查看的代码
main PROC
push 4
push 5
call sub_12
push 5
call sub_48
add esp, 4
INVOKE ExitProcess, 0
main endp
sub_12 PROC
push ebp
mov ebp, esp
mov eax, 10
mul DWORD PTR [ebp+12]
pop ebp
ret 8
sub_12 endp
sub_48 PROC
push ebp
mov ebp, esp
mov eax, [ebp+8]
mul DWORD PTR [ebp+8]
pop ebp
ret
sub_48 endp
我原来的答案是 sub_12 和 sub_48 都是 CDECL 因为调用者负责清理堆栈。但现在我一直在看 [mov ebp, esp] 指令,我想知道这是否真的是 STDCALL 的一个例子。
是否有人对我有任何提示或一些我似乎缺少的额外信息?
【问题讨论】:
-
恢复
ebp会清除函数分配的堆栈空间。无论调用约定如何,都必须始终这样做。 Cdecl 与 stdcall 是关于谁清理参数。 -
我明白了!我认为问题在于我从来没有被教导过如何识别参数
-
在这两种约定中,参数都是在调用函数之前由调用者推送的。因此,它们位于返回地址正上方的堆栈中。无法确定参数的数量。
标签: assembly x86 callstack calling-convention stdcall