Search code examples
c++assemblyx86stack-memorystack-pointer

Why does the compiler reserve just 0x10 bits for an int?


I have the following code:

#include <iostream>
using namespace std;

void f()
{
    cout << "hello" << endl;
}

void f(int i)
{
    cout << i << endl;
}

int main()
{
    f();
    f(0x123456);
}

I compiled it using g++, then disassembled it using objdump -Mintel -d and I got the following for the main function:

 08048733 <main>:
 8048733:   55                      push   ebp
 8048734:   89 e5                   mov    ebp,esp
 8048736:   83 e4 f0                and    esp,0xfffffff0
 8048739:   83 ec 10                sub    esp,0x10
 804873c:   e8 9b ff ff ff          call   80486dc <_Z1fv>
 8048741:   c7 04 24 56 34 12 00    mov    DWORD PTR [esp],0x123456
 8048748:   e8 bb ff ff ff          call   8048708 <_Z1fi>
 804874d:   b8 00 00 00 00          mov    eax,0x0
 8048752:   c9                      leave  
 8048753:   c3                      ret   

Now, the reserved space in the stack is 16 bits (0x10, in line 8048739), while an int (on my machine) is 32 bits. This can't be because of optimization because the number 0x123456 won't fit into 16 bits. So why doesn't the compiler reserve enough space?


Solution

  • So it's been pointed out that it's 0x10 bytes (not bits). it's 16 bytes because gcc keeps stack 16-byte aligned for x86. From GCC manual:

    -mstackrealign Realign the stack at entry. On the Intel x86, the -mstackrealign option generates an alternate prologue and epilogue that realigns the run-time stack if necessary. This supports mixing legacy codes that keep 4-byte stack alignment with modern codes that keep 16-byte stack alignment for SSE compatibility. See also the attribute force_align_arg_pointer, applicable to individual functions.

    -mpreferred-stack-boundary=num Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary. If -mpreferred-stack-boundary is not specified, the default is 4 (16 bytes or 128 bits).