【问题标题】:Why are the instructions ENTER and LEAVE not used by compilers? [duplicate]为什么编译器不使用 ENTER 和 LEAVE 指令? [复制]
【发布时间】:2020-11-01 13:21:18
【问题描述】:

阅读程序的反汇编,我注意到了一个模式。在设置函数的框架时,很少使用指令enter。我还将编译器资源管理器与最新的 GCC 一起使用——GCC 不使用 enter,而是使用 leave

为什么不使用指令enter?为什么编译器使用两条或更多指令来执行可以在一条指令中完成的操作? (推送 rbp,保存 rsp,并使用sub rsp 在堆栈上分配,而不是使用enter 0x20, 0)。但是leave 被使用了……还有什么我不知道的leave 吗?据我所知,leave 相当于

mov ebp, esp
pop ebp

GCC 使用 leave 而 MSVC 没有。我不明白为什么从未使用过enter 而有时使用leave

【问题讨论】:

  • tl;dr:一条指令而不是两条并不总是意味着更快。
  • 好的,谢谢。
  • 问题不在于leave 所做的,而是enter 所做的。 enterinsane,它应该为块结构高级语言中的嵌套堆栈帧提供汇编支持。因为enter 的一般形式不能被现代处理器快速处理,所以即使是不那么疯狂的版本,它只为当前堆栈帧保留堆栈空间,也被忽略了处理器实现者。如果您查看 Agner Fog 的指令表,您会发现 enter a, 0push; mov; sub 慢约 3-4 倍,而 enter a,b 有效地占用了永恒。
  • 此外,现代编译器通常可以避免使用帧指针(因为现代调试和展开表使帧指针变得多余),因此帧指针大多是过去的遗物,尤其是在寄存器匮乏的架构上,如 x86( _64),其中编译器的寄存器分配器的额外寄存器非常有价值。
  • 哦?我还有两个问题。如果我们不使用enter,为什么有时会使用leave?另外,我在哪里可以了解有关展开表的更多信息? (例如示例)@EOF

标签: assembly x86 x86-64 compiler-optimization


【解决方案1】:

为什么编译器不使用 ENTER 和 LEAVE 指令?

这些指令在i286i386时代已经使用过,所以在1999年之前。

今天,这些机器指令一般 比简单的等价物慢。编译器编写者确实知道这一点,因此请避免发出这些机器指令。

【讨论】:

    猜你喜欢
    • 2018-06-09
    • 1970-01-01
    • 2013-08-26
    • 2014-02-10
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多