我有一个适用于Mac OS X的汇编Hello World程序,代码如下:
global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msg]
mov rdx, msg.len
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "Hello, World!", 10
.len: equ $ - msg
我对 lea rsi, [rel msg]
这行代码感到困惑。我不明白为什么NASM强制我这样写。据我的理解,msg
只是可执行文件中某些数据的指针,使用 mov rsi, msg
就可以将该地址放入 rsi
中。但如果我用其他方式代替 lea rsi, [rel msg]
,比如 mov rsi, msg
,那么NASM会报错(注意:我使用的命令是 nasm -f macho64 hello.asm
):
hello.asm:9: fatal: No section for index 2 offset 0 found
为什么会出现这种情况?
lea
有什么特别之处,mov
不能做到的?我该如何知道何时使用它们?
mov rsi,msg
使用绝对地址,这将根据程序加载的位置而改变,而Mach-O不支持这种情况。 - Ross Ridgemov rsi,msg
指令时,它会将寄存器加载为编码为立即操作数的值。该立即值需要是“msg”的实际地址。Mach-O不支持这一点。 - Ross Ridgemsg
的地址在哪里? - Jerfov2msg
将位于何处。但是通过使用 RIP 相对寻址,它就不需要知道这些信息了。 - Ross Ridge