繁体   English   中英

lea 和 offset 的区别

[英]Difference between lea and offset

ar db "Defference $"

有什么区别

mov dx,offset ar

lea dx,ar

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

在这个用例中,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]lea dx, [ar + bx]指令中执行的加法不会以任何方式更改标志,因为它不被视为算术指令。

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

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

无法使用 OFFSET 来获取堆栈参数的地址,因为 OF​​FSET 仅适用于编译时已知的地址。 以下语句不会组合:

mov esi,OFFSET [ebp-30]        ; error

您可以使用它们来做同样的事情,但是,如果地址有点复杂, 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指令来获取编译时间之前未知的地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM