2016-10-31 2 views
3

私はこのようなOS X(32bit版)のシステムコールを実行しています:システムコールを実行するときにBSDシステムがなぜespサブを必要とするのですか?

push 123 
mov eax, 1 
sub esp, 4 
int 0x80 

そして、私はかなりそのsub esp, 4ギャップを理解していません。

私はどこかでBSDとその派生語が常にこのギャップを持っていると読んでいますが、その理由を見つけることができませんでした。

私の最初の考えはスタックアライメントでしたが、その行はどこからでも見つかるはずで、OS Xが16バイトのスタックアライメントを必要としていることを知っている限り(どちらの場合もそうではありません)。

sub esp, 4を実行する必要性の背後に何が隠れているのか、それを正しく説明するリソースを指摘できますか?彼らはただ周りに引数をコピーせずにint 0x80を行うことができますので、

+0

ここでは推論について説明します:https://www.freebsd.org/doc/en/books/developers-handbook/book.html#x86-system-calls –

+1

これは、あなたが関数を呼び出すと予想されるためです。これが戻りアドレスのスペースです。私は重複を見つけることができます。 – Jester

+0

@MichaelPetch非常に同じ文書を読みましたが、 'call'を置き換えるという事実は、なぜ' call'が最初に必要なのかを全く説明していません。 – mewa

答えて

3

は(コミュニティのwiki私はコメントを要約していますので)

BSDシステム用のlibcラッパー関数を作るためにこれを行い、より効率的に呼び出します。これは、CALLによってラッパー関数にプッシュされた戻りアドレスのための余地を残します。

システムコールでは、read(2)のようなUnix/Linuxシステムでは、inline-asmに展開されるマクロではなく、実際にはカーネルコールのライブラリラッパー関数であることが標準です。


Linuxは、この問題を別の方法で解決します。すべてのsyscall引数をレジスタに渡します。 32ビットのラッパー関数は、すべてのargsをスタックからロードする必要があるが、少なくともカーネルが格納して再読み込みする必要はないということだ。

x86-64のシステムコールABIは、関数呼び出し規約と互換性があります。System V関数呼び出し規約ではargsがレジスタに渡されるため、単一のmov r10, rcxが必要です(syscallレジスタはそれに合わせて選択されます)。可能であればthe SYSCALL instruction itself destroys RCX and R11, so the kernel can't see the original valuesを除きます)。

実際の呼び出し規約とABIへのリンクの詳細については、タグwikiを参照してください。

+0

私は他の呼び出し規約を知っていますが、私はちょうど1つのポインタギャップスペースが説明されている必要があります;)ありがとうございましたリンクのためにありがとう()、私はあなたのコメントを読むまで、申し訳ありませんとにかく! – mewa

+1

@mewa:今後の読者の中には、ある時点で恩恵を受ける人もいます。 :) –

関連する問題