MOV 和 LEA 在检索地址方面有什么区别 [英] What is the difference between MOV and LEA in terms of retrieving an address

查看:28
本文介绍了MOV 和 LEA 在检索地址方面有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What exactly is the difference between mov and lea when I use them to get an address?

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

Let's say if I have a program printing out a character string starting from its 5th character whose code is shown below:

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,它的运行方式会有所不同吗?

Then, if I swap lea ecx, [msg + 4] for mov ecx, msg + 4, would it run differently?

我尝试了两者,输出似乎相同.但是,我从这个链接中读到了LEA 指令的目的是什么?,在第一个答案的评论部分,似乎有人声称像 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?, 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. Can someone help me to understand this? Thanks in advance!

推荐答案

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

When the absolute address is a link-time constant, mov r32, imm32 and lea r32, [addr] will both get the job done. The imm32 can be any valid NASM expression. In this case msg + 4 is a link-time constant. 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). That final value replaces the 4B placeholder when copying the bytes from the .o to the linker output.

lea 的有效地址中的 4B 位移完全相同.

Exactly the same thing happens to the 4B displacement in lea's effective address.

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

mov has a slightly shorter encoding, and can run on more execution ports. Use mov reg, imm unless you can take advantage of lea to do some useful math with registers at the same time. (for example: lea ecx, [msg + 4 + eax*4 + edx])

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

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). There's no way to achieve this functionality with 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. (x86 addressing modes)

另见 标记 wiki 以获得许多好的链接.

Also see the x86 tag wiki for many good links.

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

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

这篇关于MOV 和 LEA 在检索地址方面有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