macos – 在OSX x64程序集中使用RIP相对寻址

我试图在OS86的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

因此,当我使用[rel …] nasm语法更改代码以使用RIP相对寻址时,警告消失,但可执行文件现在会出现错误:

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

有谁知道出了什么问题?

最佳答案
问题是原始的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

注意地址如何包含来自msg,0x00000a< olleh>的字节.

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

lea rdi, [rel msg]

转载注明原文:macos – 在OSX x64程序集中使用RIP相对寻址 - 代码日志