省略帧指针时有没有实质性的优化?
如果我通过阅读理解正确 this page, -fomit-frame-pointer
当我们想避免保存、设置和恢复帧指针时使用。
这是否仅针对每个函数调用完成?如果是,是否真的值得为每个函数避免一些指令? 优化不是微不足道的吗? 除了调试限制之外,使用此选项的实际含义是什么?
我在使用和不使用这个选项的情况下编译了以下 C 代码
int main(void)
{
int i;
i = myf(1, 2);
}
int myf(int a, int b)
{
return a + b;
}
,
# gcc -S -fomit-frame-pointer code.c -o withoutfp.s
# gcc -S code.c -o withfp.s
.
diff -u
分析这两个文件显示了以下汇编代码:
--- withfp.s 2009-12-22 00:03:59.000000000 +0000
+++ withoutfp.s 2009-12-22 00:04:17.000000000 +0000
@@ -7,17 +7,14 @@
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
- pushl %ebp
- movl %esp, %ebp
pushl %ecx
- subl $36, %esp
+ subl $24, %esp
movl $2, 4(%esp)
movl $1, (%esp)
call myf
- movl %eax, -8(%ebp)
- addl $36, %esp
+ movl %eax, 20(%esp)
+ addl $24, %esp
popl %ecx
- popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
@@ -25,11 +22,8 @@
.globl myf
.type myf, @function
myf:
- pushl %ebp
- movl %esp, %ebp
- movl 12(%ebp), %eax
- addl 8(%ebp), %eax
- popl %ebp
+ movl 8(%esp), %eax
+ addl 4(%esp), %eax
ret
.size myf, .-myf
.ident "GCC: (GNU) 4.2.1 20070719
有人可以阐明上面代码中 -fomit-frame-pointer 确实产生影响的关键点吗?
编辑 objdump
的输出替换为 gcc -S
的
最佳答案
-fomit-frame-pointer
允许一个额外的寄存器可用于通用用途。我认为这在 32 位 x86 上真的只是一个大问题,它有点缺乏寄存器。*
人们希望看到 EBP 不再在每次函数调用时保存和调整,并且可能在正常代码中额外使用 EBP,并且在 EBP 用作通用寄存器的情况下堆栈操作更少。
您的代码太简单了,无法从这种优化中看到任何好处——您没有使用足够的寄存器。此外,您还没有打开优化器,这可能是查看其中一些效果所必需的。
* ISA 寄存器,不是微架构寄存器。
关于c - 我什么时候应该省略帧指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1942801/