一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

徹底搞懂系統(tǒng)調(diào)用

 xpxys99 2021-05-10

在應(yīng)用程序開發(fā)過(guò)程中經(jīng)常會(huì)進(jìn)行IO設(shè)備的操作,比如磁盤的讀寫,網(wǎng)卡的讀寫,鍵盤,鼠標(biāo)的讀入等,大多數(shù)應(yīng)用開發(fā)人員使用高級(jí)語(yǔ)言進(jìn)行開發(fā),例如C,C++,java,python等,這些高級(jí)語(yǔ)言都提供了標(biāo)準(zhǔn)庫(kù)或者API去操作IO設(shè)備,不過(guò)標(biāo)準(zhǔn)庫(kù)或者API最終還是通過(guò)系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn)操作IO設(shè)備的,系統(tǒng)調(diào)用操作系統(tǒng)提供的,它是操作系統(tǒng)內(nèi)核的一部分。

系統(tǒng)調(diào)用封裝了對(duì)硬件操作的所有細(xì)節(jié),而標(biāo)準(zhǔn)庫(kù)或者SDK又在系統(tǒng)調(diào)用的基礎(chǔ)上做了高度抽象的封裝和優(yōu)化,因此使得應(yīng)用程序開發(fā)人員的日子好過(guò)多了,開發(fā)效率也提高了不少。

本篇文章主要闡述以下兩部分:

1.什么是系統(tǒng)調(diào)用?

2.系統(tǒng)調(diào)用的實(shí)現(xiàn)?

主要以Linux 操作系統(tǒng)和IA-32處理器舉例,高級(jí)語(yǔ)言以C語(yǔ)言為例,同時(shí)也會(huì)摻雜一些其它操作系統(tǒng)和處理器。

什么是系統(tǒng)調(diào)用?

對(duì)于現(xiàn)代的操作系統(tǒng)來(lái)說(shuō),應(yīng)用程序運(yùn)行的時(shí)候是沒有權(quán)限去訪問系統(tǒng)資源的,操作系統(tǒng)為了防止各類應(yīng)用程序可能會(huì)破壞系統(tǒng)資源,對(duì)系統(tǒng)資源做了保護(hù),阻止應(yīng)用程序直接去訪問這些資源,而應(yīng)用程序又有訪問這些系統(tǒng)資源的需求,因此操作系統(tǒng)提供了系統(tǒng)調(diào)用,讓所有的應(yīng)用程序統(tǒng)一通過(guò)系統(tǒng)調(diào)用來(lái)訪問系統(tǒng)資源,這里所說(shuō)的系統(tǒng)資源包括文件,網(wǎng)絡(luò) ,內(nèi)存,各類IO設(shè)備等。

應(yīng)用程序可以進(jìn)行系統(tǒng)調(diào)用,也可以調(diào)用標(biāo)準(zhǔn)庫(kù)或者API,一個(gè)系統(tǒng)調(diào)用的內(nèi)部有很多的步驟,比如需要進(jìn)行用戶態(tài)模式到內(nèi)核態(tài)模式的互相切換。

這里簡(jiǎn)單介紹下模式切換,我們知道一個(gè)完整的應(yīng)用程序分為兩部分,一部分是應(yīng)用程序的代碼和數(shù)據(jù),另一部分是內(nèi)核的代碼和數(shù)據(jù),切換模式就是這兩部分的分水嶺,意味著處理器進(jìn)入了一個(gè)不同的模式,不同的模式就是不同的世界,不同的世界就有不同的權(quán)限,而內(nèi)核態(tài)模式就是王者,可以掌握所有的資源,用戶態(tài)模式只能掌握自己的一畝三分地。

正如上面所說(shuō),系統(tǒng)調(diào)用需要進(jìn)行模式切換,而每個(gè)完整的應(yīng)用程序都有兩個(gè)棧,一個(gè)用戶棧,一個(gè)內(nèi)核棧,這兩個(gè)棧是獨(dú)立的,用戶棧在用戶空間,內(nèi)核棧在內(nèi)核空間,因此切換模式時(shí),棧也得切換。

因此我們可以將系統(tǒng)調(diào)用的執(zhí)行步驟分為三步:1.執(zhí)行前的準(zhǔn)備工作。2.執(zhí)行處理程序(處理函數(shù))。3.執(zhí)行后的善后工作,當(dāng)然內(nèi)核模式切換和棧切換就是1和3的工作了,這里的三步都是在內(nèi)核模式下執(zhí)行的,如下圖所示

徹底搞懂系統(tǒng)調(diào)用

應(yīng)用程序直接系統(tǒng)調(diào)用步驟

