![](/img/trans.png)
[英]Why does GCC allocate more space than necessary on the stack, beyond what's needed for alignment?
[英]Why does GCC produce stack preservation instructions when they're not necessary?
我正在编译以下简单的演示函数:
int add(int a, int b) {
return a + b;
}
当然,这个函数将被内联,但我们假设它是动态链接的或者由于某些其他原因而没有内联。 禁用优化后,编译器会生成预期的代码:
00000000 <add>:
0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
6: 03 45 08 add eax,DWORD PTR [ebp+0x8]
9: 5d pop ebp
a: c3 ret
由于此函数内没有函数调用,0,1和9的指令似乎没有用处。 由于禁用了优化,因此这是可以接受的。
但是,在使用-Os -s
优化大小时进行编译时,会生成完全相同的代码。 使用这些选项将函数的大小增加66%似乎相当浪费。
为什么代码未针对以下内容进行优化?
00000000 <add>:
0: 8b 45 0c mov eax,DWORD PTR [esp+0x8]
3: 03 45 08 add eax,DWORD PTR [esp+0x4]
6: c3 ret
编译器是否认为这不值得优化,还是与功能对齐等其他细节有关?
这样做是为了保持调试器逐步执行代码的能力。
如果你真的想要禁用这个try -fomit-frame-pointer
。
使用-Os -fomit-frame-pointer -S -masm=intel
编译上面的代码给出了:
.file "frame.c"
.intel_syntax noprefix
.text
.globl _add
.def _add; .scl 2; .type 32; .endef
_add:
mov eax, DWORD PTR [esp+8]
add eax, DWORD PTR [esp+4]
ret
.ident "GCC: (rev0, Built by MinGW-builds project) 4.8.0"
当函数进入时,EBP的值是未知的。 代码可以使用mov eax,dword ptr [esp+8]
而不打扰BP
寄存器,但许多调试工具假设每个局部变量相对于某个寄存器处于固定偏移量。 即使编译器可以跟踪堆栈上推送的内容并适当地调整索引偏移量,调试器也可能无法这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.