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

标签 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 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   
  1. 到底为什么要为没有任何变量的函数保留 192 字节
  2. 这四行是怎么回事:第 1 行、第 2 行、第 3 行、第 4 行?它试图做什么?为什么?

最佳答案

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

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

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

关于c - 用Visual C++编译器解释空C `main`函数奇怪的汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3362872/

相关文章:

c - 如何在可能的递归过程中设置缓冲区?

c - 为什么使用 fork() 时终端的 AppCode 中出现不同的输出?

c - 使用 getch() 将 char 数转换为 int 时出现问题;

c++ - 避免在 libgmp 中中止

c++ - 在 Windows 7 上读取文件速度很慢

c++ - 包含头文件

c++ - 如何为 operator[] 指定返回类型?

performance - 英特尔 Broadwell 处理器出现明显的 FMA 性能异常

debugging - 在 x32dbg/x64dbg 中,我如何自动跟踪 'dump window' 中的堆栈(ESP)?

无法使用字符串变量中的指令执行内联汇编程序