【问题标题】:In x86 assembly how does register arithmetic in effective addresses get compiled to byte code?在 x86 汇编中,有效地址中的寄存器算术如何编译为字节码?
【发布时间】:2016-09-07 15:26:48
【问题描述】:

汇编编译器如何编译如下指令:

mov eax, [bx+si]

mov eax, [ebp + 4*eax - 40]

免责声明:我对这些东西还是很陌生。

根据我目前的知识水平,我无法理解。我已经用尽了谷歌,但找不到关于它如何编译的解释;只是关于它的作用。因为根据我目前的理解,这不可能是预先确定的计算。

这是否会生成一个特定的、不同的操作码,然后传入各个部分,CPU 会自动为它处理?如果是这样,我在找到的所有 x86 参考资料中都错过了这一点;或者我可能不是在寻找正确的东西或我期望参考文献显示的内容。

或者它是在编译时注入一堆指令来在指令本身之前进行数学运算?虽然,通过阅读使用这种技术执行某些乘法运算比调用 MUL 更快的各种资源(类似于mov eax, [eax*4 + eax] 的东西(如果我记错了,请原谅我)相当于乘以 5,但更快)。这让我相信这不可能是这样处理的。

我也没有找到关于 x86 汇编编译过程的好的指南/阅读。只有在其中编程的资源。因此,如果有人知道任何好的资源,请告诉我。 :)

谢谢!

【问题讨论】:

  • 是的,不同的寻址模式有不同的操作码/指令。

标签: assembly compilation x86


【解决方案1】:

所有处理器都有一组寻址模式,必须在架构定义中建模。

编译器后端将中间表示与一系列可用寻址模式模式相匹配。通常 IR 会显式计算地址。 “窥孔优化”寻找机会将计算合并到指令中,使用匹配的寻址模式。

有时优化器会做相反的事情,有时他们将计算提升到循环之外,然后使用简单的指针取消引用寻址模式。最佳选择尚不清楚,这取决于复杂寻址模式计算对目标的接近零成本。

复杂的寻址模式可以减少寄存器压力,因为减少了保存计算地址的需要。


如果您想更深入地了解编译器是如何工作的,您应该阅读这个关于编译器实现的Stanford University online material。在讲义 18 和第 8 讲中会很有趣。我将假设您将使用解析器生成器,因此现在可以跳过关于它如何解析的理论。

【讨论】:

  • 现在更有意义了。谢谢。
  • 太棒了,感谢您的参考,梳理了大量不同的来源,有时信息相互矛盾已经很累了。我肯定会大量使用该资源。再次感谢。
  • 所有寻址模式在 x86 上都同样便宜(除了代码大小),除了 Intel Sandybridge 系列。 (即每个人都关心的 CPU)。这似乎是对不同问题的一个很好的回答。 OP 似乎在询问寻址模式是如何用机器语言编码的,或者即使它们是汇编成多条指令的伪操作。这很好地回答了编译器如何选择要使用的寻址模式,而不是编译器输出是如何组装的。
  • @PeterCordes 是的,我回答了这个问题,“编译器如何编译复杂的寻址模式”。当我最初回答时,我不记得所有与汇编程序相关的东西都在那里。我回答了第一个问题,并假设一条指令中 ofs+a+b*2^[0-3] 的“lea技巧”只是与实际问题无关的切线。
  • 啊,我明白了。你一定马上就开始回答了,OP 在 5 分钟的窗口中偷偷地进行了一些编辑。当我看到这个问题时,很明显,当他的意思是“汇编”时,OP 刚刚写了“编译”,名词也一样,因为那里有 asm 源代码。当然,如果人们有足够的知识来提出完美的问题,在大多数情况下,他们已经知道在哪里可以快速轻松地找到答案。 :P 我很可能。不过,不会为了解决这个问题而费心编辑问题。
【解决方案2】:

你想的是lea,而不是mov。 (mov eax, [eax*4 + eax] 是一种负担。)lea is a shift-and-add instruction 使用 asm 语法和机器代码编码来进行寻址模式。是的,值得用它来替换多个其他指令,或者替换 imul

有关寻址模式如何在机器代码中编码的详细信息,请参阅英特尔的指令集手册。官方手册包含了从头开始编写汇编程序所需了解的几乎所有内容,它们是available for free in PDF format。 Volume2 是 insn 集参考,操作数编码信息在附录中。另请参阅 标签 wiki 中的其他链接,了解大量内容,包括优化指南。

另见summary of the available addressing modes

只有一个基址寄存器的寻址模式只需要一个字节,加上一个 disp8 或 disp32 位移。索引寻址模式需要一个额外的字节(比例索引和基本字节)。索引的*1*2*4*8 比例因子是移位计数,编码在 SIB 字节中的 2 位字段中。

除了代码大小之外,在英特尔 Sandybridge 系列 CPU 上使用索引寻址模式也会产生性能成本:they can't micro-fuse。而在 Haswell 上,专用 store-AGU 只能处理“简单”的寻址模式。

在其他当前的 x86 CPU 上,所有寻址模式除了代码大小之外都执行相同的操作,因此地址数学是免费的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多