5

I'm currently playing with C, C++ and ASM. I can see that there's always difference of 12 between ebp substraction values. My disassembled code:

Code:

int main()
{
    int abc = 10;
    int def = 20;
    short int a = 1;
    long int b = 1000;

    //PlayFloat();

    GetValue();
    return 0;
}

Disassebled:

 push        ebp  
 mov         ebp,esp  
 sub         esp,0F0h  
 push        ebx  
 push        esi  
 push        edi  
 lea         edi,[ebp+FFFFFF10h]  
 mov         ecx,3Ch  
 mov         eax,0CCCCCCCCh  
 rep stos    dword ptr es:[edi]  
    ;int abc = 10;
 mov         dword ptr [ebp-8],0Ah  
    ;int def = 20;
 mov         dword ptr [ebp-14h],14h  
    ;short int a = 1;
 mov         eax,1  
 mov         word ptr [ebp-20h],ax  
    ;long int b = 1000;
 mov         dword ptr [ebp-2Ch],3E8h  

    ;//PlayFloat();

    ;GetValue();
 call        004110EB  
    ;return 0;
 xor         eax,eax

But why? Int takes 4 bytes and short only 2 bytes. So why there's difference of 12? Please help.

EDIT: It seems to be same in released listed asm code. I have set it in settings.

_TEXT   SEGMENT
_b$ = -44                       ; size = 4
_a$ = -32                       ; size = 2
_def$ = -20                     ; size = 4
_abc$ = -8                      ; size = 4
_main   PROC                        ; COMDAT

; 18   : {

    push    ebp
    mov ebp, esp
    sub esp, 240                ; 000000f0H
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-240]
    mov ecx, 60                 ; 0000003cH
    mov eax, -858993460             ; ccccccccH
    rep stosd

; 19   :    int abc = 10;

    mov DWORD PTR _abc$[ebp], 10        ; 0000000aH

; 20   :    int def = 20;

    mov DWORD PTR _def$[ebp], 20        ; 00000014H

; 21   :    short int a = 1;

    mov eax, 1
    mov WORD PTR _a$[ebp], ax

; 22   :    long int b = 1000;

    mov DWORD PTR _b$[ebp], 1000        ; 000003e8H

; 23   : 
; 24   :    //PlayFloat();
; 25   : 
; 26   :    GetValue();

    call    _GetValue

; 27   :    return 0;

    xor eax, eax

; 28   : }

    pop edi
    pop esi
    pop ebx
    add esp, 240                ; 000000f0H
    cmp ebp, esp
    call    __RTC_CheckEsp
    mov esp, ebp
    pop ebp
    ret 0
_main   ENDP
_TEXT   ENDS

As you can see, there's also difference of 12.

user35443
  • 6,309
  • 12
  • 52
  • 75
  • But if starting point is ebp-20 and size is 32 bits, it will be in another variable on address ebp-8.... Won't it? – user35443 Jun 27 '12 at 14:27
  • What compiler, what version of the compiler, what switches? Also, please post a complete function and its associated assembly. – Robᵩ Jun 27 '12 at 14:30
  • VC++ 2010...... Ok. Edit has been done. – user35443 Jun 27 '12 at 14:31
  • The stack frame may also include incoming parameters, return address, and pre-allocated space for return value. Whether these things are stored above [ebp] or below it tends to be at least OS/ABI specific, if not compiler and even compiler-version specific. – twalberg Jun 27 '12 at 14:40
  • 1
    @Luchian, it can't possibly be alignment. 12 is not a power of 2. – TonyK Jun 27 '12 at 15:26

1 Answers1

11

This is debug code. The space between variables is filled with 0CCCCCCCCh to detect e.g. buffer overruns.

I'm sure you won't see this in release builds. But you have to actually use the variables, so they are not optimized away in release build.

Henrik
  • 23,186
  • 6
  • 42
  • 92
  • 2
    I had no idea debug mode produced so much overhead. It's reserving 240 bytes of stack to hold 14 bytes of variables! – Mark Ransom Jun 27 '12 at 14:38
  • I can see it also in release build. – user35443 Jun 27 '12 at 14:42
  • @user35443: I'm pretty sure this is not release build. You don't even use the variables, so they would be optimized away in release build. – Henrik Jun 27 '12 at 14:48
  • So in release ebp substraction is with real size? Or how it is? – user35443 Jun 27 '12 at 14:52
  • @user35443 The variables are DWORD aligned, so in this case (4 variables of type short or int) it subtracts 16. – Henrik Jun 27 '12 at 15:14
  • 1
    @user35443 - to clarify my comment: it will reserve 16 bytes in total. There are two bytes of padding between the short and the int so that the int is DWORD aligned. – Henrik Jun 28 '12 at 07:14