亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  捋一捋系統調用

捋一捋系統調用

時間:2024-02-12

最近C++技術交流群發現了很多水平很高的朋友,歡迎大家來加喵哥微信,進群一起討論計算機知識!

正文:系統調用就是調用操作系統提供的一系列內核功能函數,因為內核總是對用戶程序持不信任的態度,一些核心功能不能交由用戶程序來實現執行。用戶程序只能發出請求,然后內核調用相應的內核函數來幫著處理,將結果返回給應用程序。如此才能保證系統的穩定和安全,關于系統調用的這些理論知識不多說,書本上有一大堆,本文旨在捋清楚系統調用這條線。

總述

Linux 里系統調用是由中斷來實現的,既然利用中斷實現,那么總體來說系統調用的過程應該與中斷的過程相似。也的確如此,總體流程是差不多,但也有所區別。

每一種中斷都會有一個中斷向量號或中斷類型號,有相應的中斷服務程序也就是處理中斷的函數。但是我們應該知道,系統調用是有很多的,比如 fork,read,write 等等。雖然中斷向量號有空缺多余的,但系統調用數目更多,到2.6.23版的 Linux,就已經有325個,而中斷向量號只有 256,明顯為每一個系統調用單獨分配一個中斷向量號不現實。

那怎么解決呢,采用的辦法是直接為所有的系統調用分配一個中斷類型號,一般是 0x80,再用系統調用號來區分各個不同的系統調用

所以我們的系統調用大致流程變為根據中斷向量號去IDT中索引相應的中斷門描述符,得到選擇子和偏移量,根據選擇子去GDT中索引相應的段描述符得到段基址,與上面得到的偏移量相加得到中斷服務程序的地址。中斷處理程序根據系統調用號再調用相應的系統調用函數做具體的處理,最后返回。

上述為系統調用的大致過程,下面我們一步步地來具體看看系統調用的過程,或者說系統調用是如何實現的。

1. 用戶接口

我們平常編寫程序調用的是操作系統或者說 C 庫提供的用戶接口,也就是常說的 API,而并不是直接使用系統調用來編程,用戶接口可以看作實際的系統調用函數的封裝。

這里要注意我們平常所說的 API 和系統調用之間并沒有一定的對應關系。一個 API 可以對應一個系統調用,也可以對應多個系統調用,甚至不依賴任何系統調用,更甚多個API對應一個系統調用。所以 API 就只是一個接口,具體使用哪些系統調用實現什么功能,從理論上來講只要邏輯沒問題隨便怎么定義怎么實現都可以,但是為了可移植兼容的考慮,還是必須得遵循一定的規則,大多操作系統 API 都是遵循POSIX標準的

上述說過系統調用的用戶接口可以看作是系統調用的封裝,咱們以 getpid 來舉例具體看看:

int getpid(){
    return _syscall0(SYS_getpid);
}

2. 系統調用接口

系統調用接口指的就是上面那個 _syscall 函數,早期的 Linux 里面的 _syscall是用宏來實現的,一共有 7 個,后面跟不同的數字來區分,如_syscall0,_syscall1,分別支持0—6個參數。咱們在這兒也不搬出具體代碼解釋說明,有興趣的朋友可以自己去看看,這7個宏的實現原理都一樣,主要做了以下三件事:

  1. 系統調用號傳給 eax 寄存器
  2. 傳入參數
  3. int 80h

傳參,如果參數少,直接存到寄存器里即可,采用寄存器傳參方便而且速度快在下x86的系統上,前5個參數按順序存放在ebx, ecx,edx, esi,edi 5 個寄存中。而如果參數過多,會使用一個單獨的寄存器存放所有參數在用戶空間的地址,陷入內核后再將參數從用戶空間拷貝到內核

系統調用號和最后的返回值都存在 eax 寄存器中,約定俗成的東西。

