我读到过它被用于在Linux中实现系统调用的函数。
asmlinkage long sys_getjiffies( void )
{
return (long)get_jiffies_64();
}
它告诉编译器将所有函数参数传递到堆栈上。但这不是已经这种情况了吗?函数参数通常是通过将它们推送到堆栈上来传递的。或者是指在这里提到通过寄存器传递函数参数吗?
我读到过它被用于在Linux中实现系统调用的函数。
asmlinkage long sys_getjiffies( void )
{
return (long)get_jiffies_64();
}
它告诉编译器将所有函数参数传递到堆栈上。但这不是已经这种情况了吗?函数参数通常是通过将它们推送到堆栈上来传递的。或者是指在这里提到通过寄存器传递函数参数吗?
这里有一个常见问题:
“asmlinkage”标记是我们需要注意的另一件事。这是一种针对gcc的魔法# define,告诉编译器该函数不应期望在寄存器中找到其任何参数(常见优化),而只能在CPU的堆栈上找到。回想一下我们之前的断言:system_call消耗其第一个参数(系统调用号),并允许最多四个传递给真实系统调用的参数。system_call通过将其它参数(已在寄存器中传递给它的参数)保留在堆栈中来实现这一点。所有系统调用都带有asmlinkage标记,因此它们都会在堆栈中查找参数。当然,在sys_ni_syscall的情况下,这没有任何影响,因为sys_ni_syscall不需要任何参数,但对于大多数其他系统调用而言,这是一个问题。而且,由于你将在许多其他函数前面看到asmlinkage,所以我认为你应该知道它是什么。同时,它也用于允许从汇编文件中调用函数。
%eax
、%edx
和%ecx
中传递,其余部分则在堆栈中传递。具有可变参数列表的函数是一个例外,在x86-32上它们所有的参数都在堆栈中传递。在x86-64上,前6个参数依次在%rdi
、%rsi
、%rdx
、%rcx
、%r8
、%r9
中传递(即使对于具有可变参数的函数也是如此),其余部分在堆栈中传递。然而,系统调用遵循不同的规定。 - Eugeneasmlinkage
是一种覆盖参数传递默认约定的方法。还可以在Agner Fog的手册中找到各种调用约定的详细描述。 - Eugene