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

问题描述 投票:0回答:2

我有以下代码:

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

c++ assembly x86 stack-memory stack-pointer
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 位)。


0
投票

我自己也不确定,但我可以尽力帮忙

sub    esp,0x10
未完成获取栈上int(32位)的保留空间。相反,前 4 条汇编指令仅仅是编译器优化,用于释放 ebp 寄存器以用作通用寄存器。

在这里阅读更多相关信息。

涉及整数的实际汇编是

mov    DWORD PTR [esp],0x123456

希望有帮助。 迪格维杰

© www.soinside.com 2019 - 2024. All rights reserved.