asmlinkage限定词
(/linux 2.6/arch/x86/include/asm)
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是关键字,是GCC的C语言扩展,regparm(0)表示0个寄存器传递参数,即不从寄存器传送参数,强迫从栈中提取。
如果regparm(3),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用的函数直接从寄存器中取参数。
这里可以解释一下,GCC编译器在汇编过程中调用C语言函数时传递参数有2种方法:
1、寄存器法(最多5个参数,超过5个的参数则堆栈吧)
2、堆栈法
缺省使用寄存器法。
在linux系统中,不管是系统调用或者是系统trap,都会引起用户态->内核态的陷入。内核态的权限是0,用户态是3,系统调用从权限3进入0的内核空间,必然要引起堆栈切换。linux系统会将从全局任务状态栈TSS中找到一个合适的内核栈信息保存覆盖当前SP,SS两个寄存器的内容,完成堆栈切换(寄存器改变了!)。因此,此时内核空间中的栈已经不是用户空间的栈了,在调用的时候压入用户栈的数据在陷入内核态的瞬间,被滞留在用户空间栈,内核根本不知道它的存在了。
在有asmlinkage限定词的地方通常是系统调用的函数,因为在系统调用中,寄存器从用户空间传过来后SAVE_ALL压入堆栈,接着调用相应的系统调用函数,这样系统调用函数一定要保证是通过堆栈传递来的参数。