简体   繁体   English

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

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

What exactly is the difference between mov and lea when I use them to get an address?当我使用它们来获取地址时,mov 和 lea 之间到底有什么区别?

Let's say if I have a program printing out a character string starting from its 5th character whose code is shown below:假设我有一个程序打印出一个从第 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'

Then, if I swap lea ecx, [msg + 4] for mov ecx, msg + 4 , would it run differently?然后,如果我将lea ecx, [msg + 4]交换为mov ecx, msg + 4 ,它会以不同的方式运行吗?

I tried both and the outputs appeared to be the same.我尝试了两者,输出似乎相同。 However, I read from this link, What's the purpose of the LEA instruction?但是,我从这个链接中读到了 LEA 指令的目的是什么? , in the comment section of this first answer, it seemed that someone claimed that something like mov ecx, msg + 4 was invalid, but I failed to see it. ,在这个第一个答案的评论部分,似乎有人声称像mov ecx, msg + 4这样的东西无效,但我没有看到它。 Can someone help me to understand this?有人可以帮助我理解这一点吗? Thanks in advance!提前致谢!

When the absolute address is a link-time constant, mov r32, imm32 and lea r32, [addr] will both get the job done.当绝对地址是链接时间常数时, mov r32, imm32lea r32, [addr]都可以完成工作。 The imm32 can be any valid NASM expression. imm32可以是任何有效的 NASM 表达式。 In this case msg + 4 is a link-time constant.在这种情况下msg + 4是一个链接时间常数。 The linker will find the final address of msg , add 4 to it (because the placeholder in the .o had the +4 as the displacement).链接器将找到msg的最终地址,将其加 4(因为.o的占位符有 +4 作为位移)。 That final value replaces the 4B placeholder when copying the bytes from the .o to the linker output.将字节从.o复制到链接器输出时,该最终值将替换 4B 占位符。

Exactly the same thing happens to the 4B displacement in lea 's effective address. lea的有效地址中的 4B 位移也发生了完全相同的事情。


mov has a slightly shorter encoding, and can run on more execution ports . mov编码稍短,可以在更多的执行端口上运行 Use mov reg, imm unless you can take advantage of lea to do some useful math with registers at the same time .使用mov reg, imm除非您可以利用lea对寄存器进行一些有用的数学运算 (for example: lea ecx, [msg + 4 + eax*4 + edx] ) (例如: lea ecx, [msg + 4 + eax*4 + edx]

In 64-bit mode, where RIP-relative addressing is possible, using LEA lets you make efficient position-independent code (that doesn't need to be modified if mapped to a different virtual address).在 64 位模式下,RIP 相对寻址是可能的,使用 LEA 可以让您制作高效的位置无关代码(如果映射到不同的虚拟地址,则不需要修改)。 There's no way to achieve this functionality with mov .使用mov无法实现此功能。 See How to load address of function or label into register in GNU Assembler (also covers NASM) and Referencing the contents of a memory location.请参阅如何将函数或标签的地址加载到 GNU 汇编器中的寄存器(也包括 NASM)和引用内存位置的内容。 (x86 addressing modes) (x86 寻址模式)

Also see the tag wiki for many good links.另请参阅标签 wiki以获取许多好的链接。


Also note that you can use a symbolic constant for the size.另请注意,您可以对大小使用符号常量。 You can also format and comment your code better.您还可以更好地格式化和注释代码。 (indenting the operands looks less messy in code that has some instructions with longer mnemonics). (在具有较长助记符的一些指令的代码中,缩进操作数看起来不那么混乱)。

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