lea和offset之间的差异

时间:2010-05-09 11:07:01

标签: assembly x86 masm tasm

ar db "Defference $"

之间有什么区别
mov dx,offset ar

lea dx,ar

我认为两者都在做同样的工作,但这两者之间有什么区别

3 个答案:

答案 0 :(得分:15)

在这个用例中,LEA和MOV做同样的事情。如果你想以更复杂的方式计算地址,LEA比MOV更强大。

让我们举例说你想得到数组中第n个字符的地址,n存储在bx中。使用MOV,您必须编写以下两条说明:

Mov dx, offset ar
add dx, bx

使用lea,只需一条指令就可以完成:

lea dx, [ar + bx]

此处需要考虑的另一件事:add dx,bx指令将更改CPU的状态标志。另一方面,在lea dx, [ar + bx]指令内完成的添加不会以任何方式更改标志,因为它不被视为算术指令。

如果您想在进行一些简单计算时保留标志(地址计算非常常见),这有时会很有用。存储和恢复标志寄存器是可行的,但操作很慢。

答案 1 :(得分:1)

引用x86处理器的汇编语言,7e,KIP R. IRVINE

  

无法使用OFFSET获取堆栈参数的地址,因为OFFSET仅适用于编译时已知的地址。以下陈述不会汇总:

mov esi,OFFSET [ebp-30]        ; error

答案 2 :(得分:-1)

您可以使用它们执行相同的操作,但是LEA如果地址有点复杂,总会更好。

请考虑您具有以下字符数组:

ASC_TBL DB '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'

如果要获取第6个元素“ 5”,则可以使用offset做类似的事情:

mov ax, offset ASC_TBL

add ax, 5h; flags [PF] will be affected 

另一方面,如果您使用的是LEA指令,则可以像这样使用一个指令:

LEA ax, [ASC_TBL + 5h]; no flags are affected

注意:

  • 尽管使用LEA证明比使用offset有优势,但是如果地址写的不是很复杂或两者都使用,则使用offset会更有效他们将使用相同数量的指令执行相同的操作。 原因是offset ASC_TBL是在翻译过程中计算的-就像被预处理一样-但是LEA是实际的处理器指令。

  • 您不能使用offset指令来获取编译时间之前未知的地址。