可以使用LEA指令来加载值
我是汇编语言的新手。 我目前正在审阅本“大会指南”。 我对LEA教学有疑问。 我对LEA
指令的理解是LEA
用源操作数的有效地址加载目标操作 数
下面的例子来自同一个链接。
lea edi, [ebx+4*esi] — the quantity EBX+4*ESI is placed in EDI.
lea eax, [var] — the value in var is placed in EAX.
lea eax, [val] — the value val is placed in EAX.
在上面的第二个和第三个示例注释中,值是在EAX中加载的。 这是我的困惑。 请让我知道LEA指令是否可用于加载有效地址以及目标操作数中的值。
以上图片来自YouTube的Open Security培训频道的汇编语言简介。
谢谢。
LEA是ALU shift + add指令,它使用寻址模式语法和机器码编码来利用硬件支持来解码这种操作。 (它不关心输入是否是地址,所以你的问题的第二部分在那里得到了回答: lea eax, [ecx + eax*2]
实现了x*2 + y
。)
在任何情况下不lea
不断加载或从存储器中存储 。 请参阅英特尔的说明手册条目。
有趣的事实:唯一的例外是ModR / M字节编码寄存器源而不是内存。 例如lea eax, eax
如果您的汇编程序不拒绝汇编它,或者您使用db
伪指令手动编码它,则lea eax, eax
会与#UD(未定义指令)相冲突。 如果你用asm编写,而不是用十六进制机器码编写的话,这在实践中并不需要担心。 但是没有数据依赖的例外情况。 它根本不在意它运行的是什么值。
在第三个val equ 4
,我认为他们正在讨论类似于val equ 4
或val = 4
,所以“ val
的值”是一个汇编时间常量,而不是存储在内存中。
是的,您可以使用LEA(或任何32位常量),但mov eax, val
更短且更高效。 使用具有绝对disp32
寻址模式的LEA是毫无意义的。
有趣的是:MASM忽略汇编时间常量的[]
: mov eax, [val]
是mov eax, imm32
,与mov eax, val
相同。 Ross Ridge在MASM32中对混淆括号写了一个很好的答案。
lea eax, [var] — the value in var is placed in EAX.
评论是错误的。 var
的地址放在EAX中。 在正常的ASM术语中, 在一个符号名的值意味着在该地址存储在存储器中的值。
mov eax, OFFSET var
比lea eax, [var]
更高效,更短。 有些人喜欢写lea
的,因为“语义”意为人类的读者:取地址。 但是如果你在汇编中写作,那么人们的可读性应该在效率之后才会出现,并且只能以打破平局的方式获胜,例如,当选择没有其他区别时,选择esi
作为源指针。 (很好地格式化/缩进您的代码,并对其进行评论。)
lea eax, [var + edi]
会有意义,你不能用mov
做到这一点。 但是您可以执行mov eax, OFFSET var + 1234
,因为汇编器+连接器必须能够支持填充32位符号+用于寻址模式(如[var + 1234]
偏移值。
在64位模式中, lea rax, [rel var]
在位置无关的代码中有意义:您无法使用mov
获取RIP相对地址。
LEA字面上是“负载有效地址”。 它首先计算一个地址 - 称为“有效”,因为它可能由多个部分组成,并且结果是有效地在目标中结束 - 并在某处加载该地址。
虽然[var]
使用一种寻址模式中, lea
仅仅计算在注定位置的地址,并将其存储,它不使用它来加载从主存储器的东西。 “var中的值”是错误的,如果“var”指的是标签的地址而不是存储值,那么“value var”更多。
由于信息来源明确指出“没有加载内存位置的内容,只有有效地址被计算并放入寄存器,”我认为这只是一个误导性的错字,而不是错误的信息。
链接地址: http://www.djcxy.com/p/72431.html