LEA指令的替代语法
可能重复:
LEA指令的目的是什么?
当我需要一个地址的值时,我可以使用有效地址,例如push dword [str+4]
。 但是当我需要引用一个地址时 - 我无法使用push dword str+4
(这对我来说是一种明显而且无干扰的方式)。
反而需要使用lea EAX, [str+4]
然后push EAX
。 这有点令人困惑,并且还提供了额外的处理器指令,尽管是“零时钟”。 (看到这个答案)
这种差异是否存在一些硬件级别的解释,还是仅仅是(NASM)汇编语法的怪癖?
编辑:好吧,这个评论问我同样的问题。 就像Lucero的回答一样,在这个评论中回答 - X86不支持这样的处理。
汇编指令直接表示x86操作码(不像高级语言那样进行转换编译)。 这些操作码在他们所代表的内容上有其局限性; 同样地,虽然地址计算可能是x86地址的一部分,但是计算值不是。 LEA通过将地址计算的结果存储在任何寄存器中而不是仅在内部消耗它来弥补这一缺陷。
只需使用正确的语法,您需要使用offset关键字:
push offset str+4
LEA指令可以方便地使用地址生成逻辑的管道。 提供非常便宜的方法来添加和增加不使用ALU的方法。 编写代码生成器的程序员的技巧列表中名列前茅。 这里不需要,afaict。
这是一个很长的评论(因为它没有回答这个问题),但读者应该知道..
lea
绝对不是零时钟指令。 有一些例如fxch
(在所有的寄存器重命名上),在Sandy Bridge上的nop
( 90
和0F 1F
),以及某些用于将寄存器设置为零(即使对于XMM寄存器也是自己的xor
或sub
成语,也在桑迪桥上。 当然,它们的吞吐量仍然有限,所以它们不是免费的。
lea
总是需要至少一个周期(至少,在我知道的任何处理器上,并非总是如此),它通常在ALU上执行,而不是在AGU上执行(某些AMD和Atom是例外),但即使在在AGU上执行的情况下,它仍然需要一个周期或更多。 lea
甚至可以超过1个周期,如缩放lea
上P4,Sandy Bridge的(好像我提的SB很多在这个帖子..)或AMD处理器。 事实上,在AMD K10上,进入AGU的lea
是一个缓慢的情况,它被缩放和/或具有3个参数,并且比快速的一个周期长,该周期长于ALU。