什麼是 "asmlinkage"?

jollen 發表於 October 26, 2006 4:15 PM

有網友來信問到,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 call routine(例如: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's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw