1

我有以下代码:

#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 位。那么为什么编译器没有预留足够的空间呢?

4

2 回答 2

10

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

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

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

于 2013-10-27T07:58:05.837 回答
0

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

在此处阅读更多相关信息。

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

希望能帮助到你。迪格维杰

于 2013-10-27T07:34:55.557 回答