欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C程序函數(shù)調(diào)用&系統(tǒng)調(diào)用

 更新時間:2024年06月13日 09:00:52   作者:by_mzy  
這篇文章主要介紹了C程序函數(shù)調(diào)用&系統(tǒng)調(diào)用,需要的朋友可以參考下

理解程序的執(zhí)行

我們要知道CPU可以自由地訪問寄存器、內(nèi)存。另外,程序是由操作系統(tǒng)執(zhí)行的,所以操作系統(tǒng)能夠控制程序的所有執(zhí)行情況,限制程序的行為。

程序地執(zhí)行過程:

  • 程序是一個二進制文件,包含程序的代碼指令、代碼中的文本信息等(參考C語言的程序的各種段)
  • 執(zhí)行一個程序后,會將這個二進制加載到內(nèi)存中,那么這個程序的代碼(想象成各種匯編指令)也就記載道了內(nèi)存中
  • CPU執(zhí)行程序時從固定的位置main處開始執(zhí)行(eip寄存器指向這里),逐條語句讀取執(zhí)行(這是CPU自帶的功能)
    • 語句可能發(fā)生跳轉(zhuǎn)(eip切換到其他匯編指令出)
    • 語句可能會操作棧(其實就是往一塊特殊地內(nèi)存空間寫入數(shù)據(jù)、讀出數(shù)據(jù),CPU有相關(guān)的指令pop push解決這個問題)
  • 程序可能會執(zhí)行系統(tǒng)調(diào)用(操作系統(tǒng)賦予的能力,例如讀寫文件,網(wǎng)絡(luò)通信等)?,F(xiàn)代操作系統(tǒng)將這些能力都放到了內(nèi)核態(tài)來執(zhí)行了,即只有內(nèi)核代碼才能做實際的讀寫文件操作,普通用戶程序只能通過系統(tǒng)調(diào)用來執(zhí)行這些能力。
    • 所以執(zhí)行系統(tǒng)調(diào)用后,cpu就會相應(yīng)地跳轉(zhuǎn)到系統(tǒng)調(diào)用地入口處(這個系統(tǒng)調(diào)用的入口也時固定的,對應(yīng)的是內(nèi)核中的一段C代碼
    • 內(nèi)核的系統(tǒng)調(diào)用入口函數(shù),根據(jù)系統(tǒng)調(diào)用號(對每個系統(tǒng)調(diào)用的標識),找到相應(yīng)的處理函數(shù)執(zhí)行(其實也是執(zhí)行call函數(shù))
    • 系統(tǒng)調(diào)用處理完后,繼續(xù)返回到用戶自己的程序代碼處執(zhí)行(所以,在執(zhí)行系統(tǒng)調(diào)用前需要把用戶代碼執(zhí)行的位置記錄下來,并且在系統(tǒng)調(diào)用結(jié)束后自動設(shè)置eip指向這個地方)

函數(shù)調(diào)用

C語言函數(shù)調(diào)用關(guān)鍵

c語言函數(shù)調(diào)用的幾個關(guān)鍵點在于:

  • 保護調(diào)用者的上下文(寄存器、棧指針(ebp,esp)信息)
  • 將傳入?yún)?shù)通過esi、edi等放到被寄存器中、或者push到棧中(當(dāng)參數(shù)比較多時)
  • 執(zhí)行call調(diào)用函數(shù),call的副作用是將eip壓入到棧中
  • 將計算的返回值放到eax中
  • pop出ebp、esp
  • 執(zhí)行ret,將eip從棧中pop出來,然后指令繼續(xù)執(zhí)行重新回到調(diào)用者上下文(將esp指向調(diào)用者調(diào)用函數(shù)后的語句)

系統(tǒng)調(diào)用

  • syscall sysenter sysret
  • int 0x80

