【发布时间】:2012-04-09 08:38:15
【问题描述】:
为了更好地掌握调用约定和堆栈的处理方式,我进行了一些尝试,但我不明白为什么 main 在设置堆栈时分配了三个额外的双字(<main+0>)。它既不与 8 个字节对齐,也不与 16 个字节对齐,所以据我所知,这不是原因。如我所见,main 需要 12 个字节用于 func 和返回值的两个参数。
我错过了什么?
该程序是在 x86 架构上使用“gcc -ggdb”编译的 C 代码。
编辑:我从 gcc 中删除了 -O0 标志,它对输出没有任何影响。
(gdb) disas main
Dump of assembler code for function main:
0x080483d1 <+0>: sub esp,0x18
0x080483d4 <+3>: mov DWORD PTR [esp+0x4],0x7
0x080483dc <+11>: mov DWORD PTR [esp],0x3
0x080483e3 <+18>: call 0x80483b4 <func>
0x080483e8 <+23>: mov DWORD PTR [esp+0x14],eax
0x080483ec <+27>: add esp,0x18
0x080483ef <+30>: ret
End of assembler dump.
编辑:当然我应该发布 C 代码:
int func(int a, int b) {
int c = 9;
return a + b + c;
}
void main() {
int x;
x = func(3, 7);
}
平台是 Arch Linux i686。
【问题讨论】:
-
贴出 C 代码可能会有所帮助
-
该平台也很有用,因为您正在询问调用约定。例如,Mac OS X 要求堆栈在 16 字节边界上保持对齐。
-
最好假设当您禁用优化时,您最终会看到未优化的代码。
-
@HansPassant 当然可以,但在这种特殊情况下没有区别。我没有它重新编译,反汇编是一样的。
-
嗯,这不可能。优化后你应该只剩下
ret。该代码没有副作用,因此可以完全消除。
标签: gcc assembly x86 stack memory-alignment