linux内核中的asmlinkage宏
阅读数:268 评论数:0
跳转到新版页面分类
Linux
正文
一、概述
在 Linux 内核编程中,asmlinkage
是一个关键字,用于告诉编译器该函数将通过堆栈而不是寄存器接收所有的参数。这个宏主要用于那些需要从用户空间通过系统调用接口调用的函数。在系统调用的上下文中,参数是通过堆栈传递的,以确保所有的系统调用都有一个统一的接口。
asmlinkage
主要用在系统调用的包装函数中,例如:
asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __user *tz);
这个函数是 gettimeofday
系统调用的内核实现。由于这个函数需要从用户空间被调用,所以它使用 asmlinkage
来确保参数通过堆栈传递。
在现代的 Linux 内核中,由于系统调用的实现方式有了变化(比如使用了更高效的系统调用表),asmlinkage
的使用已经不像以前那么频繁了。但是,对于理解 Linux 内核的历史和一些旧代码,了解 asmlinkage
是很有帮助的。
二、源码相关
这个宏的作用是保持参数在stack中。查看arch/x86/include/asm/linkage.h里面的定义
#ifdef CONFIG_X86_32
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
#endif
__attribute__((regparm(0))):告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。
__attribute__((regparm(3))):告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。
CPP_ASMLINKAGE
是一个空的宏,用于兼容性目的。
asmlinkage大都用在系统调用中。 有一些情况下是需要明确的告诉编译器,我们是使用stack来传递参数的,比如X86中的系统调用,是先将参数压入stack以后调用sys_*函数的,所以所有的sys_*函数都有asmlinkage来告诉编译器不要使用寄存器来编译