在 x86-64 架構(gòu)上,當(dāng)應(yīng)用程序需要執(zhí)行系統(tǒng)調(diào)用時,CPU 會從用戶態(tài)切換到內(nèi)核態(tài),經(jīng)歷以下過程:

  • 用戶態(tài)程序執(zhí)行 syscall 指令:
    • 用戶態(tài)程序通過執(zhí)行 syscall 指令來觸發(fā)系統(tǒng)調(diào)用請求。
  • CPU 切換到內(nèi)核態(tài):
    • syscall 指令會引發(fā)一個特殊的異常,導(dǎo)致 CPU 從當(dāng)前的用戶態(tài)特權(quán)級切換到內(nèi)核態(tài)的更高特權(quán)級。
    • 這個過程會自動保存用戶態(tài)的部分寄存器狀態(tài),如 rip、rflags 等,并將控制權(quán)轉(zhuǎn)交給內(nèi)核。
  • 內(nèi)核處理系統(tǒng)調(diào)用:
    • 內(nèi)核接管控制權(quán)后,會根據(jù)系統(tǒng)調(diào)用號找到對應(yīng)的系統(tǒng)調(diào)用處理函數(shù),并執(zhí)行相應(yīng)的操作。
    • 內(nèi)核執(zhí)行完成后,會將結(jié)果返回給用戶態(tài)程序。
  • 從內(nèi)核態(tài)切換回用戶態(tài):
    • 內(nèi)核執(zhí)行完系統(tǒng)調(diào)用處理后,會通過 sysret 指令從內(nèi)核態(tài)切換回用戶態(tài)。
    • sysret 指令會自動恢復(fù)之前保存的用戶態(tài)寄存器狀態(tài),并將控制權(quán)轉(zhuǎn)回給用戶態(tài)程序。

整個切換過程由硬件和操作系統(tǒng)內(nèi)核共同完成,應(yīng)用程序感知不到這個切換過程。這種基于硬件支持的用戶態(tài) - 內(nèi)核態(tài)切換機制,能夠大幅降低系統(tǒng)調(diào)用的開銷,提高操作系統(tǒng)的整體性能。
需要注意的是,除了 syscall/sysret 指令,Intel 的 x86-64 架構(gòu)也支持使用 int 0x80 軟中斷來執(zhí)行系統(tǒng)調(diào)用,不過 syscall/sysret 方式通常更加高效。

cpu的特權(quán)級別(privilege level )

chatgpt告訴我們:Linux 系統(tǒng)通過以下幾種方式來實現(xiàn)當(dāng)前特權(quán)級別的切換:

  • 系統(tǒng)調(diào)用:
    • 用戶態(tài)應(yīng)用程序通過系統(tǒng)調(diào)用機制從 Ring 3 切換到 Ring 0 內(nèi)核態(tài)。
    • 應(yīng)用程序執(zhí)行 int 0x80 或 syscall 指令觸發(fā)軟中斷,CPU 切換到 Ring 0 執(zhí)行內(nèi)核代碼。
    • 內(nèi)核處理完成后,通過 iret 或 sysret 指令返回到用戶態(tài)。
  • 中斷/異常處理:
    • 當(dāng) CPU 遇到硬件中斷或軟件異常時, 會自動從當(dāng)前特權(quán)級切換到 Ring 0 內(nèi)核態(tài)。
    • 內(nèi)核處理完中斷/異常后,通過 iret 指令返回到之前的特權(quán)級別。
  • 特權(quán)級切換指令:
    • x86 架構(gòu)提供了一些用于特權(quán)級切換的指令,如 call gate、task gate 等。
    • 這些指令可以在不同特權(quán)級之間跳轉(zhuǎn),并自動完成上下文切換。
  • 進程切換:
    • 當(dāng)內(nèi)核需要切換進程時,會切換進程的特權(quán)級別。
    • 內(nèi)核將新進程的特權(quán)級別設(shè)置為 Ring 3,并通過 iret 指令返回到用戶態(tài)。

在 Linux 中,大多數(shù)情況下都是通過系統(tǒng)調(diào)用和中斷/異常處理來實現(xiàn)特權(quán)級切換。內(nèi)核代碼運行在 Ring 0 級別,用戶態(tài)應(yīng)用程序運行在 Ring 3 級別。當(dāng)應(yīng)用程序需要訪問受保護的系統(tǒng)資源時,會通過系統(tǒng)調(diào)用陷入內(nèi)核態(tài),由內(nèi)核代碼執(zhí)行相應(yīng)的操作。中斷和異常處理也會觸發(fā)內(nèi)核態(tài)的切換,內(nèi)核負責(zé)處理各種硬件事件??傊?Linux 系統(tǒng)利用 CPU 硬件提供的特權(quán)級機制,通過系統(tǒng)調(diào)用、中斷/異常處理、特權(quán)級切換指令等方式,實現(xiàn)了內(nèi)核態(tài)和用戶態(tài)之間的特權(quán)級切換,保證了系統(tǒng)的安全和穩(wěn)定性。

