web-dev-qa-db-ja.com

Nasm-シンボル `printf 'がR_X86_64_PC32の再配置でオーバーフローを引き起こす

aという文字を表示するシンプルなプログラムをnasmで作成しようとしています。しかし、それは私にセグフォルトを与え、これを言っています:

./a.out: Symbol `printf' causes overflow in R_X86_64_PC32 relocation
Segmentation fault (core dumped)

基本的に、私は値0x61(文字aの16進数)をメモリアドレス1234に移動し、それを引数としてprintfに渡そうとしています。これが私の正確なコードです:

extern printf
section .text
global main
main:
Push rbp
mov rax,0
mov qword [1234], 0x61 ; move 0x61 into address 1234
mov rdi, qword [1234] ; mov address 1234 into rdi
call printf ; should print the letter a
pop rbp
mov rax,0
ret

Linux x86_64を実行しています

11
Unknown

-no-pieでコンパイルしてみてください。説明については、これらの投稿を確認してください: GCCでアセンブルすると、.dataに関して奇妙な再配置エラーが発生します

要するに:

Debianは64ビットモードでPIC/PIEバイナリに切り替えました。この場合、GCCはオブジェクトをPICとしてリンクしようとしていますが、mov $ str、%rdiで絶対アドレスを検出します。

10
brian

https://stackoverflow.com/users/3062591/brian への完全なクレジット

これを機能させる方法を理解するため。あなたが私と同じように、nasmに非常に慣れている場合OR何らかの理由でnasmに慣れておらず、gccでほとんど何もしていない場合は、コマンドを実行する必要があります。 :

nasm -felf64 YOUR_FILE.asm && gcc -no-pie YOUR_FILE.o && ./a.out

私はこれを使ってこれを得ることができました

printfを呼び出す

に変更する必要はありません

printf wrt ..got

これは、以前のいくつかのNASM導入例での試みにありましたが、すべてではありませんでした。

4