当我使用它们获取地址时,mov和lea之间究竟有什么区别? 假设我有一个程序从第5个字符开始打印出一个字符串,其代码如下所示: section .text global _start_start: mov edx, 0x06 ;the length of msg fr
假设我有一个程序从第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,它会以不同的方式运行吗?
我试过两个,输出看起来是一样的.但是,我从这个链接,What’s the purpose of the LEA instruction?,在第一个答案的评论部分读到,似乎有人声称像mov ecx,msg 4这样的东西是无效的,但我没有看到它.有人能帮助我理解这个吗?提前致谢!
当绝对地址是链接时间常量时,mov r32,imm32和lea r32,[addr]都将完成工作. imm32可以是任何有效的NASM表达式.在这种情况下,msg 4是链路时间常数.链接器将找到msg的最终地址,向其添加4(因为.o中的占位符具有4作为位移).将字节从.o复制到链接器输出时,该最终值将替换4B占位符.在lea的有效地址中4B位移恰好发生了同样的事情.
mov的编码略短,can run on more execution ports.使用mov,除非你可以利用lea同时对寄存器进行一些有用的数学运算. (例如:lea ecx,[msg 4 eax * 4 edx])
在64位模式下,可以进行RIP相对寻址,使用LEA可以创建有效的位置无关代码(如果映射到不同的虚拟地址则不需要修改).使用mov无法实现此功能.见Referencing the contents of a memory location. (x86 addressing modes)
有关许多好的链接,请参阅x86 tag 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