從上圖得知,執(zhí)行一個(gè)系統(tǒng)調(diào)用很復(fù)雜,需要干很多的活,Linux的編譯器提供了很多共享庫(kù)(so文件)來(lái)提供系統(tǒng)調(diào)用,例如Linux的glibc庫(kù)就提供了文件操作相關(guān)的系統(tǒng)調(diào)用,例如下面的代碼:

int read(int fd,void *buf,int count);//讀文件數(shù)據(jù)int write(int fd,const void *buf,int couint);//寫文件數(shù)據(jù)int open(const char * pathname,int flags,mode_t mode);//打開文件

上面的代碼只是glibc庫(kù)中幾個(gè)比較有代表性的例子,linux操作系統(tǒng)提供了幾百個(gè)系統(tǒng)調(diào)用,這些系統(tǒng)調(diào)用分散在各個(gè)共享庫(kù)中,這里就不再闡述。

Windows操作系統(tǒng)提供了API,簡(jiǎn)稱Windows API或者SDK,它不是系統(tǒng)調(diào)用而是對(duì)系統(tǒng)調(diào)用做了二次封裝,這些API是由各類DLL(動(dòng)態(tài)鏈接庫(kù))提供的,開發(fā)人員導(dǎo)入這些DLL就可以通過(guò)Windows API來(lái)開發(fā)Windows應(yīng)用程序,因此Widows應(yīng)用程序執(zhí)行系統(tǒng)調(diào)用的步驟就變成了如下圖所示

徹底搞懂系統(tǒng)調(diào)用

Windows應(yīng)用程序系統(tǒng)調(diào)用步驟

正如上文所述,每個(gè)操作系統(tǒng)都提供它各自的系統(tǒng)調(diào)用,那么寫一段C代碼怎樣能做到跨操作系統(tǒng)呢?答案是C語(yǔ)言標(biāo)準(zhǔn)庫(kù),C語(yǔ)言標(biāo)準(zhǔn)庫(kù)的目的就是讓開發(fā)人員寫一段C代碼,這些C代碼使用的是C標(biāo)準(zhǔn)庫(kù),那么這段代碼不需要進(jìn)行任何修改就可以跨操作系統(tǒng),前提是經(jīng)過(guò)不同操作系統(tǒng)編譯器的編譯,C標(biāo)準(zhǔn)庫(kù)的調(diào)用關(guān)系如下圖

徹底搞懂系統(tǒng)調(diào)用

C標(biāo)準(zhǔn)庫(kù)

由上圖得知,Linux通過(guò)共享庫(kù)直接提供系統(tǒng)調(diào)用,而Windows則通過(guò)Windows API間接進(jìn)行提供系統(tǒng)調(diào)用,中間增加了一個(gè)C標(biāo)準(zhǔn)庫(kù),它將不同操作系統(tǒng)之間系統(tǒng)調(diào)用標(biāo)準(zhǔn)化,做了二次封裝,簡(jiǎn)化了系統(tǒng)調(diào)用的復(fù)雜度,提供給應(yīng)用程序。

標(biāo)準(zhǔn)庫(kù)也有它的缺點(diǎn),缺點(diǎn)就是只能取各個(gè)操作系統(tǒng)系統(tǒng)調(diào)用的交集,這意味著只有操作系統(tǒng)都有的功能才能納入到標(biāo)準(zhǔn)庫(kù),然后有的時(shí)候,需要一些操作系統(tǒng)專有的功能時(shí),還得直接進(jìn)行系統(tǒng)調(diào)用或者調(diào)用API,這個(gè)就會(huì)出現(xiàn)跨系統(tǒng)的問題。

對(duì)于用標(biāo)準(zhǔn)庫(kù)開發(fā)的應(yīng)用程序,它的系統(tǒng)調(diào)用步驟可以總結(jié)如下圖

徹底搞懂系統(tǒng)調(diào)用

C標(biāo)準(zhǔn)庫(kù)系統(tǒng)調(diào)用

好了,【什么是系統(tǒng)調(diào)用】的話題介紹到這里了,下面來(lái)看看系統(tǒng)調(diào)用具體是怎么實(shí)現(xiàn)的。

系統(tǒng)調(diào)用的實(shí)現(xiàn)?

上個(gè)環(huán)節(jié)闡述的是【什么是系統(tǒng)調(diào)用】以及系統(tǒng)調(diào)用的大致步驟,這個(gè)環(huán)節(jié)將以Linux操作系統(tǒng)為例來(lái)闡述系統(tǒng)調(diào)用的實(shí)現(xiàn)原理和細(xì)節(jié),當(dāng)然其它操作系統(tǒng)系統(tǒng)調(diào)用的實(shí)現(xiàn)原理比較相似,可以舉一反三。

