The asmlinkage tag is one other thing that we should observe aboutthis simple function. This is a #define for some gcc magic that tellsthe compiler that the function should not expect to find any of itsarguments in registers (a common optimization), but only on theCPU’s stack. Recall our earlier assertion that system_call consumesits first argument, the system call number, and allows up to four morearguments that are passed along to the real system call. system_callachieves this feat simply by leaving its other arguments (which werepassed to it in registers) on the stack. All system calls are markedwith the asmlinkage tag, so they all look to the stack for arguments.Of course, in sys_ni_syscall’s case, this doesn’t make any difference,because sys_ni_syscall doesn’t take any arguments, but it’s an issuefor most other system calls. And, because you’ll be seeingasmlinkage in front of many other functions, I thought you shouldknow what it was about.
而我在 2.6.8的内核上的include/linux/linkage.h查到它的定义是:
#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE #endif
进一步,CPP_ASMLINKAGE的定义为:
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern “C” #else #define CPP_ASMLINKAGE #endif
而在include/asm-i386/linkage.h里则有更明确的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是GCC的C语言扩展语法。regparm(0)表示不从寄存器中传递参数。
另外,如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。
此句引自了海中一浪的博客文章
asmlinkage确保它定义的函数从栈中读取参数而不是在寄存器中。