Beginner
Beginner

Reputation: 5467

Instructions after main in disassembly

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

Answers (1)

user3344003
user3344003

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

Related Questions