主流的操作系統(tǒng)如Linux和Windows是通過(guò)中斷來(lái)實(shí)現(xiàn)系統(tǒng)調(diào)用的。

以操作系統(tǒng)Linux(2.5以前),處理器為Inter IA-32為例,看看fork這個(gè)系統(tǒng)調(diào)用是怎么實(shí)現(xiàn)的,其它的Linux系統(tǒng)調(diào)用類似,整體過(guò)程如下圖

徹底搞懂系統(tǒng)調(diào)用

Linux系統(tǒng)調(diào)用過(guò)程

上圖為系統(tǒng)調(diào)用涉及到的9個(gè)步驟,我們逐個(gè)看起

1.應(yīng)用程序調(diào)用linux庫(kù)提供的fork函數(shù),發(fā)起一個(gè)fork系統(tǒng)調(diào)用,這個(gè)系統(tǒng)調(diào)用的目的是創(chuàng)建一個(gè)子進(jìn)程,這個(gè)子進(jìn)程拷貝一份父進(jìn)程的虛擬進(jìn)程空間。

2.fork函數(shù)的第一步就是將2放入寄存器eax,每個(gè)系統(tǒng)調(diào)用都有一個(gè)編號(hào),2就是fork系統(tǒng)調(diào)用的編號(hào),eax是默認(rèn)用于傳遞系統(tǒng)調(diào)用編號(hào)的寄存器。

如果系統(tǒng)調(diào)用有參數(shù),則將參數(shù)傳入到如下的寄存器EBX,ECX,EDX,ESI,EDI,EBP,可以看出系統(tǒng)調(diào)用最多支持6個(gè)參數(shù),fork系統(tǒng)調(diào)用沒有參數(shù)。

fork函數(shù)的第二步就是執(zhí)行中斷指令int 0x80,中斷指令int用于發(fā)送中斷信號(hào)給處理器,0x80為中斷向量號(hào),這個(gè)向量號(hào)是系統(tǒng)調(diào)用中斷處理程序?qū)S谩?/p>

int指令同時(shí)也會(huì)將模式從用戶態(tài)切換到內(nèi)核態(tài),用戶棧切換到內(nèi)核棧,同時(shí)會(huì)將當(dāng)前被中斷的應(yīng)用程序,中斷時(shí)的寄存器內(nèi)容入棧(SS,ESP,EFLAGS,CS,EIP),這里的入棧指的是入內(nèi)核棧(每一個(gè)應(yīng)用程序都一個(gè)用戶棧和內(nèi)核棧)。

整體來(lái)看,2步驟的匯編代碼如下:

push EAX,2;//設(shè)置fork系統(tǒng)調(diào)用的系統(tǒng)調(diào)用編號(hào)mov EBX,arg1;//可選,參數(shù)1mov ECX,arg1;//可選,參數(shù)2mov EDX,arg1;//可選,參數(shù)3mov ESI,arg1;//可選,參數(shù)4mov EDI,arg1;//可選,參數(shù)5mov EBP,arg1;//可選,參數(shù)6int 0x80;//發(fā)送系統(tǒng)調(diào)用中斷信號(hào)

3.處理器執(zhí)行完當(dāng)前的指令后,會(huì)檢查處理器的中斷引腳,發(fā)現(xiàn)有中斷信號(hào),然后檢查狀態(tài)寄存器(EFLAGS),發(fā)現(xiàn)中斷屏蔽IF標(biāo)志是打開的(系統(tǒng)調(diào)用中斷信號(hào)不會(huì)被屏蔽),處理器根據(jù)中斷信號(hào),分析出中斷向量號(hào),然后根據(jù)中斷向量號(hào)去查找中斷描述符表,找到了該中斷向量號(hào)對(duì)應(yīng)的中斷處理程序。

4.操作系統(tǒng)跳轉(zhuǎn)到中斷處理程序,然后開始執(zhí)行中斷處理程序,0x80對(duì)應(yīng)的中斷處理程序是系統(tǒng)調(diào)用中斷處理程序(system_call)。

該中斷處理程序首先會(huì)將EAX,EBX,ECX,EDX,ESI,EDI,EBP這幾個(gè)寄存器入棧,之所以入棧,就是為了防止后續(xù)的工作覆蓋這些寄存器,核心匯編指令如下:

push EAX;push EBX;push ECX;push EDX;push ESI;push EDI;push EBP;

5.系統(tǒng)調(diào)用中斷處理程序緊接著根據(jù)系統(tǒng)調(diào)用號(hào)(這里就是fork系統(tǒng)調(diào)用號(hào)即2),去系統(tǒng)調(diào)用表進(jìn)行查找,可以找到該系統(tǒng)調(diào)用號(hào)對(duì)應(yīng)的處理程序(也可以叫處理函數(shù)),Linux操作系統(tǒng)的系統(tǒng)處理函數(shù)一般以sys開頭,fork的系統(tǒng)處理函數(shù)就是sys_fork。

