1. 程式人生 > >《Linux核心原理與設計》第五週作業

《Linux核心原理與設計》第五週作業

使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫

方法一:使用庫函式API在螢幕上顯示程序的ID

    先在實驗樓中開啟XFCE,在目錄下輸入指令: vi getpid.c;新建並開啟getpid.c檔案。

    隨後再在VI中輸入在網上查閱的實現getpid的函式程式碼後,儲存並退出。

    隨後再同gcc將該函式程式碼進行編譯。再通過輸入指令./getpid即可得出目前程序的ID為:22056.

實驗樓

實驗樓

這種方式是用C語言使用庫函式API進行系統呼叫。

方法二:使用C語言內嵌彙編程式碼在螢幕上顯示程序ID

實驗樓

實驗樓

對於內嵌彙編呼叫system_call()

    1、系統呼叫號放入eax中。

    2、系統呼叫的引數,按照順序存入相應暫存器中。

    3、返回值使用eax傳遞值。

     因為中斷(包括異常)是從使用者態進入核心態的唯一方式,所以在上述程式碼中使用了中斷(“int $s0x80\n\t”這句),然後中斷處理程式SAVE_ALL儲存現場,隨後就進入了核心態

進行下一步的操作。
  • 中斷處理
     中斷處理是從使用者態進入核心態主要的方式,系統呼叫是一種特殊的中斷。

     中斷處理的完整過程(由中斷訊號或者int指令完成): 將cs:eip的值,堆疊段暫存器當前的棧頂(ss:eip)和當前的標誌暫存器(eflags)儲存到核心堆疊中;同時將當前中斷服

務例程的入口載入到cs:eip中,當前堆疊段和eip也載入到CPU中。執行完以上以上步驟之後,當前CPU在執行下一條指令時,就已經開始執行整個中斷處理程式的入口了。此時已經

開始操作核心態的堆疊了。

     若完成中斷服務之後不發生程序排程,則繼續執行指令(RESTORE_ALL和iret),然後返回到原來的狀態;

     若發生程序排程,那麼當前發生的狀態都會暫時的儲存在系統中,當下一次發生排程再次回到當前程序時就繼續執行指令RESTORE_ALL和iret。
  • 系統呼叫的工作機制:

      使用者態中xyz()函式就是系統呼叫對應的API;

      這個API中封裝了一個系統呼叫,這個系統呼叫會觸發int 0x80的一箇中斷;

      0x80這個中斷向量就對應著system_call(核心程式碼的入口起點);

      核心程式碼中可能會執行到對應的中斷服務程式sys_xyz();

      在中斷服務程式執行完之後,可能會執行ret指令,此時可能會發生程序排程;

      如果沒有發生程序排程,就執行iret,返回到使用者態接著執行其他指令。

###實驗總結:

       即便是最簡單的程式,也難免要用到諸如輸入、輸出以及推出等操作,而要進行這些操作則需要呼叫作業系統所提供的服務,也就是系統呼叫。除非程式中只完成加減乘除等數學

演算法,否則將很難避免使用系統呼叫。在Linux平臺下有兩種方式來採用系統呼叫:利用封裝後的C庫或者通過彙編直接呼叫。

      這次實驗,我知道了如何進行系統呼叫,但是對於程式碼,我只能選擇借鑑,彙編的知識也不太熟練,不過這次實驗讓我更加熟悉了系統呼叫的本質和系統呼叫與中斷的關聯。中斷

處理是從使用者態進入核心態的主要方式,系統呼叫是一種特殊的中斷。

###系統呼叫的工作機制:

       1、使用者態中的xyz()函式就是系統呼叫所對應的系統API;

       2、在這個API中將系統呼叫封裝好,並在執行時觸發int 0x80這個中斷。對應核心態的system_call();
 
       3、system_call()中可能會執行中斷服務程式sys_xyz()