现在的位置: 首页 > 综合 > 正文

asmlinkage

2013年09月27日 ⁄ 综合 ⁄ 共 2185字 ⁄ 字号 评论关闭

说明这是系统调用
它是GCC对C程序的一种扩展, #define asmlinkage __attribute__((regparm(0)))
表示用0个寄存器传递函数参数,这样,所有的函数参数强迫从栈中提取。
这个asmlinkage大都用在系统调用中,系统调用需要在entry.s文件中用汇编语言调用,所以必须要保证它符合C语言的参数传递规则,才能用汇编语言正确调用它。
这也是为何使用asmlinkage的原因吧!这是我的理解。

有網友來信問到,kernel 裡的 system call 實作函數中(C 函數),為什麼每一個函數原型宣告的前面都有一個 "asmlinkage" 的字串?例如:

asmlinkage long sys_nice(int increment)

"asmlinkage" 是在 i386 system call 實作中相當重要的一個 gcc 標籤(tag)。

當 system call handler 要呼叫相對應的 system call routine 時,便將一般用途暫存器的值 push到 stack 裡,因此 system call routine 就要由 stack 來讀取 system call handler傳遞的參數。這就是 asmlinkage 標籤的用意。

system call handler 是 assembly code,system callroutine(例如:sys_nice)是 C code,當 assembly code 呼叫 C function,並且是以 stack方式傳參數(parameter)時,在 C function 的 prototype 前面就要加上 "asmlinkage"。

加上 "asmlinkage" 後,C function 就會由 stack 取參數,而不是從 register 取參數(可能發生在程式碼最佳化後)。

更進一步的說明...

80x86 的 assembly 有 2 種傳遞參數的方法:

1. register method
2. stack method

Register method 大多使用一般用途(general-purpose)暫存器來傳遞參數,這種方法的好處是簡單且快速。另外一種傳遞參數的做法是使用 stack(堆疊),assembly code 的模式如下:

push number1
push number2
push number3
call sum

在 'sum' procedure 裡取值的方法,最簡單的做法是:

pop ax
pop ax
pop bx
pop cx

Stack Top 是放 IP,我們傳給 sum procedure 的參數由 stack 的後一個 entry 開始讀取。

其它有關 asmlinkage

1. asmlinkage 是一個定義
2. "asmlinkage" 被定義在 /usr/include/linux/linkage.h
3. 如果您看了 linkage.h,會發現 "__attribute__" 這個語法,這是 gcc 用來定義 function attribute 的語法。

--jollen

相信大家在看linux的source code的时候,都会注意到asmlinkage这个宏,它是用来做什么的呢?

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 the CPU'sstack. Recall our earlier assertion that system_call consumes its firstargument, the system call number, and allows up to four more argumentsthat are passed along to the real system call. system_call achievesthis feat simply by leaving its
other arguments (which were passed toit in registers) on the stack. All system calls are marked with theasmlinkage tag, so they all look to the stack for arguments. Of course,in sys_ni_syscall's case, this doesn't make any difference, becausesys_ni_syscall
doesn't take any arguments, but it's an issue for mostother system calls.

看一下/usr/include/asm/linkage.h里面的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数

如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。

抱歉!评论已关闭.