6

コードは次のとおりです(exit.s):

.section .data,
.section .text,
.globl _start
_start:
    movl $1, %eax
    movl $32, %ebx
    syscall

実行すると" as exit.s -o exit.o && ld exit.o -o exit -e _start && ./exit"

戻り値は「バスエラー:10」で、「echo $?」の出力は138です。

この質問の正解の例も試しました:Linux64ビットのプロセスコマンドライン

「バスエラー」が発生します。

4

2 に答える 2

17

まず、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(または%eaxXNU では上位 32 ビットが使用されないため) になります。最初の引数は に入り%rdiます。次は へ%rsi。等々。%rcxはカーネルによって使用され、その値は破棄されるため、 のすべての関数はsyscall を行う前にlibc.dyldそれを保存します( のマクロと同様)。%r10kernel_trapsyscall_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-nasas

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
于 2012-06-24T18:11:06.683 に答える