Ring 0和Ring 3也有其他區(qū)別,例如Ring 0 程序可以執(zhí)行所有的 CPU 指令集,包括特權(quán)指令。Ring 3 程序只能執(zhí)行非特權(quán)指令集,無法直接執(zhí)行特權(quán)級別的指令。

到此這篇關(guān)于C程序函數(shù)調(diào)用&系統(tǒng)調(diào)用的文章就介紹到這了,更多相關(guān)C程序函數(shù)調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VS Code C/C++環(huán)境配置教程(無法打開源文件“xxxxxx.h”或者檢測到 #include 錯誤,請更新includePath)(POSIX API)

    VS Code C/C++環(huán)境配置教程(無法打開源文件“xxxxxx.h”或者檢測到 #include 錯誤,請更新in

    這篇文章主要介紹了VS Code C/C++環(huán)境配置教程(無法打開源文件“xxxxxx.h” 或者 檢測到 #include 錯誤。請更新includePath) (POSIX API),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • C語言八道筆試題精講帶你掌握指針

    C語言八道筆試題精講帶你掌握指針

    C語言這門課程在計算機的基礎(chǔ)教學(xué)中一直占有比較重要的地位,然而要想突破C語言的學(xué)習(xí),對指針的掌握是非常重要的,本文將具體針對指針的基礎(chǔ)做詳盡的介紹
    2022-07-07
  • C語言實現(xiàn)的循環(huán)單鏈表功能示例

    C語言實現(xiàn)的循環(huán)單鏈表功能示例

    這篇文章主要介紹了C語言實現(xiàn)的循環(huán)單鏈表功能,結(jié)合實例形式分析了基于C語言實現(xiàn)的循環(huán)單鏈表定義、創(chuàng)建、添加、刪除、打印、排序等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • C++日期與時間 chrono庫介紹及使用教程

    C++日期與時間 chrono庫介紹及使用教程

    chrono庫是C++11中的一個標準庫,它提供了一系列與時間相關(guān)的類和函數(shù),用于表示和處理時間間隔,時鐘和時間點,C++20新增Calendar,這篇文章主要介紹了C++日期與時間 chrono庫介紹及使用,需要的朋友可以參考下
    2023-12-12
  • Java?C++題解leetcode1598文件夾操作日志搜集器

    Java?C++題解leetcode1598文件夾操作日志搜集器

    這篇文章主要為大家介紹了Java?C++題解leetcode1598文件夾操作日志搜集器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • C++中string使用+號與int拼接方式

    C++中string使用+號與int拼接方式

    這篇文章主要介紹了C++中string使用+號與int拼接方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • c++實現(xiàn)二路歸并排序的示例代碼

    c++實現(xiàn)二路歸并排序的示例代碼

    這篇文章主要介紹了c++實現(xiàn)二路歸并排序的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • C++賦值運算符

    C++賦值運算符

    這篇文章主要介紹了C++賦值運算符,C++當(dāng)中允許類對象賦值,這是通過默認的重載賦值運算符實現(xiàn)的,下面我們就來介紹介紹該內(nèi)容吧,,需要的朋友可以參考一下
    2022-01-01
  • 淺談C++中const與constexpr的區(qū)別

    淺談C++中const與constexpr的區(qū)別

    C++11中新增加了用于指示常量表達式的constexpr關(guān)鍵字。本文將帶大家詳細了解一下const與constexpr之間的區(qū)別,需要的小伙伴們可以參考一下
    2021-11-11
  • C++實現(xiàn)單例模式的自動釋放

    C++實現(xiàn)單例模式的自動釋放

    這篇文章主要為大家詳細介紹了C++實現(xiàn)單例模式的自動釋放,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06

最新評論