当我使用它们获取地址时,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'
Run Code Online (Sandbox Code Playgroud)
然后,如果我换lea ecx, [msg + 4]了mov ecx, msg + 4,将它运行不同?
我试过两个,输出看起来是一样的.但是,我从这个链接中读到,LEA指令的目的是什么?,在第一个答案的评论部分,似乎有人声称有类似mov ecx, msg + 4无效的东西,但我没有看到它.有人能帮助我理解这个吗?提前致谢!
当绝对地址是链路的时间常数,mov r32, imm32并lea r32, [addr]都将完成这项工作.的imm32可以是任何有效NASM表达.在这种情况下msg + 4是链接时间常数.链接器将找到最终地址msg,向其添加4(因为占位符在.o+4中作为位移).将字节从.o链接器输出复制到链接器输出时,该最终值将替换4B占位符.
在lea有效地址中的4B位移恰好发生了同样的事情.
mov编码略短,可以在更多的执行端口上运行. 除非您可以同时利用寄存器进行有用的数学运算,否则请使用movlea.(例如:lea ecx, [msg + 4 + eax*4 + edx])
在64位模式下,可以进行RIP相对寻址,使用LEA可以创建有效的位置无关代码(如果映射到不同的虚拟地址则不需要修改).没有办法实现这个功能mov.请参阅引用内存位置的内容.(x86寻址模式)
另请注意,您可以使用符号常量作为大小.您还可以更好地格式化和评论您的代码.(缩进操作数在代码中看起来不那么混乱,这些代码具有一些具有较长助记符的指令).
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1236 次 |
| 最近记录: |