Reputation: 5467
I have a very simple program where my goal was to study how the compiler pushes the values to the different registers. But now the behaviour is much more complicated than expected, at least in debug-mode.
What is going on here?
#include <cstdio>
struct A
{
int B;
A() : B(0) { }
};
int main()
{
A a;
A b(a);
printf("%d", b.B);
printf("%d", a.B);
return 0;
}
This is how the disassembly looks like in Visual Studio:
int main()
{
01048210 push ebp
01048211 mov ebp,esp
01048213 sub esp,0D8h
01048219 push ebx
0104821A push esi
0104821B push edi
0104821C lea edi,[ebp-0D8h]
01048222 mov ecx,36h
01048227 mov eax,0CCCCCCCCh
0104822C rep stos dword ptr es:[edi]
A a;
0104822E lea ecx,[a]
01048231 call A::A (104678Ah)
A b(a);
01048236 mov eax,dword ptr [a]
01048239 mov dword ptr [b],eax
printf("%d", b.B);
0104823C mov eax,dword ptr [b]
0104823F push eax
01048240 push offset string "%d" (1093C6Ch)
01048245 call @ILT+3885(_printf) (1046F32h)
0104824A add esp,8
printf("%d", a.B);
0104824D mov eax,dword ptr [a]
01048250 push eax
01048251 push offset string "%d" (1093C6Ch)
01048256 call @ILT+3885(_printf) (1046F32h)
0104825B add esp,8
}
The first lines are explained in this answer, they are there to kep the frame pointer so that nice stack traces can be generated.
But the next lines are confusing: why subtract 216 (0D8h) from esp?
What are these lines after main, but before the first line of code A a;
doing?
Edit: after setting the runtime checks to default the disassembly is much smaller:
int main()
{
00247110 push ebp
00247111 mov ebp,esp
00247113 sub esp,48h
00247116 push ebx
00247117 push esi
00247118 push edi
A a;
Edit 2: in Release mode (/Ox) a and b are completely optimized away and no memory is allocated on the stack at all:
int main()
{
A a;
A b(a);
printf("%d", b.B);
00B41000 push 0
00B41002 push 0B499A0h
00B41007 call printf (0B4102Dh)
printf("%d", a.B);
00B4100C push 0
00B4100E push 0B499A4h
00B41013 call printf (0B4102Dh)
00B41018 add esp,10h
return 0;
0127101B xor eax,eax
}
0127101D ret
Edit 3: this is the result using gcc -m32 -O3 -mpreferred-stack-boundary=2
(thanks to @CodyGray).
.LC0:
.string "%d"
Test():
push 0
push OFFSET FLAT:.LC0
call printf
pop eax
pop edx
push 0
push OFFSET FLAT:.LC0
call printf
pop ecx
pop eax
ret
Upvotes: 1
Views: 297
Reputation: 21627
00CC8223 sub esp,0D8h
Allocates the stack space for the local variables.
What are these lines after main, but before the first instruction doing?
What are you referring to?
Upvotes: 5