1)はい、それはLinuxだけのようです。私はあなたがここに記述されているLinuxの規則に頼ることができると思います:http://www.x86-64.org/documentation/abi.pdf。しかし、実際には引数を渡すことは自由ですそれはスタックを使用してintel assembly manual章6.3.3
2)に記載された方法は、コンパイラがそれをしない方法です。そして、
int func(int i, int j, int k, int l, int m, int n, int o, int p, int q) { return q; }
void func2() { func(1, 2, 3, 4, 5, 6, 7, 8, 9); }
:
$ gcc -c func.c && objdump -d func.o
私x86_64のマシン上で出力
:
0000000000000000 <func>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 89 55 f4 mov %edx,-0xc(%rbp)
d: 89 4d f0 mov %ecx,-0x10(%rbp)
10: 44 89 45 ec mov %r8d,-0x14(%rbp)
14: 44 89 4d e8 mov %r9d,-0x18(%rbp)
18: 8b 45 20 mov 0x20(%rbp),%eax
1b: 5d pop %rbp
1c: c3 retq
000000000000001d <func2>:
1d: 55 push %rbp
1e: 48 89 e5 mov %rsp,%rbp
21: 48 83 ec 18 sub $0x18,%rsp
25: c7 44 24 10 09 00 00 movl $0x9,0x10(%rsp)
2c: 00
2d: c7 44 24 08 08 00 00 movl $0x8,0x8(%rsp)
34: 00
35: c7 04 24 07 00 00 00 movl $0x7,(%rsp)
3c: 41 b9 06 00 00 00 mov $0x6,%r9d
42: 41 b8 05 00 00 00 mov $0x5,%r8d
48: b9 04 00 00 00 mov $0x4,%ecx
4d: ba 03 00 00 00 mov $0x3,%edx
52: be 02 00 00 00 mov $0x2,%esi
57: bf 01 00 00 00 mov $0x1,%edi
5c: e8 00 00 00 00 callq 61 <func2+0x44>
61: c9 leaveq
62: c3 retq
3)私が言うのカーネルあなたがカーネルモジュールの中で関数を呼び出しているからです。完全な有効な例を得るためには、モジュール内のCから関数を呼び出すことができ、コンパイラがどのように処理するのかと同じ方法で.koを逆アセンブルすることができます。それはまっすぐでなければなりません。
私の理解では、ユーザとカーネルの間の 'syscall'インタフェースでは4番目のカラム(" x64(kernel) "と表示されています)が使われています。カーネル内の関数間の呼び出しでは、標準のABIが使用されます( "x64(userland)"というラベルが付いています)。しかし、私はこれについての専門家ではないので、誰かが私が間違っている場合は私を修正してください。 –
特別なケースでは、研究__syscall –
@MarcovandeVoort:詳細を教えてください。 –