我有以下代码:
#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位。那么为什么编译器没有保留足够的空间呢?
答案 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寄存器以用作通用寄存器。
涉及整数的实际程序集为mov DWORD PTR [esp],0x123456
。
希望它有所帮助。 Digvijay