接著就是 int n 指令,int n 就相當于發生了一個n號中斷,屬于軟中斷,雖然引發中斷的方式不同,但對中斷的處理基本是一樣的,中斷這一塊前文講述的應該很清楚了,這里不再贅述只是簡單說明一下:

  1. 有特權級變化的話壓入 ssesp,因為是系統調用,特權級是肯定發生了變化的
  2. 壓入 eflags,cs,eip 寄存器
  3. 根據中斷類型號索引 IDT 中的中斷門描述符,取出里面的內容修改 cs,eip 寄存器的值;根據 cs 里面的選擇子又去 GDT 中索引段描述符,獲取段基址。再根據 eip 中的偏移量找到系統調用服務程序。

這里對于用戶態的 ssesp 寄存器值保存作為題外話補充說明一下。不知大家有沒有想過這個問題,用戶態下的 ssesp 怎么保存到內核棧里面去的,切換到內核棧需要改變 ssesp,那原 ssesp不就丟掉了嗎?所以處理器會臨時保存 ssesp 的值,切換到內核態時再重新拷貝一份用戶態的 ssesp 的值。之后再壓入 eflagscseip 寄存器,當然如果特權級沒有發生變化,也就不會有上述過程。

這一塊兒在我寫的中斷文章里面忘記說了,在此補上,這些所有有關處理器的規則約定功能都由指令集體系結構ISA所管,它規定了我們需要做什么,提供什么,然后它就自動完成一些事情。就像調用 API 編程一樣,我們提供合理的參數,然后相應的函數自動完成一些工作。對于CPU而言同樣的道理,只是更偏向于底層具體的物理實現,但從邏輯上來講是相通的。

3. 系統調用號

每個系統調用都有自己的專屬號碼,其實就是個索引號,如下面所示:

/*...................*/
#define __NR_eixt   1
#define __NR_fork   2
#define __NR_read  3
/*...................*/

4. 系統調用服務例程

系統調用服務例程才是具體干事的內核功能函數,前面的那些用戶接口,系統調用接口,中斷服務程序都不是具體干事的,全都相當于接口一類,而這個系統調用服務例程才是具體做事的一個函數,舉個簡單例子,用 getpid 這個系統調用來說明:

int sys_getpid(void){
 return current->pid   //current指向當前進程
}

5. 系統調用表

每個系統調用都對應著一個服務例程,將它們的首地址集中起來放在一個數組里方便使用系統調用號來索引,這個表(數組一個意思)在Linux里面是 sys_call_table,就像這樣:

ENTRY(sys_call_table)
.long sys_restart_syscall
.long sys_exit
.long sys_fork

6. 系統調用服務程序

這個系統調用服務程序就是中斷服務程序,以前的哪些外設引發的中斷相應的服務程序會處理實際的事務,而系統調用前面說過不太一樣,它交給系統調用服務例程來處理的,下面來仔細看看:

system_call:
SAVE_ALL #保存上下文
push arg #壓入參數

call *sys_call_table(,%eax,4) #根據eax里面的系統調用號調用相應服務例程

mov %eax, 24(%esp) #將服務例程的返回值保存到上下文中的eax處

syscall_exit:
#返回退出

系統調用利用中斷實現,所以處理中斷要先保存上下文,因為系統調用不具體處理事務而是調用其他函數來處理,所以壓入參數然后調用函數。這是調用函數前的一慣做法:先壓入參數再調用。參數從何而來?還記得前面把參數放在寄存器里面吧,所以這兒push arg就是壓入寄存器,就不具體寫了,知道就好。

系統調用服務例程的運行結果是要傳回到用戶態的,eax 里面存放的返回值,所以當服務例程運行完后,只要將當前寄存器 eax 里面的值保存到上下文里面的 eax 處即可。在Linux2.6 里面棧頂向上 24 個字節處就是用戶態下的 eax,這個用戶態下eax的位置與具體保存上下文時如何壓棧有關,前后能夠對應上就行。

注:上述是根據  Linux2.6 簡化來的偽碼,Linux2.6里面是確有 SAVE_ALL 這個宏的,其中壓入參數就是 SAVE_ALL 的一部分,在這兒只是為了過程更清晰所以單獨寫了出來。

7. 總結捋線

