1,看一下asmlinkage的定义
CPP_ASMLINKAGE __attribute__((regparm(0)))
GCC中使用__attribute__((regparm(n)))指定最多可以使用n个寄存器(eax, edx, ecx)传递参数,n的范围是0~3,超过n时则将参数压入栈中(n=0表示不用寄存器传递参数)。
补充:C语言调用函数参数使用栈传递,有的说使用寄存器传递,上面的asmlinkage关键字主要用于这个作用,那么linux下有几个是使用栈传递,几个使用寄存器传递的呢。
#include <stdio.h>int fun(int a, int b, int c, int d, int e, int f, int g,int h)
{return a+b+c+d+e+f+g;
}int main() {int a = fun(1,2,3,4,5,6,7,8);return 0;
}
汇编查看
lark@ubuntu:~/test$ sudo gcc example.c -o example -g
lark@ubuntu:~/test$ objdump -d example
0000000000001129 <fun>:
1129: f3 0f 1e fa endbr64
112d: 55 push %rbp
112e: 48 89 e5 mov %rsp,%rbp
1131: 89 7d fc mov %edi,-0x4(%rbp)
1134: 89 75 f8 mov %esi,-0x8(%rbp)
1137: 89 55 f4 mov %edx,-0xc(%rbp)
113a: 89 4d f0 mov %ecx,-0x10(%rbp)
113d: 44 89 45 ec mov %r8d,-0x14(%rbp)
1141: 44 89 4d e8 mov %r9d,-0x18(%rbp)
1145: 8b 55 fc mov -0x4(%rbp),%edx
1148: 8b 45 f8 mov -0x8(%rbp),%eax
114b: 01 c2 add %eax,%edx
114d: 8b 45 f4 mov -0xc(%rbp),%eax
1150: 01 c2 add %eax,%edx
1152: 8b 45 f0 mov -0x10(%rbp),%eax
1155: 01 c2 add %eax,%edx
1157: 8b 45 ec mov -0x14(%rbp),%eax
115a: 01 c2 add %eax,%edx
115c: 8b 45 e8 mov -0x18(%rbp),%eax
115f: 01 c2 add %eax,%edx
1161: 8b 45 10 mov 0x10(%rbp),%eax
1164: 01 d0 add %edx,%eax
1166: 5d pop %rbp
1167: c3 retq0000000000001168 <main>:
1168: f3 0f 1e fa endbr64
116c: 55 push %rbp
116d: 48 89 e5 mov %rsp,%rbp
1170: 48 83 ec 10 sub $0x10,%rsp
1174: 6a 08 pushq $0x8
1176: 6a 07 pushq $0x7
1178: 41 b9 06 00 00 00 mov $0x6,%r9d
117e: 41 b8 05 00 00 00 mov $0x5,%r8d
1184: b9 04 00 00 00 mov $0x4,%ecx
1189: ba 03 00 00 00 mov $0x3,%edx
118e: be 02 00 00 00 mov $0x2,%esi
1193: bf 01 00 00 00 mov $0x1,%edi
1198: e8 8c ff ff ff callq 1129 <fun>
119d: 48 83 c4 10 add $0x10,%rsp
11a1: 89 45 fc mov %eax,-0x4(%rbp)
11a4: b8 00 00 00 00 mov $0x0,%eax
11a9: c9 leaveq
11aa: c3 retq
11ab: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
我们可以看到edi,esi,edx,ecx,r8d,r9d这几个寄存器 访问,另外的两个为pushq(栈访问)。
2,asmlinkage举例