6.找到了系統(tǒng)處理函數(shù)后,開始執(zhí)行該函數(shù),處理函數(shù)可以從內(nèi)核棧中獲取函數(shù)的參數(shù),函數(shù)執(zhí)行完成后,函數(shù)的返回值,默認(rèn)采用EAX寄存器進(jìn)行返回。

7~8.系統(tǒng)處理函數(shù)執(zhí)行完成后,回到了系統(tǒng)調(diào)用中斷處理程序,中斷處理程序執(zhí)行iret指令,iret指令負(fù)責(zé)從內(nèi)核態(tài)切換到用戶態(tài),將內(nèi)核態(tài)入棧的寄存器數(shù)據(jù)出棧到SS,ESP,EFLAGS,CS,EIP這幾個(gè)寄存器,然后跳轉(zhuǎn)到系統(tǒng)調(diào)用處。

9.系統(tǒng)調(diào)用fork返回到應(yīng)用程序。

Linux操作系統(tǒng)(2.5以前)的系統(tǒng)調(diào)用實(shí)現(xiàn)原理闡述完了,Windows操作系統(tǒng)的系統(tǒng)調(diào)用也采用類似的機(jī)制,另外要說(shuō)的是,自從Linux(2.5)以上,處理器Inter 奔騰二代以后,為了提高系統(tǒng)調(diào)用的效率,Inter處理器提供了兩個(gè)指令來(lái)進(jìn)行系統(tǒng)調(diào)用的進(jìn)入和退出即sysenter和sysexit指令。

sysenter指令代替了int中斷指令發(fā)起系統(tǒng)調(diào)用,執(zhí)行這個(gè)指令后,會(huì)直接跳轉(zhuǎn)到一個(gè)系統(tǒng)調(diào)用的處理函數(shù)地址處,去執(zhí)行系統(tǒng)調(diào)用,這個(gè)處理函數(shù)的地址是存儲(chǔ)在一個(gè)指定的寄存器中,sysenter這個(gè)指令也負(fù)責(zé)模式的切換和應(yīng)用程序現(xiàn)場(chǎng)寄存器的備份,這一點(diǎn)同int一樣,處理函數(shù)參數(shù)的傳遞跟以前一樣,還是通過(guò)寄存器的方式傳遞,沒有變化。

syscenter指令代替了iret恢復(fù)指令,它負(fù)責(zé)模式切換和現(xiàn)場(chǎng)寄存器的恢復(fù),這一點(diǎn)同iret指令相似。

其它的操作系統(tǒng)例如Power PC,AMD的系統(tǒng)調(diào)用與Linux(2.5以上)類似,不同的是,它們采用不同的指令來(lái)進(jìn)行模式切換和寄存器備份,參數(shù)的傳遞也是采用寄存器的方式,只是寄存器個(gè)數(shù)和名稱不一樣罷了。

好了,關(guān)于系統(tǒng)調(diào)用闡述完成,談下一個(gè)話題。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲精品国产精品日韩| 国内女人精品一区二区三区| 日本久久中文字幕免费| 99久热只有精品视频免费看| 欧美成人免费夜夜黄啪啪| 日韩中文无线码在线视频| 九九热精彩视频在线播放| 日本成人中文字幕一区| 亚洲一区二区精品国产av| 午夜亚洲少妇福利诱惑| 日本 一区二区 在线| 少妇人妻一级片一区二区三区| 麻豆国产精品一区二区| 在线免费视频你懂的观看| 亚洲中文字幕在线观看黑人| 久草国产精品一区二区| 十八禁日本一区二区三区| 国产欧美日韩视频91| 少妇激情在线免费观看| 亚洲欧洲在线一区二区三区| 日韩精品区欧美在线一区| 国产精品国产亚洲区久久| 中文字幕日韩无套内射| 国产精品大秀视频日韩精品| 乱女午夜精品一区二区三区| 亚洲精品深夜福利视频| 国产99久久精品果冻传媒| 久久精品国产一区久久久| 亚洲一区二区三区精选| 欧美黄色黑人一区二区| 黄色三级日本在线观看| 欧美乱妇日本乱码特黄大片| 国产国产精品精品在线| 丰满少妇高潮一区二区| 熟妇人妻av中文字幕老熟妇| 国产又大又硬又粗又黄| 精品国自产拍天天青青草原| 国产在线不卡中文字幕| 国产又粗又猛又大爽又黄同志| 中文字幕乱子论一区二区三区| 国产二级一级内射视频播放|