This question comes from answering Stack Overflow question Why do books say, “the compiler allocates space for variables in memory”?, where I tried to demonstrate to the OP what happens when you allocate a variable on the stack and how the compiler generates code that knows the size of memory to allocate. Apparently the compiler allocates much more space than what is needed.
However, when compiling the following
#include <iostream> using namespace std; int main() { int foo; return 0; }
You get the following assembler output with Visual C++ 2012 compiled in debug mode with no optimisations on:
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 }
Adding one more int
to my program makes the commented line above to the following:
00B81CC3 sub esp,0D8h // Allocate 216 bytes
The question raised by @JamesKanze in my answer linked atop, is why the compiler, and apparently it's not only Visual C++ (I haven't done the experiment with another compiler), allocated 204 and 216 bytes respectively, where in the first case it only needs four and in the second it needs only eight?
This program creates a 32-bit executable.
From a technical perspective, why may it need to allocate 204 bytes instead of just 4?
EDIT:
Calling two functions and creating a double
and two int
in main, you get
01374493 sub esp,0E8h // 232 bytes
For the same program as the edit above, it does this in release mode (no optimizations):
sub esp, 8 // Two ints movsd QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes
The variables allocated on the stack are called stack variables, or automatic variables.
Because all threads in a process share the same address space, they have to divide it between them. And after the operating system has taken its part, there is "only" 2-3 GB left for an application. And that size is the limit for both the physical and the virtual memory, because there just aren't any more addresses.
Because the data is added and removed in a last-in-first-out manner, stack-based memory allocation is very simple and typically much faster than heap-based memory allocation (also known as dynamic memory allocation) typically allocated via malloc .
We know that when a process is created,one stack is allocated for this process.
This extra space is generated by the /Zi compile option. Which enables Edit + Continue. The extra space is available for local variables that you might add when you edit code while debugging.
You are also seeing the effect of /RTC, it initializes all local variables to 0xcccccccc so that it is easier to diagnose problems due to forgetting to initialize variables. Of course none of this code is generated in the default Release configuration settings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With