在OSX x64汇编中使用RIP相对寻址

5

我试图在OSX上使用x86-64汇编语言制作一个基本的printf示例,以下是我的第一版:

section .data
msg db 'hello', 0Ah

section .text
extern _printf

global _main
_main:
  sub rsp, 8

  mov rdi, msg
  mov rax, 0
  call _printf

  add rsp, 8

  ret

所以,这段代码将msg的绝对地址移动到rdi中作为_printf的第一个参数,然后gcc会抱怨缺少位置无关代码。但是二进制文件仍然可以正常工作:

→ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from new.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
hello

当我改变代码使用RIP相对寻址,使用[rel ...] nasm语法时,警告消失了,但可执行文件现在会发生段错误:

section .data
msg db 'hello', 0Ah

section .text
extern _printf

global _main
_main:
  sub rsp, 8

  mov rdi, [rel msg]
  mov rax, 0
  call _printf

  add rsp, 8

  ret

当我编译和运行它时:

→ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new
zsh: segmentation fault  ./new

有人知道出了什么问题吗?


同样适用于GAS:https://dev59.com/questions/83A75IYBdhLWcg3wg5bs - Ciro Santilli OurBigBook.com
1个回答

7
问题在于原始代码中的mov rdi, msg在汇编时将msg的内存地址加载到了rdi中。当它被改为mov rdi, [rel msg]后,这个代码使用了msg的值作为相对地址,调试时可以看到这一点。
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000a6f6c6c6568

注意观察地址,其中包含了来自msg0x00000a<olleh>的字节。

正确解决方案是在运行时使用lea指令加载msg的有效RIP相对地址,代码如下:

lea rdi, [rel msg]

...并在字符串末尾加上零终止符! - Frank Kotler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接