I was trying to make a basic printf
example in x86-64 assembly code for OSX, here's my first version:
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
So this code is moving the absolute address of msg
into rdi
for the first argument to _printf
, and gcc then complains about the lack of position-independent code. The binary still works though:
→ 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
So when I change the code to use RIP-relative addressing, using the [rel ...]
nasm syntax, the warning disappears but the executable now seg faults:
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
And when I compile and run it:
→ nasm -f macho64 new.asm && gcc -m64 -o new new.o && ./new
zsh: segmentation fault ./new
Does anyone know what's going wrong?