这个小程序在OS X上运行正常,使用nasm:
global _main
extern _puts
section .text
default rel
_main:
push rbp
lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
以下是它的运行方式:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
Hello, world
但是如果我用等效的MOV立即替换LEA指令(带有内存操作数):
global _main
extern _puts
section .text
default rel
_main:
push rbp
mov rdi, message ; <---- Should have same effect as lea rdi, [message]
call _puts
pop rbp
ret
message:
db 'Hello, world', 0
该程序将运行但有一条警告消息,我知道之前有关Stack Overflow的问题:
$ nasm -fmacho64 hello.asm && gcc hello.o && ./a.out
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from hello.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Hello, world
我的问题是为什么会出现这种警告?我看到错误是抱怨链接器不喜欢绝对寻址;但MOV命令显然是使用立即操作数,而不是绝对地址!警告是否贴错标签?我很困惑
顺便说一句,这种区别在Linux下不会发生。删除default rel
以及main
和puts
上的下划线可以让我在Ubuntu上免费运行。什么是OS X在这里采取不同的做法?这是汇编器默认配置设置不同的情况吗?或者像OS X一样奇怪,就像AMD的ABI比Ubuntu更接近?