これをより簡単に識別できるように、Linuxシステムコールの順序を覚えておきたいと思います。それから私は見つけました。論文はここにあります。、それは言う、
32ビットLinuxでシステムコールを実行するには、システムコール番号をに入力し、対応するパラメータを、、、、、順に入力してから
eax
int 0x80を呼び出します。ebx
ecx
edx
esi
edi
ebp
その後、
64ビットLinuxでシステムコールを実行するには、システムコール番号を、、、、順に入力し、対応するパラメータを
rax
入力してsyscallを呼び出します。rdi
rsi
rdx
r10
r8
r9
64ビットと32ビットの間の順序はなぜそれほど混乱していますか?私はこの質問が技術的ではなく歴史的かもしれないことを知っています。
これは完全にカーネルによって決まりますか?新しいルールを支持する技術的な理由はありますか?
答え1
これはカーネルに大きく依存しますが、64ビットx86で選択された呼び出し規則を使用する理由があります。これは、選択したユーザースペースルールと一致するためです。 Linuxで使用されるSystem V x86-64 ABI、指定するこの関数は、レジスタ、、、、およびを%rdi
使用してパラメータを渡します。システムコールの規則はこれに非常に似ています。唯一の違いは、代わりに使用することです。これは、主にシステムコールを呼び出すために使用される新しい64ビット命令が他の目的に必要なためです。%rsi
%rdx
%rcx
%r8
%r9
%r10
%rcx
SYSCALL
%rcx
答え2
コンパイルされたコードの登録順序は、コードの構築とデバッグを容易にするためのLinux呼び出し規則です。
AMD-64アーキテクチャには32ビットアーキテクチャよりも多くのレジスタがあり、新しい呼び出し規則を使用して他のレジスタを取得してコードを最適化します。
2つのアーキテクチャ間のコードを分解すると、amd-64は関数のローカル整数変数を置き換えるより多くのレジスタを見ることができることがわかります。私が正確に覚えている場合、rebpは関数から返される前にローカル変数スタックを使用して生成されたコードを最適化するために使用されます。