为什么编译器只为int保留0x10位?

时间:2013-10-27 07:23:43

标签: c++ assembly x86 stack

我有以下代码:

#include <iostream>
using namespace std;

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

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

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

我使用g++编译它,然后使用objdump -Mintel -d对其进行反汇编,我得到了以下主函数:

 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   

现在,堆栈中的保留空间是16位(0x10,在行8048739中),而int是(在我的机器上)32位。这不是因为优化,因为数字0x123456不适合16位。那么为什么编译器没有保留足够的空间呢?

2 个答案:

答案 0 :(得分:9)

所以有人指出它是0x10字节(不是位)。这是16个字节,因为gcc保持堆栈16字节对齐x86。来自GCC手册:

  

-mstackrealign在入口处重新对齐堆栈。在Intel x86上,-mstackrealign选项会生成备用序言和结尾,以便在必要时重新调整运行时堆栈。这支持混合   遗留代码,保持4字节堆栈与现代代码对齐   保持16字节堆栈对齐以实现SSE兼容性。另见   属性force_align_arg_pointer,适用于各个函数。

     

-mpreferred-stack-boundary = num尝试保持堆栈边界对齐2到num字节边界。如果   未指定-mpreferred-stack-boundary,默认值为4(16字节或128位)。

答案 1 :(得分:0)

我不确定自己,但我可以尝试帮助 不需要sub esp,0x10来获取堆栈上的int(32位)的保留空间。相反,前4个汇编指令只是一个编译器优化,用于释放ebp寄存器以用作通用寄存器。

Read more about it here.

涉及整数的实际程序集为mov DWORD PTR [esp],0x123456

希望它有所帮助。 Digvijay