上述就是系統調用的大概過程,這兒再總結總結捋一捋:

  1. 調用用戶接口函數
  2. 用戶接口封裝的是系統調用接口,早期的 Linux 里就是那7個宏
  3. _syscall 傳系統調用號,傳參,int 80h
  4. int 80h 陷入內核,保存ss,esp,eflags,cs,eip寄存器
  5. 根據中斷向量號 80h 去IDT中索引中斷門描述符,根據其內容修改 cseip 的值
  6. 根據 cs 里的選擇子去 GDT 中索引段描述符,獲得中斷(系統調用)服務程序的段基址,結合 eip 里面的偏移量就得到系統調用服務程序的地址
  7. 系統調用服務程序中 system_call 保存上下文,壓入系統調用服務例程需要的參數
  8. 根據 eax 里面的系統調用號索引 sys_call_table,然后調用執行
  9. 修改上下文中 eax 處的值,將其修改為服務例程返回值
  10. 返回,相當于第4步的逆過程

大致的過程圖如下所示:

并不是所有的系統調用都有上述的過程,在這兒只是從頭至尾的捋一捋,知曉有這么一個過程就好,畢竟本文的目的就是捋一捋系統調用這條線嘛

8. syscall說明

_syscall 宏這種形式的系統調用在 Linux 里面已經廢棄不再提供庫實現支持,因為這種方式最多支持6個參數,而且每個參數還要提供相應的類型,總共就是2n個參數。但是這種實現方式思路清晰簡單,所以上述我也是以這種實現為基來說明的。

現在 Linux 的系統調用都是用庫函數syscall來實現的,原型為:

int syscall(int number, ...);

number指的是系統調用號。從這原型就能看出,庫函數這種實現方式支持變參(...)所以能夠將所有的系統調用統一起來,不像宏實現方式不同參數的系統調用還需要使用不同的宏。


往期推薦


