Во-первых, вы используете старое 32-битное соглашение о вызове ядра Linux в Mac OS X - это абсолютно не работает.
Во-вторых, системные вызовы в Mac OS X структурированы по-другому - все они имеют идентификатор ведущего класса и номер системного вызова. Класс может быть Mach, BSD или что-то еще (см. here в источнике XNU) и сдвигается на 24 бита влево. Обычные системные вызовы BSD имеют класс 2
и таким образом начинаются с 0x2000000
. Салоны в классе 0
: недействительный.
Согласно §A.2.1 из SysV AMD64 ABI, также следует Mac OS X, идентификатор (системного вызовов вместе со своим классом на XNU!) Идет в %rax
(или к %eax
как высокий 32 бит не используется на XNU). Кулачный аргумент идет в %rdi
. Далее идет %rsi
. И так далее. %rcx
используется ядром, и его значение уничтожается, и поэтому все функции в libc.dyld
сохраняют его в %r10
перед выполнением системных вызовов (аналогично макросу kernel_trap
от syscall_sw.h
).
В-третьих, участки кода в двойных Маха-O называются __text
и не .text
как и в Linux ELF, а также находиться в __TEXT
сегменте, в совокупности называют (__TEXT,__text)
(nasm
автоматически переводит .text
в зависимости от обстоятельств, если Маха-O, выбирается в качестве мишени тип объекта) - см. Mac OS X ABI Mach-O File Format Reference. Даже если вы правильно получаете инструкции по сборке, помещая их в неправильный сегмент/секцию, приводит к ошибке шины. Вы можете либо использовать директиву .section __TEXT,__text
(см. here для директивного синтаксиса), либо вы также можете использовать (упрощенную) директиву .text
, или вы можете отказаться от нее вообще, поскольку предполагается, что опция -n
была поставлена на as
(см. Справочную страницу as
).
В-четвертых, точка входа по умолчанию для Mach-O ld
называется start
(хотя, как вы уже догадались, это может быть изменено с помощью опции -e
линкера).
Учитывая все вышесказанное, вы должны изменить свой источник ассемблере следующим образом:
; You could also add one of the following directives for completeness
; .text
; or
; .section __TEXT,__text
.globl start
start:
movl $0x2000001, %eax
movl $32, %edi
syscall
Вот она, работает, как ожидалось:
$ as -o exit.o exit.s; ld -o exit exit.o
$ ./exit; echo $?
32
возможно дубликат [GNU Assembler (Mac OS X 64-бит): Незаконная инструкция: 4] (http://stackoverflow.com/questions/11178313/gnu-assembler-mac-os-x-64-bit-illegal-instruction-4) –