x64 nasm: wypychanie adresów pamięci na funkcję stosu i wywołania

Jestem całkiem nowy w x64-assembly na Macu, więc mylę się przenosząc jakiś 32-bitowy kod w 64-bitowy.
Program powinien po prostu wydrukować wiadomość za pośrednictwemprintf funkcja z biblioteki standardowej C.
Zacząłem od tego kodu:

section .data
    msg db 'This is a test', 10, 0    ; something stupid here

section .text
    global _main
    extern _printf

_main:
    push    rbp
    mov     rbp, rsp       

    push    msg
    call    _printf

    mov     rsp, rbp
    pop     rbp
    ret

Kompilowanie go z nasm w ten sposób:

$ nasm -f macho64 main.s

Zwrócony następujący błąd:

main.s:12: error: Mach-O 64-bit format does not support 32-bit absolute addresses

Próbowałem rozwiązać ten problem, zmieniając kod na ten:

section .data
    msg db 'This is a test', 10, 0    ; something stupid here

section .text
    global _main
    extern _printf

_main:
    push    rbp
    mov     rbp, rsp       

    mov     rax, msg    ; shouldn't rax now contain the address of msg?
    push    rax         ; push the address
    call    _printf

    mov     rsp, rbp
    pop     rbp
    ret

Kompilował się dobrze znasm polecenie powyżej, ale teraz pojawia się ostrzeżenie podczas kompilowania pliku obiektu za pomocągcc do aktualnego programu:

$ gcc main.o
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not
allowed in code signed PIE, but used in _main from main.o. To fix this warning,
don't compile with -mdynamic-no-pic or link with -Wl,-no_pie

Ponieważ jest to ostrzeżenie, a nie błąd, wykonałema.out plik:

$ ./a.out
Segmentation fault: 11

Mam nadzieję, że ktoś wie, co robię źle.

questionAnswers(3)

yourAnswerToTheQuestion