1、少寫點
if-else吧,它的效率有多低你知道嗎?
2、年度原創好文匯總
3、全網首發!!C++20新特性全在這一張圖里了
4、
他來了,他來了,C+
+17新特性精華都在這了
5、一文讓你搞懂設計模式
6、C++11新特性,所有知識點都在這了!


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产主播一区二区| 国产日韩欧美亚洲一区| 亚洲图片欧洲图片av| 日韩写真视频在线观看| 一区二区三区久久| 欧美在线视频一区| 欧美精品久久久久久| 欧美性开放视频| 国产免费一区二区三区香蕉精| 亚洲美女中出| 亚洲图片欧美一区| 性伦欧美刺激片在线观看| 久久综合九色综合网站| 欧美日韩黄色一区二区| 国产亚洲一本大道中文在线| 亚洲国产精品国自产拍av秋霞 | 欧美日韩www| 国产日韩av高清| 日韩视频在线永久播放| 欧美一级一区| 尤物网精品视频| 中日韩视频在线观看| 欧美在线观看视频| 欧美日韩另类一区| 亚洲丰满在线| 午夜性色一区二区三区免费视频| 欧美影视一区| 国产精品美女xx| 宅男66日本亚洲欧美视频| 午夜精品福利一区二区三区av | 亚洲国产裸拍裸体视频在线观看乱了 | 欧美视频精品一区| 在线精品国精品国产尤物884a| 亚洲午夜久久久久久尤物 | 亚欧成人精品| 欧美午夜影院| 夜夜嗨av色一区二区不卡| 快she精品国产999| 激情婷婷亚洲| 欧美在线网址| 免费观看久久久4p| 国产一区亚洲| 久久精品国产视频| 国产亚洲精品久久久久动| 亚洲一区二区成人| 欧美日韩国产999| 99视频在线精品国自产拍免费观看| 久久午夜电影| 亚洲人成人一区二区在线观看| 欧美一区二区网站| 国产日韩欧美不卡| 午夜性色一区二区三区免费视频| 国产精品成人国产乱一区| 一区二区三区回区在观看免费视频| 男同欧美伦乱| 亚洲高清视频的网址| 久久夜色精品国产噜噜av| 韩国三级电影一区二区| 欧美在线视频一区二区三区| 国产精品视频| 欧美诱惑福利视频| 国内精品久久久| 久久国产天堂福利天堂| 国产日韩av一区二区| 欧美在线在线| 黄色亚洲在线| 欧美sm极限捆绑bd| 日韩视频不卡中文| 欧美日韩国产综合网| 亚洲在线成人| 国产色综合网| 美女黄色成人网| 日韩小视频在线观看专区| 欧美日韩免费高清| 欧美一区1区三区3区公司| 伊人久久亚洲美女图片| 欧美国产在线观看| 亚洲一区二区不卡免费| 国产亚洲激情| 欧美日韩黄色大片| 久久国产日韩| 亚洲日本中文字幕免费在线不卡| 欧美视频精品在线观看| 欧美亚洲视频| 亚洲精品乱码视频| 欧美视频网站| 久久婷婷久久| 亚洲视频免费在线观看| 一区在线免费观看| 国产精品mv在线观看| 免费高清在线一区| 先锋影音久久久| 99精品黄色片免费大全| 国产欧美亚洲视频| 欧美欧美全黄| 久久久噜噜噜久久人人看| aa级大片欧美三级| 激情成人亚洲| 国产精品国产三级国产aⅴ9色| 久久精品天堂| 欧美一区二区三区日韩视频| 亚洲精品在线观看视频| 韩国一区二区三区美女美女秀| 欧美激情中文不卡| 美日韩精品视频| 久久久久久免费| 香蕉久久夜色精品国产| 一区二区久久久久久| 亚洲欧洲久久| 亚洲第一区中文99精品| 国产日韩av一区二区| 欧美全黄视频| 欧美激情精品久久久久久黑人| 久久成人免费网| 欧美在线三级| 欧美主播一区二区三区美女 久久精品人| 洋洋av久久久久久久一区| 经典三级久久| 韩国免费一区| 在线观看欧美| 亚洲国产天堂久久国产91| 国模私拍视频一区| 国产亚洲精品久久久| 国产精品高清在线| 欧美日韩免费区域视频在线观看| 免费看av成人| 欧美成人一品| 欧美不卡视频一区| 免费成人美女女| 久久亚洲欧美| 欧美国产免费| 欧美日韩免费网站| 欧美猛交免费看| 欧美日韩国产综合新一区| 欧美日韩国产综合视频在线观看中文 | 欧美日韩精品不卡| 欧美日韩成人精品| 欧美女同视频| 国产精品欧美日韩一区二区| 欧美图区在线视频| 国产欧美精品国产国产专区| 国产区精品在线观看| 国产揄拍国内精品对白| 亚洲丰满在线| 亚洲午夜久久久久久久久电影网| 亚洲综合第一| 欧美一区二区播放| 久久久青草婷婷精品综合日韩 | 中文在线一区| 亚洲欧美国内爽妇网| 久久久久久久91| 欧美jjzz| 国产精品一二| 亚洲欧洲精品一区二区三区不卡 | 国产精品扒开腿爽爽爽视频| 国产精品成av人在线视午夜片| 国产日韩高清一区二区三区在线| 韩国久久久久| 在线视频你懂得一区二区三区| 亚洲网站在线| 麻豆精品视频在线| 国产精品豆花视频| 亚洲国产一区二区a毛片| 国产精品99久久久久久宅男| 久久国产福利| 欧美精品在线视频| 国产亚洲福利一区| 一区二区三区视频在线| 久久久亚洲欧洲日产国码αv| 欧美激情bt| 国语自产精品视频在线看抢先版结局| 亚洲精品美女免费| 久久av资源网| 国产精品magnet| 亚洲黄色成人| 久久精品国产2020观看福利| 欧美日韩精品| 亚洲人成人一区二区在线观看| 欧美亚洲在线播放| 欧美日韩一区二区视频在线观看| 国内精品伊人久久久久av一坑| 在线一区二区日韩| 欧美国产精品久久| 一区二区三区中文在线观看 | 欧美黄色影院| 激情欧美亚洲| 欧美激情综合亚洲一二区 | 久久综合图片| 国产日产精品一区二区三区四区的观看方式| 亚洲国产精品久久久久秋霞蜜臀| 亚洲欧美激情四射在线日 | 久久女同精品一区二区| 国产伦精品一区二区三区照片91 | 国产一区视频观看| 9久草视频在线视频精品| 欧美成人乱码一区二区三区| 狠狠色狠狠色综合| 欧美一区国产二区| 国产一区二区三区久久| 欧美一区二视频在线免费观看|