【发布时间】:2013-03-26 06:14:00
【问题描述】:
这个问题来自回答 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 字节,在第一种情况只需要 4 个,第二种情况只需要 8 个?
此程序创建一个 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
【问题讨论】:
-
因为是调试模式。
-
你有没有与调用一些函数的稍微复杂的 main 进行比较?我知道 g++ 只是为函数参数分配了足够的空间。不了解visual c++
-
调试模式可以包含各种堆栈保护等。它在发布模式下的表现如何?
-
进行优化后会发生什么?
-
没有调试模式使用多少字节?