汇编程序:VC ++生成的“函数调用”汇编程序代码

时间:2012-06-09 17:27:38

标签: visual-c++ assembly function-call

我绝不是汇编专家,而且我对这个主题的了解相当浅薄,但我很好奇Microsoft VC ++编译器在一个简单的函数调用中做了什么,除了返回一个值之外别无其他。

让我们有以下功能:

unsigned long __stdcall someFunction ( void * args) {
    return 0;
}

现在,我知道使用__stdcall调用约定时,CALLEE负责堆栈展开,并且使用__cdecl函数的CALLER负责处理。但是对于这个例子,我想坚持前者。

使用非优化的调试版本,我看到正在生成以下输出:

unsigned long __stdcall someFunction (void * args) {
00A31730  push        ebp  
00A31731  mov         ebp,esp  
00A31733  sub         esp,0C0h  
00A31739  push        ebx  
00A3173A  push        esi  
00A3173B  push        edi  
00A3173C  lea         edi,[ebp-0C0h]  
00A31742  mov         ecx,30h  
00A31747  mov         eax,0CCCCCCCCh  
00A3174C  rep stos    dword ptr es:[edi]  
    return 0;
00A3174E  xor         eax,eax  
}
00A31750  pop         edi  
00A31751  pop         esi  
00A31752  pop         ebx  
00A31753  mov         esp,ebp  
00A31755  pop         ebp  
00A31756  ret         4

如果可能的话,我会感谢任何人为我解释这段代码。我知道xor语句实际上会重置eax寄存器以产生零返回值。 ret 4对我来说也是不言自明的。我认为ediesiebx寄存器在之前被推送并弹出以保存原始状态,因此函数可以自由地使用它们。但其余的 - 我不知道。

非常感谢任何答案! :)

谢谢!

1 个答案:

答案 0 :(得分:3)

所以你问这些行是做什么的:

00A3173C  lea         edi,[ebp-0C0h]  
00A31742  mov         ecx,30h  
00A31747  mov         eax,0CCCCCCCCh  
00A3174C  rep stos    dword ptr es:[edi]

在Visual C ++调试运行时库中,未初始化的堆栈内存初始化为包含0xCC个字节。这就是这些说明的作用。

在ASM代码的开头,有一条指令sub esp,0C0h为堆栈分配0xC0个字节。但是,此函数中没有使用局部变量,因此它来自何处?这是编辑+继续支持:您可以添加局部变量并继续调试。

0xCC操作码意味着INT 3 x86汇编指令,因此如果您尝试执行该代码(意外地由于错误),程序将抛出一个INT 3异常,该异常将由调试器或操作系统。所以它不仅仅是一些随机值。