Как написать ассемблер hello world program для 64 бит Mac OS X с помощью printf?
Я пытаюсь научиться писать язык ассемблера для 64-битной Mac OS. У меня нет проблем с 32-битной Mac OS и 32-битной и 64-битной Linux.
однако Mac OS 64 бит отличается, и я не мог понять. Поэтому я здесь, чтобы просить о помощи.
У меня нет проблем с использованием системного вызова для печати. Тем не менее, я хотел бы узнать, как вызвать функции C, используя 64-битный язык сборки Mac OS.
пожалуйста, посмотрите на следующее код
.data
_hello:
.asciz "Hello, worldn"
.text
.globl _main
_main:
movq , %rax
movq _hello(%rip), %rdi
call _printf
Я использую $ gcc-arch x86_64 Здравствуйте.s
собрать и связать.
Он генерирует двоичный код. Однако, я получил ошибку сегментации при запуске.
Я попытался добавить "subq $8, %rsp" перед вызовом _printf, все тот же результат, что и раньше.
что я сделал не так?
кстати, это какой-нибудь способ отладки этого кода на Mac? Я попытался добавить -ggdb или-gstab или-gDWARF, и $ gdb ./а.и не вижу код и установить точки останова.
1 ответов
вы не сказали точно, в чем проблема, которую вы видите, но я предполагаю, что вы разбиваетесь в точке вызова 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 , %rsp // align rsp to 16B boundary
mov , %rax
lea _hello(%rip), %rdi // load address of format string
call _printf // call printf
add , %rsp // restore rsp
ret