stdcall 函数的这个 asm 如何从堆栈中清除 args? [英] How does this asm for a stdcall function clean args from the stack?
问题描述
我有简单的代码.StdCall
是 __stdcall
而 CdeclCall
是 __cdecl
.
I have simple code. StdCall
is __stdcall
and CdeclCall
is __cdecl
.
#include <stdio.h>
int __stdcall StdCall(int a,int b)
{
return a + b;
}
int __cdecl CdeclCall(int a,int b)
{
return a + b;
}
int main(int argc, char **argv) {
StdCall(10,20);
CdeclCall(10,20);
printf("Done");
return 0;
}
StdCall 的 main() 的部分 Disassabmbly(Main 不为 StdCall 清除堆栈)
Part of Disassabmbly of main() for StdCall (Main does not clear stack for StdCall)
push 20 ; 00000014H
push 10 ; 0000000aH
call ?StdCall@@YGHHH@Z ; StdCall
CdeclCall 的 main() 解除部分(Main 确实清除 CdeclCall 的堆栈)
Part of Disassabmbly of main() for CdeclCall (Main does clear stack for CdeclCall)
push 20 ; 00000014H
push 10 ; 0000000aH
call ?CdeclCall@@YAHHH@Z ; CdeclCall
add esp, 8 ; Stack cleared here
现在,StdCall 负责从堆栈中删除其 args,但反汇编没有显示任何弹出 ag 以清除/清理堆栈的代码.
Now, it is responsibility of StdCall to remove its args from the stack, but disassembly does not show any code which pops the ags to clear / clean the stack.
StdCall 的反汇编
Disassembly for StdCall
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR _a$[ebp]
add eax, DWORD PTR _b$[ebp]
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 8
为 __stdcall
生成清除堆栈代码是运行时活动还是我错误地理解了概念?
Is it runtime activity to generate clearing stack code for __stdcall
or I have taken concept wrongly?
推荐答案
它是 ret 8
指令的一部分 - 8 是弹出返回地址后添加到堆栈指针的字节数.
It's part of the ret 8
instruction - 8 is the number of bytes to add to the stack pointer after popping the return address.
https://www.felixcloutier.com/x86/ret
另见什么是含义和用法__stdcall? 了解有关 Windows 中 C 函数名称的 @
修饰的更多信息.
See also What is the meaning and usage of __stdcall? for more about the @
decorations on C functions names in Windows.
这篇关于stdcall 函数的这个 asm 如何从堆栈中清除 args?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!