Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用visualc+解释空C`main`函数的奇怪组合+;编译程序_C_Visual C++_Assembly - Fatal编程技术网

用visualc+解释空C`main`函数的奇怪组合+;编译程序

用visualc+解释空C`main`函数的奇怪组合+;编译程序,c,visual-c++,assembly,C,Visual C++,Assembly,我刚刚注意到空main方法的一些奇怪的汇编语言代码 //filename: main.c void main() { } 拆卸: 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 s

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

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

}
拆卸:

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   
  • 它究竟为什么要为没有任何变量的函数保留192个字节
  • 这四条线是怎么回事:1号线,2号线,3号线,4号线?它想做什么&为什么

  • 您指出的四行代码是调试构建,使用“clear”特殊值(
    0xcccc
    )清除局部变量空间

    我不确定为什么会有192字节的死区,但这可能是VC++在局部变量区域中构建了一些保护空间来检测堆栈崩溃


    如果从调试切换到发布版本,您可能会得到非常不同的输出。

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

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


    顺便说一句:如果在代码中使用递归,这可能会导致问题。调试构建将以该站点的名称快速轰炸。通常不会有太大的问题,您可以使用实际的数据集大小进行调试。

    为什么不突出显示代码语法?当您组装非空的主语句时,会生成什么程序集,那么当你把main的返回类型改为int时会发生什么呢?值得指出的是main返回int。使用void作为main并不是好的jujuju。@Joe D:幸运的是,编译器通常不是大脑有行星大小的抑郁机器人。这通常是独立实现的定义。独立实现允许但不要求提供完整的c库。在独立实现中,STDC_HOSTED被定义为0,而在HOSTED中,它被定义为1。为什么
    0xcccc
    =
    1100
    ?用0x00000000清除不是更有意义吗?@claws:Microsoft选择该值是因为如果程序最终使用未初始化的变量,它是独特的,并且很容易识别。使用零会掩盖许多潜在的错误,因为变量通常会被初始化为零,而让编译器在调试版本中这样做会导致发布版本失败。@claws:对于返回0的空函数的发布模式版本,您的pastebin正是我所期望的。正如我所说,当编译器不发出任何不必要的代码时,您将得到非常不同的输出。@Greg Hewgill:啊,是的,我记得很清楚。事实上,一旦这个未初始化的模式给我们带来了一个巨大的问题,当一个客户报告一个只发生在发布版本中的bug时,我们就根本无法复制它。结果证明,我们使用的是未初始化的布尔值。在发布版本中,它通常为零,但在调试版本中,它从未为零。打开关于使用未初始化变量的警告是一个更好的主意。“特殊值”的术语是内存毒药。Up,用于提供晦涩但有趣的信息。你所说的是正确的