我有以下代码:
#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 位。那么为什么编译器没有预留足够的空间呢?
所以有人指出它是 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 位)。
我自己也不确定,但我可以尽力帮忙
sub esp,0x10
未完成获取栈上int(32位)的保留空间。相反,前 4 条汇编指令仅仅是编译器优化,用于释放 ebp 寄存器以用作通用寄存器。
涉及整数的实际汇编是
mov DWORD PTR [esp],0x123456
。
希望有帮助。 迪格维杰