5

printf私はOSX用のx86-64アセンブリコードで基本的な例を作ろうとしていました.これが私の最初のバージョンです:

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を に移動しており、gcc は位置に依存しないコードがないことを訴えています。ただし、バイナリは引き続き機能します。rdi_printf

→ 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

誰が何が問題なのか知っていますか?

4

1 に答える 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

msgアドレスに , からのバイトが含まれていることに注意してください0x00000a<olleh>

正しい解決策は、次のように、実行時にlea有効な RIP 相対アドレスをロードする命令を使用することです。msg

lea rdi, [rel msg]
于 2012-09-09T15:39:19.540 に答える