Domanda

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 a int is (on my machine) 32 bit. This can't be because of optimization because the number 0x123456 won't fit into 16 bits. So why the compiler doesn't reserve enough space?

È stato utile?

Soluzione

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).

Altri suggerimenti

I am not sure myself but I can try to help
sub esp,0x10 is not done to get the reserved space of the int(32bits) on the stack. Instead the first 4 assembly instructions are merely a compiler optimization used to free up the ebp register to be used as a general purposed register.

Read more about it here.

The actual assembly involving the integer is mov DWORD PTR [esp],0x123456.

Hope it helps. Digvijay

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top