まず、Mac OS X で古い 32 ビット Linux カーネル呼び出し規則を使用しています。これはまったく機能しません。
次に、Mac OS X の syscall は異なる方法で構造化されています。それらはすべて、先頭のクラス識別子とsyscall 番号を持っています。クラスは、Mach、BSD、またはその他 ( XNU ソースのこちらを参照) であり、24 ビット左にシフトされます。通常の BSD システムコールにはクラスが2
あり、したがって から始まります0x2000000
。クラスのシステムコール0
は無効です。
SysV AMD64 ABIの §A.2.1 に従って、また Mac OS X が続き、syscall id (XNU のクラスと一緒に!) は to %rax
(または%eax
XNU では上位 32 ビットが使用されないため) になります。最初の引数は に入り%rdi
ます。次は へ%rsi
。等々。%rcx
はカーネルによって使用され、その値は破棄されるため、 のすべての関数はsyscall を行う前にlibc.dyld
それを保存します( のマクロと同様)。%r10
kernel_trap
syscall_sw.h
3 番目に、Mach-O バイナリのコード セクションが呼び出さ__text
れ.text
、Linux ELF の場合とは異なり、__TEXT
セグメント内に存在し、総称して(__TEXT,__text)
( Mach-O がターゲット オブジェクト タイプとして選択されている場合は、適切nasm
に自動的に変換されます) と呼ばれます - Mac OS X ABIを参照してください。 Mach-O ファイル形式リファレンス. 組み立て説明書が正しくても、間違ったセグメント/セクションに配置すると、バス エラーが発生します。ディレクティブ (ディレクティブの構文についてはこちらを参照) を使用するか、(より単純な)ディレクティブを使用するか、オプションが指定されていない場合と見なされるため、ディレクティブを完全に削除することができます(のマンページを参照)。.text
.section __TEXT,__text
.text
-n
as
as
4 番目に、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