asmlinkage
LilyVMのコード読んでいるとき、asmlinkageのマクロが出てきたが定義がされていない。Linuxカーネルなどにも使用されているので調べてみた。
asmlinkageマクロとは
Linuxカーネルなどによく見かけるマクロの一つとして、asmlinkageマクロがある。このマクロは関数の整数引数を確実に、スタックに渡すことを保証するマクロである。Linuxではシステムコールなどに使われる。システムコールの引数の渡しかたは次の様になる。
GCC拡張 regparm (number)
asmlinkageのコードは以下の様になっている。
#define asmlinkage __attribute__((regparm(0)))
regparm (number)はコンパイラにnumberの数だけ引数をレジスタに渡します。i386では最大3個まで渡すことが可能です。eax, edx, ecxレジスタを使用します。x86_64環境では最大6個まで渡すことが可能です。edi, esi, edx, ecx,r8d, r9dレジスタを使用します。
regparm使用した結果
i386環境
#include <stdio.h> __attribute__((regparm(3))) int add(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) { return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; } int main(void) { int ret = add(1, 2, 3, 4, 5, 6, 7, 8, 9); printf("ret: %d\n", ret); return 0; } /* $ objdump -d a.out 08048354 <add>: 8048354: 55 push %ebp 8048355: 89 e5 mov %esp,%ebp 8048357: 83 ec 0c sub $0xc,%esp 804835a: 89 45 fc mov %eax,0xfffffffc(%ebp) 804835d: 89 55 f8 mov %edx,0xfffffff8(%ebp) 8048360: 89 4d f4 mov %ecx,0xfffffff4(%ebp) 8048363: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 8048366: 03 45 fc add 0xfffffffc(%ebp),%eax 8048369: 03 45 f4 add 0xfffffff4(%ebp),%eax 804836c: 03 45 08 add 0x8(%ebp),%eax 804836f: 03 45 0c add 0xc(%ebp),%eax 8048372: 03 45 10 add 0x10(%ebp),%eax 8048375: 03 45 14 add 0x14(%ebp),%eax 8048378: 03 45 18 add 0x18(%ebp),%eax 804837b: 03 45 1c add 0x1c(%ebp),%eax 804837e: c9 leave 804837f: c3 ret */
x86_64環境
#include <stdio.h> __attribute__((regparm(3))) int add(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) { return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; } int main(void) { int ret = add(1, 2, 3, 4, 5, 6, 7, 8, 9); printf("ret: %d\n", ret); return 0; } /* $ objdump -d a.out 0000000000400478 <add>: 400478: 55 push %rbp 400479: 48 89 e5 mov %rsp,%rbp 40047c: 89 7d fc mov %edi,0xfffffffffffffffc(%rbp) 40047f: 89 75 f8 mov %esi,0xfffffffffffffff8(%rbp) 400482: 89 55 f4 mov %edx,0xfffffffffffffff4(%rbp) 400485: 89 4d f0 mov %ecx,0xfffffffffffffff0(%rbp) 400488: 44 89 45 ec mov %r8d,0xffffffffffffffec(%rbp) 40048c: 44 89 4d e8 mov %r9d,0xffffffffffffffe8(%rbp) 400490: 8b 45 f8 mov 0xfffffffffffffff8(%rbp),%eax 400493: 03 45 fc add 0xfffffffffffffffc(%rbp),%eax 400496: 03 45 f4 add 0xfffffffffffffff4(%rbp),%eax 400499: 03 45 f0 add 0xfffffffffffffff0(%rbp),%eax 40049c: 03 45 ec add 0xffffffffffffffec(%rbp),%eax 40049f: 03 45 e8 add 0xffffffffffffffe8(%rbp),%eax 4004a2: 03 45 10 add 0x10(%rbp),%eax 4004a5: 03 45 18 add 0x18(%rbp),%eax 4004a8: 03 45 20 add 0x20(%rbp),%eax 4004ab: c9 leaveq 4004ac: c3 retq */