为什么在堆栈上分配了这么多空间?

时间:2013-04-04 08:57:14

标签: c++ compiler-construction

这个问题来自回答Stack Overflow问题 Why do books say, “the compiler allocates space for variables in memory”? ,我试图向OP演示在堆栈上分配变量时会发生什么以及编译器如何生成知道的代码要分配的内存大小。显然,编译器会分配比所需空间更多的空间。

但是,在编译以下内容时

#include <iostream>
using namespace std;

int main()
{
    int foo;
    return 0;
}

使用在调试模式下编译的Visual C ++ 2012获得以下汇编程序输出,但未进行优化:

int main()
{
00A31CC0  push        ebp
00A31CC1  mov         ebp,esp
00A31CC3  sub         esp,0CCh  // Allocates 204 bytes here.
00A31CC9  push        ebx
00A31CCA  push        esi
00A31CCB  push        edi
00A31CCC  lea         edi,[ebp-0CCh]
00A31CD2  mov         ecx,33h
00A31CD7  mov         eax,0CCCCCCCCh
00A31CDC  rep stos    dword ptr es:[edi]
   int foo;
   return 0;
00A31CDE  xor         eax,eax
}

在我的程序中再添加一个int,使上面的注释行显示如下:

00B81CC3  sub         esp,0D8h // Allocate 216 bytes

@JamesKanze在我的回答中提到的问题是,为什么编译器,显然它不仅是Visual C ++(我还没有用另一个编译器做过实验),分别分配204和216个字节,其中在第一种情况它只需要四个而在第二种情况下它只需要八个?

该程序创建一个32位可执行文件。

从技术角度来看,为什么需要分配204个字节而不只是4个?

编辑:

调用两个函数并在main中创建double和两个int,你得到

 01374493  sub         esp,0E8h  // 232 bytes

对于与上面编辑相同的程序,它在发布模式下执行此操作(无优化):

 sub    esp, 8                // Two ints
 movsd  QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes

1 个答案:

答案 0 :(得分:102)

这个额外的空间由/ Zi编译选项生成。这使Edit + Continue成为可能。额外的空间可用于在调试时编辑代码时可能添加的局部变量。

您还看到了/ RTC的效果,它将所有局部变量初始化为0xcccccccc,以便更容易诊断由于忘记初始化变量而导致的问题。当然,这些代码都不会在默认的发布配置设置中生成。