用Visual C++编译器解释空C`main`函数的奇怪汇编

cla*_*aws 14 c assembly visual-c++

我刚刚注意到一些空主方法的奇怪的汇编语言代码.

//filename: main.c
void main()
{

}
Run Code Online (Sandbox Code Playgroud)

拆卸:

push        ebp  
mov         ebp,esp  
sub         esp,0C0h; why on the earth is it reserving 192 bytes?  
push        ebx  
push        esi  
push        edi  ; good compiler. Its saving ebx, esi & edi values.
lea         edi,[ebp-0C0h]  ; line 1
mov         ecx,30h  ; line 2
mov         eax,0CCCCCCCCh  ; line 3
rep stos    dword ptr es:[edi]  ; line 4


xor         eax,eax  ; returning value 0. Code following this line is explanatory.
pop         edi  ; restoring the original states of edi,esi & ebx
pop         esi  
pop         ebx  
mov         esp,ebp  
pop         ebp  
ret   
Run Code Online (Sandbox Code Playgroud)
  1. 为什么在地球上它为没有任何变量的函数保留192个字节
  2. 最新的四条线:第1行,第2行,第3行,第4行?它想做什么&为什么?

Han*_*ant 18

Greg已经解释了编译器如何生成代码来诊断未初始化的局部变量,由/ RTCu编译选项启用.0xcccccccc值被选择为独特且易于在调试器中识别.并确保程序在未取消引用未初始化指针时发生炸弹.并确保它在作为代码执行时终止程序.0xcc非常适合完成所有这些工作,它是INT3的指令操作码.

在堆栈帧中分配的神秘192字节用于支持Edit + Continue功能,/ ZI编译选项.它允许您在断点处于活动状态时编辑代码.并将局部变量添加到函数中,这些192个字节可用于为这些添加的局部变量提供空间.超过该空间将使IDE强制您重建程序.

顺便说一句:如果在代码中使用递归,这可能会导致问题.调试版本将以更快的速度轰炸这个网站的名称.通常不是很大的问题,您可以使用实际的数据集大小进行调试.

  • 向上,提供晦涩而迷人的信息. (2认同)

Gre*_*ill 15

您指出的四个代码行是调试版本,使用"clear"特殊值(0xCCCCCCCC)清除局部变量空间.

我不确定为什么有192个字节的看似死空间,但这可能是VC++在你的局部变量区域建立一些保护空间以试图检测堆栈粉碎.

如果从Debug转换为Release版本,您可能会得到一个非常不同的输出.