Вы не сказали точно, в чем проблема, с которой вы сталкиваетесь, но я предполагаю, что вы терпите крах в точке вызова на printf
. Это связано с тем, что OS X (32- и 64-разрядная) требует, чтобы указатель стека имел 16-байтовое выравнивание в точке вызова любой внешней функции.
Указатель стека был выровнен на 16 байтов при вызове _main
; этот вызов поместил восьмибайтовый адрес возврата в стек, поэтому стек не выровнен по 16 байтов в точке вызова на _printf
. Вычтите восемь из %rsp
перед выполнением вызова, чтобы правильно выровнять его.
Так что я пошел дальше и отладил это для вас (без магии, просто используйте gdb, break main
, display/5i $pc
, stepi
и т. Д.). Другая проблема у вас здесь:
movq _hello(%rip), %rdi
Это загружает первые восемь байтов вашей строки в %rdi
, что совсем не то, что вам нужно (в частности, первые восемь байтов вашей строки крайне маловероятно составляют действительный указатель на строку формата, что приводит к сбою в printf
). Вместо этого вы хотите загрузить адрес строки. Отладочная версия вашей программы:
.cstring
_hello: .asciz "Hello, world\n"
.text
.globl _main
_main:
sub $8, %rsp // align rsp to 16B boundary
mov $0, %rax
lea _hello(%rip), %rdi // load address of format string
call _printf // call printf
add $8, %rsp // restore rsp
ret