2013-04-04 121 views
62

这个问题来自回答堆栈溢出问题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个?

编辑:

调用两个功能,创造一个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 
+10

由于它是调试模式。 – ForEveR 2013-04-04 08:58:53

+2

你有比较稍微更复杂的主要调用一些功能?我知道g ++只是分配足够的空间用于函数参数。不知道关于visual C++ – 2013-04-04 08:59:12

+9

调试模式可以包含各种堆栈守卫等等。它在释放模式下的表现如何? – Angew 2013-04-04 09:00:47

回答

101

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

你也看到/ RTC的效果,它初始化所有局部变量0xcccccccc,这样很容易诊断,因为有忘记初始化变量的问题。当然,这些代码在默认的发布配置设置中都不会生成。

+7

啊哈。我没有想到这一点。 (我知道一些编译器在每个函数之间留出了额外的空间,完全是出于这个原因,但是对于本地变量来说,同样是不可缺少的。) – 2013-04-04 09:21:45

相关问题