繁体   English   中英

MOV 和 LEA 在检索地址方面有什么区别

[英]What is the difference between MOV and LEA in terms of retrieving an address

当我使用它们来获取地址时,mov 和 lea 之间到底有什么区别?

假设我有一个程序打印出一个从第 5 个字符开始的字符串,其代码如下所示:

section .text
    global _start
_start:
    mov edx, 0x06  ;the length of msg from its 5th char to the last is 6.
    lea ecx, [msg + 4]
    mov ebx, 1
    mov eax, 4
    int 0x80

section .data
msg db '1234567890'

然后,如果我将lea ecx, [msg + 4]交换为mov ecx, msg + 4 ,它会以不同的方式运行吗?

我尝试了两者,输出似乎相同。 但是,我从这个链接中读到了 LEA 指令的目的是什么? ,在这个第一个答案的评论部分,似乎有人声称像mov ecx, msg + 4这样的东西无效,但我没有看到它。 有人可以帮助我理解这一点吗? 提前致谢!

当绝对地址是链接时间常数时, mov r32, imm32lea r32, [addr]都可以完成工作。 imm32可以是任何有效的 NASM 表达式。 在这种情况下msg + 4是一个链接时间常数。 链接器将找到msg的最终地址,将其加 4(因为.o的占位符有 +4 作为位移)。 将字节从.o复制到链接器输出时,该最终值将替换 4B 占位符。

lea的有效地址中的 4B 位移也发生了完全相同的事情。


mov编码稍短,可以在更多的执行端口上运行 使用mov reg, imm除非您可以利用lea对寄存器进行一些有用的数学运算 (例如: lea ecx, [msg + 4 + eax*4 + edx]

在 64 位模式下,RIP 相对寻址是可能的,使用 LEA 可以让您制作高效的位置无关代码(如果映射到不同的虚拟地址,则不需要修改)。 使用mov无法实现此功能。 请参阅如何将函数或标签的地址加载到 GNU 汇编器中的寄存器(也包括 NASM)和引用内存位置的内容。 (x86 寻址模式)

另请参阅标签 wiki以获取许多好的链接。


另请注意,您可以对大小使用符号常量。 您还可以更好地格式化和注释代码。 (在具有较长助记符的一些指令的代码中,缩进操作数看起来不那么混乱)。

section .text
    global _start
_start:
    mov    edx, msgsize - 4
    mov    ecx, msg + 4     ; In MASM syntax, this would be mov ecx, OFFSET msg + 4
    mov    ebx, 1       ; stdout
    mov    eax, 4       ; NR_write
    int    0x80         ; write(1, msg+4, msgsize-4)

    mov    eax, 1       ; NR_exit
    xor    ecx, ecx
    int    0x80         ; exit(0)
    ;; otherwise execution falls through into non-code and segfaults

section .rodata
msg db '1234567890'     ; note, not null-terminated, and no newline
msgsize equ $-msg       ; current position - start of message

暂无
暂无

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

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