【问题标题】:Why does GCC drop the frame pointer on 64-bit?为什么 GCC 会在 64 位上丢弃帧指针?
【发布时间】:2011-05-23 16:11:04
【问题描述】:

默认情况下在 64 位架构上丢弃帧指针的基本原理是什么?我很清楚它可以启用,但为什么 GCC 在启用 32 位时首先禁用它?毕竟,64 位的寄存器比 32 位 CPU 多。

编辑:

看起来当使用更新的 GCC 版本时,x86 的帧指针也会被丢弃。来自手册:

从 GCC 4.6 版开始,32 位 Linux x86 和 32 位 Darwin x86 目标的默认设置(未优化大小时)已更改为 -fomit-frame-pointer。通过使用 --enable-frame-pointer 配置选项配置 GCC,可以将默认值恢复为 -fno-omit-frame-pointer

但是为什么呢?

【问题讨论】:

    标签: gcc assembly x86 64-bit stack-frame


    【解决方案1】:

    对于 x86-64,ABI (PDF) 鼓励不使用帧指针。基本原理或多或少是“我们现在有 DWARF,因此不需要调试或异常展开;如果我们从一开始就将其设为可选,那么任何软件都不会依赖它的存在。”

    x86-64 确实比 x86-32 有更多的寄存器,但它仍然没有足够。从编译器的角度来看,释放更多通用寄存器总是一件好事。需要堆栈爬取的操作较慢,是的,但它们是罕见的事件,因此这是一个很好的折衷方案,可以将每个子例程调用的几个周期缩短,并减少堆栈溢出。

    【讨论】:

    • 通过 CFI 使用 DWARF 展开的性能与遍历帧相比如何?我想它会增加很多开销,因为 .debug_frame 部分没有映射到进程中,即需要一些系统调用来打开 ELF 二进制文件,然后解析文件以找到该部分,最后我们可以解析 CFI。这听起来很慢。
    • @asdf - 做任何展开的代码呢?它还有一个空闲寄存器,并且不必设置堆栈帧。
    • 使用.eh_frame 中的信息完成展开,该信息 映射到进程中(它是.debug_frame 的子集)。是的,它仍然比追逐帧指针慢,但正如我所说,假设这是一个罕见的事件。
    • ABI 允许避免使用 %rbp(参见 §3.2.2,脚注 7),但不要求没有框架指针(%rbp 的使用如图 3.3 的栈帧布局所示,在图 3.4 中描述为“可选使用帧指针”)。
    • 或者在 DWARF CFI 中是否支持引用相对于 RBP 而不是 RSP 的已保存寄存器,因此您可以在更改 RSP 时省略 .cfi 更新?我想必须有,以支持具有 VLA 或 alloca 的函数,其中编译器出于同样的原因选择制作堆栈帧。所以毕竟不是那么可笑。
    猜你喜欢
    • 2013-01-11
    • 2015-04-02
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2011-07-03
    • 1970-01-01
    相关资源
    最近更新 更多