4

可能重复:
LEA 指令的目的是什么?

当我需要某个地址的值时,我可以使用有效地址,例如push dword [str+4]. 但是当我需要引用一个地址时——我不能使用push dword str+4(这对我来说是显而易见且直观的方法)。

而是需要使用lea EAX, [str+4]then push EAX。这有点令人困惑,并且还提供了额外的处理器指令,尽管是“零时钟”指令。(见这个答案

这种差异是否有一些硬件级别的解释,或者它只是(NASM)汇编语法的一个怪癖?

编辑: 好的,所以这个评论和我问了同样的问题。就像 Lucero 的回答一样,它在此评论中得到了回答——X86 不支持这种寻址。

4

4 回答 4

4

只需使用正确的语法,您需要offset关键字:

 push offset str+4

LEA 指令可以方便地使用地址生成逻辑的管道。提供不使用 ALU 的非常便宜的加法和乘法方法。在编写代码生成器的程序员的技巧列表中名列前茅。这里不需要,afaict。

于 2012-08-18T13:18:38.783 回答
2

这是一个较长的评论(因为它没有回答问题),但读者应该知道..

lea最肯定不是零时钟指令。其中有一些,例如fxch(在所有带有寄存器重命名的东西上),nop900F 1F)在 Sandy Bridge 上,以及某些用于将寄存器设置为零(xorsub自身,甚至对于 XMM 寄存器)的习语,也在 Sandy Bridge 上。当然,它们的吞吐量仍然有限,因此它们不是免费的。

lea总是需要至少一个周期(至少,在我知道的任何处理器上,它可能并不总是这样),它通常在 ALU 而不是 AGU 上执行(一些 AMD 和 Atom 是例外),但即使在在 AGU 上执行的情况下,它仍然需要一个周期或更长时间。lea甚至可能需要超过 1 个周期,例如lea在 P4、Sandy Bridge(似乎我在这篇文章中经常提到 SB..)或 AMD 处理器上进行缩放。事实上,在 AMD K10 上lea,进入 AGU 的是慢速情况,它被缩放和/或有 3 个参数,并且比进入 ALU 的快速周期长。

于 2012-08-18T13:18:28.867 回答
0

因为那开始看起来像 C。唯一可以使用这种内联加法的地方是寻址内存时。LEA让您“寻址”内存而不对其进行寻址,这在保护模式下非常有用,在这种模式下,一个小的指针误步会杀死您的应用程序(在指针误步可能会杀死 DOS、Windows、机器和杀死的实模式下可能更好)任何数量的东西)。汇编是一个有限的野兽,其中每条指令对应一个物理电路。这些说明是一般性的,这本身就是一个小奇迹。

于 2012-08-18T14:24:56.390 回答
0

Assembly instructions directly represent x86 opcodes (no transforming compilation takes place as in higher-level languages). The opcodes have their limitations in what they can represent; as such, while address computations are possible as part of the x86 adressing, value computations are not. LEA covers this gap by storing the result of the address computation in any register instead of only consuming it internally.

于 2012-08-18T12:45:53.007 回答