色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

系統調用與普通的函數調用之間的區別

jf_78858299 ? 來源:碼農的荒島求生 ? 作者:碼農的荒島求生 ? 2023-02-15 11:47 ? 次閱讀

我們來聊聊系統調用與普通的函數調用之間的區別。

作為程序員你肯定寫過無數的函數,假設有這樣兩個函數:

void funcB() {
}


void funcA() {
  funcB();
}

函數之間是可以相互調用的,這很簡單很happy有沒有。

要知道是代碼、是函數就可以相互調用,不管你用什么語言寫的。

假設funcB是內核中的函數,funcA是你自己寫的函數,就像這樣:

// Linux內核中的函數void funcB() {}
// 你的函數void funcA() { funcB();}

那么funcA應該也能調用funcB(如果funcB可以供外界調用的話)。

有的同學可能會驚呼,我們可以自己編寫代碼調用操作系統的函數,那豈不是可以直接控制操作系統了?

too yong too simple!

如果我們編寫的代碼可以直接調用所有的操作系統函數那么從某種程度上講的確可以說是能控制操作系統,但如果操作系統只允許你調用內核中的有限的幾個函數呢?

怎么樣,你(應用程序)是不是就被限制住了。

你又會問,操作系統是怎樣限制應用程序能調用哪些內核中的函數呢?

實際上單靠操作系統這種軟件是沒有辦法限制應用程序能調用哪些以及多少個內核函數的,因此為施加這種限制必須依靠——硬件

這里的硬件指的就是CPU

那么CPU又是怎么施加這種限制的呢?

我們先來看看普通的函數調用,函數調用對應的機器指令是call指令,就像這樣:

call 0x400410

call指令后的這個地址0x400410就是被調函數的第一條機器指令所在的內存地址。

當CPU執行到這條機器指令時直接跳轉到對應的地址繼續執行指令,從程序員的角度看就是函數調用。

而如果是我們程序的函數調用操作系統的函數就不允許使用call指令了,而是syscall機器指令(x86_64)。

使用syscall指令調用操作系統函數時也是把相應函數的第一條指令的地址放到syscall之后嗎?

顯然不是的,因為操作系統系統代碼和你的代碼都是單獨編譯以及運行的,你根本就不知道操作系統的某個函數存放在內存的什么位置上,也不應該讓你知道,因此使用syscall調用操作系統的函數時我們只能附加一個序號,比如序號0對應操作系統中的A函數、序號1對應操作系統中的B函數等等,這樣使用syscall指令時只需要將該序號寫入rax寄存器即可,CPU在執行syscall指令時通過讀取rax寄存器的值就能知道到底該調用操作系統中的哪個函數了。

可以看到,利用這種機制操作系統限制了應用程序可以調用哪些內核中的函數。

有的同學可能會有疑問,如果一個call指令因為種種原因后面跟上的地址”無意“中指向了一個內核函數的地址,那么CPU執行call指令時會怎樣呢?就像這樣:

call 0x400410

這里假設0x400410這個地址指向了一個內核函數地址。

很簡單,CPU在執行這條指令時會判斷出當前進程沒有權限訪問0x400410這個地址,因此CPU在執行這條指令時會產生異常,該進程會被直接kill掉。

這里列舉了Linux在各種處理器上怎樣進行系統調用。

圖片

看到了吧,syscall和call在使用方法上還是有很大不同的,可以看到call是直接調用的,也就是說應用程序這一層中的函數調用是直接調用的,而syscall其實是間接調用的,即我們調用操作系統中的函數時其實是間接調用的。

除此之外,CPU在執行call指令以及syscall指令時另外一個不同點在于模式的切換。

當CPU執行普通函數時其實是運行在用戶態,user mode,在這種模式下CPU不能執行某些特權指令,這也就意味著我們的程序其實是受限的;而當CPU執行syscall開始執行操作系統的代碼時會切換到內核態,kernel mode,在這種模式下CPU可以執行任何特權指令,不受任何限制,操作系統才是真正的管理計算機的大boss。

可以看到,當在普通程序中進行函數調用時就是函數調用,而普通函數調用操作系統中的函數時才叫系統調用。

最后再說一點,普通的函數調用所使用的棧全部位于進程的棧區,假設main函數調用funcA函數,funcA調用funcB函數,那么此時的進程內存布局就像這樣:

圖片

而進行系統調用時當CPU開始執行操作系統的代碼時不再基于進程棧區而是會跳轉到操作系統某個特定內存區域,該區域作為進程在內核中的棧區,因此也叫做內核棧,每個進程在內核中都有自己的內核棧,因此我們可以看到一個進程其實有兩個棧區,一個在用戶態一個在內核態。

假設main函數調用funcA,funcA進行系統調用,調用內核中的funcB函數,funcB函數調用內核中的funcC函數,那么此時的內存布局就像這樣:

圖片

好啦,這個話題就到這里,希望對大家理解操作系統有所幫助。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 函數
    +關注

    關注

    3

    文章

    4327

    瀏覽量

    62573
  • 代碼
    +關注

    關注

    30

    文章

    4779

    瀏覽量

    68525
  • 系統調用
    +關注

    關注

    0

    文章

    28

    瀏覽量

    8324
