Pergunta

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?

Foi útil?

Solução

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

Outras dicas

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top