Assembly lea和offset之间的差异
两者之间有什么区别Assembly lea和offset之间的差异,assembly,x86,masm,tasm,Assembly,X86,Masm,Tasm,两者之间有什么区别 ar db "Defference $" 及 我认为两者都在做相同的工作,但是在这个用例中,这两个之间的区别是什么。如果您想以更复杂的方式计算地址,LEA比MOV更强大 例如,假设您想要获取数组中第n个字符的地址,并且n存储在bx中。使用MOV,您必须编写以下两个说明: lea dx,ar 使用lea,您只需一个指令即可完成: Mov dx, offset ar add dx, bx 这里要考虑的另一件事: AddixDX,BX指令将改变CPU的状态标志。另一方面,在l
ar db "Defference $"
及
我认为两者都在做相同的工作,但是在这个用例中,这两个之间的区别是什么。如果您想以更复杂的方式计算地址,LEA比MOV更强大 例如,假设您想要获取数组中第n个字符的地址,并且n存储在bx中。使用MOV,您必须编写以下两个说明:
lea dx,ar
使用lea,您只需一个指令即可完成:
Mov dx, offset ar
add dx, bx
这里要考虑的另一件事:<代码> AddixDX,BX指令将改变CPU的状态标志。另一方面,在
lea dx[ar+bx]
指令内进行的加法不会以任何方式更改标志,因为它不被视为算术指令
如果您希望在执行一些简单计算(地址计算非常常见)时保留标志,这有时会很有用。存储和恢复标志寄存器是可行的,但操作缓慢。引用x86处理器汇编语言7e,KIP R.IRVINE 不可能使用偏移量来获取堆栈参数的地址,因为偏移量仅适用于编译时已知的地址。以下语句无法汇编:
你可以用它们做同样的事情,但是如果地址有点复杂,
LEA
总是会更好
假设您有以下字符数组:
ASC_TBL数据库'0'、'1'、'2'、'3'、'4'、'5'、'6'、'7'、'8'、'9'、'A'、'B'、'C'、'D'、'E'、'F'
如果要获取第6个元素“5”,可以使用偏移量执行类似操作:
mov esi,OFFSET [ebp-30] ; error
另一方面,如果您正在使用LEA
指令,您可以简单地使用one指令,如下所示:
leaax[ASC_TBL+5h];没有任何标志受影响
请注意:
- 虽然使用
LEA
证明了它比使用offset
有优势,但是如果地址写起来不是很复杂,或者两者都使用相同数量的指令做相同的事情,那么使用offset
会更有效。
原因是offset ASC\u TBL
是在翻译过程中计算的,就像被预处理一样,但是LEA
是实际的处理器指令
- 不能使用
offset
指令获取编译时间之前未知的地址
还有偏移量ar
-是在转换过程中计算的即时值。和lea
-是实际的处理器指令“加载有效地址”,第二个操作数引用memmory。@ony:lea
只是一个移位和加法指令。它从不实际从内存加载,它只使用寻址模式语法和二进制编码。在OP的例子中,当绝对地址上有lea
时,disp16
与mov
的imm16
相同,两者在组装时(实际上是在最终地址已知的链接时)以相同的方式计算。@PeterCordes,我没有说lea
加载任何内容(引用只是一个引用). 我说过这是一条真正的x86指令。如果你在翻译过程中进行计算,你可以使用mov
。lea
最让我困惑的是编译器和调试器使用的语法leaax,[addr]
对我来说“对addr
的内容执行一些操作,并将结果放入ax
,但事实并非如此。此外,这在以前的16位实模式编程中也是一个问题。当链接到一个所有内容都在同一段中的小binary.com文件时,您可以在大多数情况下互换使用offset
或lea
,但是使用非tiny
的内存模型会导致很多问题,因为偏移量
与定义数据的段基址有关。它们之间的唯一区别是lea
是一条指令,偏移量
不可能与mov ax重复,偏移量ASC_TBL+5
合法且较短(mov ax为3字节,imm16为4字节,LEA为4字节:操作码+modrm+disp16)。无论哪种方式,绝对地址都由汇编程序(或链接器)计算并嵌入到机器代码中ASC_TBL+5
是一个链路时间常数,就像ASC_TBL
一样;运行时没有执行+5
。符号在运行时并不真正存在,除非作为调试元数据存在于可执行文件中。CPU在运行引用它们的指令时没有搜索它们。我没有说+5
是在运行时完成的,我说完整的LEA
指令是一条实际的处理器指令ok,所以你只是不知道你可以mov ax,offset ASC\u TBL+5
。嗯,你可以P汇编器(如果您没有生成平面二进制文件,则为链接器)使用与它们在lea
操作数中填充[disp16]
字段相同的机制来处理它。mov reg,imm16
编码也只需要机器代码中的绝对地址。LEA在代码大小方面更差,因此永远不应用于此目的,除非在64位代码中使用RIP相对寻址以获得位置独立性,或代替64位绝对地址。
lea dx, [ar + bx]
mov esi,OFFSET [ebp-30] ; error
mov ax, offset ASC_TBL
add ax, 5h; flags [PF] will be affected