天天看點

java開發系統核心:像Linux一樣使用中斷實作核心API

我們目前提供的核心API有個問題,就是每次使用時,需要計算API函數在核心中的位置,一旦核心代碼改變,API接口的位置也會改變,同時調用API的應用程式也必須跟着改變,顯然這種限制是不可接受的。

為了突破目前缺陷,我們必須想出新的API提供辦法。常用的做法是,仿照Linux 将API當做一個中斷調用,由此應用程式在使用API時,隻需要記住API對應的中斷号,然後使用指令int 即可,這樣無論API接口位置如何變動,應用程式的代碼都不需要重新更改。

由此在系統核心的彙編代碼部分做如下修改:

LABEL_IDT:
...
.2DH:
    Gate SelectorCode32, AsmConsPutCharHandler,, DA_386IGate
           

我們在中斷向量表中增加了一個.2D号中斷,該中斷對應的相應函數位址為AsmConsPutCharHandler。

在原來的API接口AsmConsPutChar處增加如下代碼:

asm_cons_putchar:
AsmConsPutCharHandler equ asm_cons_putchar - $$
        pushad

        push  
        and  eax, 
        push eax
        call  cons_putchar
        add  esp, 

        popad

        iretd
           

首先我們通過把函數入口位址減去段的起始位址,得到函數相對于代碼段的偏移,這個偏移的值就是AsmConsPutCharHandler, 其次asmConsPutChar一旦調用是,先執行指令pushad, 該指令的作用是把所有通用寄存器壓入堆棧,寄存器跟代碼運作的上下文密切相關,如果在調用中斷時不包含好通用寄存器,那麼從中斷傳回後,由于寄存器的改變,可能會導緻代碼邏輯出現錯誤。在APIZ執行完畢後,執行指令popad,把原先保持起來的寄存器資料重新恢複到對應的寄存器中。

使用中斷提供核心接口調用,應用程式在開發邏輯上可以得到極大的簡化,以下代碼顯示了應用程式如何調用核心API在控制台上顯示字元:

[map symbols hlt.map]
[SECTION .s32]
BITS 
mov  ax, 'L'
int DH
mov  ax,  'G'
int DH

retf
           

應用程式隻需要把要顯示的字元指派給寄存器ax, 然後出發2d号中斷就可以利用核心導出的API,實作在控制台上輸出字元的功能。同時應用程式無需估計核心代碼修改後,結構API位址會改變的問題,代碼隻需兼顧自身邏輯,于是相比于前一版本的核心調用,邏輯上得到了很大的簡化。

把上面代碼編譯後,在控制台運作hls指令後,效果如下:

java開發系統核心:像Linux一樣使用中斷實作核心API

更詳實的講解和代碼調試流程,請參看視訊。

更多技術資訊,包括作業系統,編譯器,面試算法,機器學習,人工智能,請關照我的公衆号:

java開發系統核心:像Linux一樣使用中斷實作核心API