收藏 人收藏

    評論

    相關推薦

    Linux內核中系統調用詳解

    Linux內核中設置了一組用于實現各種系統功能的子程序,稱為系統調用。用戶可以通過系統調用命令在自己的應用程序中
    發表于 08-23 10:37 ?785次閱讀
    Linux內核中<b class='flag-5'>系統</b><b class='flag-5'>調用</b>詳解

    如何查看及更改函數/函數塊的調用環境

    模塊化設計的思想是把一些相似的功能(比如電機控制、閥控制)設計成函數函數塊,這樣就可以反復調用。其優點是:使程序架構更加清晰,避免重復編寫相似功能的代碼。不過可能會產生一個疑惑:既然PLC的程序
    的頭像 發表于 11-17 09:08 ?938次閱讀
    如何查看及更改<b class='flag-5'>函數</b>/<b class='flag-5'>函數</b>塊的<b class='flag-5'>調用</b>環境

    linux內核系統調用之參數傳遞

    普通函數一樣,系統調用通常需要一些輸入/輸出參數,這些參數可能包括實際值(即數字)、用戶模式進程地址空間中的變量地址,甚至包括指向用戶模式函數
    的頭像 發表于 12-20 09:32 ?1610次閱讀

    如何確保在調用之間保留它的值?

    大家好。一個非常基本的問題讓我困惑。一個變量在ISR()文件和3個非中斷文件中更新(讀和寫),并且我希望它的生存期延長,這意味著它在函數/文件調用之間保留它的值。它將被限定為“volatile”。但是,它是否還需要具備“靜態”的資格呢?如何確保在
    發表于 03-31 07:48

    C++教程之函數的遞歸調用

    C++教程之函數的遞歸調用 在執行函數 f 的過程中,又要調用 f 函數本身,稱為函數的遞歸
    發表于 05-15 18:00 ?35次下載

    系統調用函數庫分析及實例

    作為用戶我們極少接觸系統調用,但是我們熟悉C 語言,對庫函數調用并不陌生。C語言支持一系列庫函數調用
    發表于 06-23 16:46 ?46次下載
    <b class='flag-5'>系統</b><b class='flag-5'>調用</b><b class='flag-5'>函數</b>庫分析及實例

    類成員函數普通函數區別研究

    本文的目的是研究類成員函數普通函數區別,以及不同調用方式之間
    發表于 09-15 14:52 ?32次下載

    詳解python普通函數創建與調用

    函數是一種僅在調用時運行的代碼塊。您可以將數據(稱為參數)傳遞到函數中,然后由函數可以把數據作為結果返回。
    的頭像 發表于 03-01 16:32 ?1856次閱讀

    Linux中的系統調用是怎樣實現

    系統調用普通函數調用沒有本質區別普通
    的頭像 發表于 02-15 11:40 ?1240次閱讀
    Linux中的<b class='flag-5'>系統</b><b class='flag-5'>調用</b>是怎樣實現

    C語言函數調用的形式及過程

    C語言函數調用時的數據傳遞 在調用有參函數時,主調函數和被調函數
    的頭像 發表于 03-10 14:28 ?1735次閱讀

    什么是函數調用

    函數調用,就是使用我們已經定義好的函數,或者C語言自帶的庫函數
    的頭像 發表于 04-04 17:21 ?5813次閱讀

    SCL中調用函數的示例

    在此,可插入函數 (FC) 調用函數塊 (FB) 調用函數塊可作為單實例、多重實例或參數實例進行調用
    的頭像 發表于 06-06 10:18 ?2183次閱讀

    網絡系統調用網絡套接字入口函數

    網絡套接字入口函數 //所有的網絡套接字系統調用函數(socket bind listen connect )都使用一個共同的入口函數:sy
    的頭像 發表于 07-24 11:02 ?470次閱讀

    python定義函數調用函數的順序

    定義函數調用函數的順序 函數被定義后,本身是不會自動執行的,只有在被調用后,函數才會被執行,得
    的頭像 發表于 10-04 17:17 ?1381次閱讀

    python函數函數之間調用

    函數函數之間調用 3.1 第一種情況 程序代碼如下: def x ( f ): def y (): print ( 1 ) return y def f (): print ( 2
    的頭像 發表于 10-04 17:17 ?588次閱讀
    主站蜘蛛池模板: 久久午夜免费视频| 黑色丝袜在线观看| 灌满内射HP1V1| 国产乱码一区二区三区| 国模精品一区二区三区视频| 九九热精品在线观看| 美国caopo超碰在线视频| 欧美另类摘花hd| 偷拍自怕亚洲在线第7页| 亚洲性无码av在线| 2017日日干| 丰满的女朋友 在线播放| 国产亚洲精品视频在线网| 久久三级网站| 日本少妇内射视频播放舔| 亚洲AV久久无码精品热九九| 在教室轮流被澡高H林萌| a在线视频免费观看| 国产精品色无码AV在线观看| 久久久久久久久女黄| 强奸美女老师| 亚洲成年人影院| 99福利视频| 国产无遮挡又黄又爽在线视频| 久久性生大片免费观看性| 日本撒尿特写| 伊人影院网| 俄罗斯美幼| 久久九九久精品国产尤物 | 久久草这在线观看免费| 欧美乱码伦视频免费66网| 性美国人xxxxx18| 99成人在线视频| 国产在线精品视频免费观看| 免费观看美女的网站| 小777论坛| yellow在线观看免费直播| 湖南电台在线收听| 日本少妇内射视频播放舔| 伊人久久精品线影院| 俄罗斯少女人体|