用戶可以通過兩種方式使用系統調用:
第一種方式是通過C庫函數,包括系統調用在C庫中的封裝函數和其他普通函數。(如write,read,kill,mkdir等函數)
第二種方式是使用_syscall宏。2.6.18版本之前的內核,在include/asm-i386/unistd.h文件中定義有7個_syscall宏,分別是:
_syscall0(type,name)
_syscall1(type,name,type1,arg1)
_syscall2(type,name,type1,arg1,type2,arg2)
_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)
_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)
_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)
_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)
這裏介紹第二種方式(其實第一種方式本質上就是第二種方式,只不過C庫函數對其進行了封裝)
先舉個例子
如下圖,testsyscall調用後,根據宏定義_syscall0會將返回值int和函數名傳入。後面會講到syscall
以下就是如何產生int80中斷
根據彙編中傳入的宏定義找到對應的系統調用號,這個時候已經由彙編產生int80軟中斷,切換到內核態了。然後再通過調用號在system_call_table中根據偏移量找到對應的內核態中該系統調用函數,如open就找到了sys_open
參數傳遞:
函數需要傳入幾個參數,就調用對應個數的syscalln(),其中n的範圍從0到6。代表需要傳遞給系統調用的參數個數,這是由於該宏必須瞭解到底有多少參數按照什麼次序壓入寄存器
對於每個宏來說,都有2+ n個參數。
第一個參數對應着系統調用的返回值類型。
第二個參數是系統調用的名稱。再以後是按照系統調用參數的順序排列的每個參數的類型和名稱。
(我的理解:第0個,第1個參數是固定的,後面2-6的值就是參數。)
如上圖所示,type是返回類型,name就是系統調用名稱。(就是說open函數調用後在彙編裏會組合爲_NR_open)