彙編臨時小結2

好多概念, 花了好長時間看懂, 過一段時間就忘得一乾二淨,等要用到時,又得從零開始看起, 實在是很浪費時間。

所以把自己剛剛看懂的東西小結一下, 以備後用。 觀點不成熟, 看的時候小心點,別被誤導了。

 

1. 實模式和保護模式段的差別。

實模式和保護模式下都使用16位的段寄存器存放段基址信息,如CS,SS,ES等。不同的是, 實模式下段寄存器中存放的就是段基址,使用時把段基址*16 加上16位的偏移量就得到20位的地址信息。而在保護模式下, 所有段定義在一張表中,也就是我們常說的GDT,每個表項以8個字節詳細定義某個段的起始地址、界限、屬性等內容,而段寄存器中存放的段值此時只是起到一個索引的作用, 它指向GDT中的某個表項, 這個索引也就是我們常說的段選擇子。使用的時候根據索引取得32位的段基址和普通寄存器中32位的段偏移,兩者共同組成了實際的物理地址。

 

2. jmp指令

有幾種常見形式:

    A. jmp xx, 跳轉至某個標號, 跳轉目標地址在當前段內。 IP的計算方法是當前IP + (跳轉標號偏移-當前標號偏移)

實模式下偏移和保護模式的偏移概念是不一樣的, 但因爲IP的計算方法使得在實模式和保護模式下都能成功跳轉至目標標號。

    B. jmp xx:xx,跳轉至某個段內某偏移, 前一個xx表示目標段, 後一個表示目標偏移。

 

3. $$ 表示當前節(section)開始的地址。

 

4. 描述符基本結構: 段基址(32位), 段界限(20位), 段屬性。通過一個8字節的描述符,詳細定義了一個段的相關信息。

 

5. 調用門結構: 指向目標段的GDT selector(16位),目標段偏移(32位),屬性(裏面包括param count, TYPE, DPL等)。這所有信息也是通過一個描述符來表示的, 並放在GDT中。

 

6. 特權級轉移

通常代碼裏的跳轉都是在段內進行的,但有時需要進行段間轉移。 先假設當前段DPL爲x。

不通過調用門,而直接通過jmp或者call跳轉時, 有以下規則:

一致代碼段: CPL>=x, 可以訪問,且跳轉後CPL不變。

非一致代碼段, CPL=x,且RPL<=x

 

可以看到,直接跳轉是非常有限的,要想自由跳轉,還需要通過調用門。

通過調用門,訪問規則如下(設調用門的DPL爲DPL_G):

一致代碼段: CPL<=DPL_G, RPL<=DPL_G, CPL>=x

非一致代碼段: 通過call指令時: CPL<=DPL_G, RPL<=DPL_G, CPL>=x, 通過jmp指令時: CPL<=DPL_G, RPL<=DPL_G, CPL=x

通過調用門,可以很好的實現低特權級向高特權級跳轉。

同時需要注意: 在通過調用門跳轉時,需要通過TSS保留從0~2的SS和EIP

 

 

 

 

7. CPL,RPL,DPL

《自己動手寫操作系統》第二版49頁寫得很清楚。 

 

8. 分頁機制

一個內存地址的大小是32位, 低12位存放頁內偏移(也即1頁有4k大小), 中間10位指示該內存地址在哪一頁(一個頁目錄有1024頁),高10位指示處於那個頁目錄(總共有1024個頁目錄)。

 

 

PDE存放的是頁目錄表, 它最多有1024項, 每一項指向每個頁目錄的起始地址。

PTE存放的是頁表,  它最多有1024*1024項, 每一項指向某個頁的物理地址。

分頁通過PDE-PTE兩級映射。 Cr3存放頁目錄基地址。

 

9. 中斷和異常

中斷通常在程序執行時因爲硬件而隨機發生, 通常用來處理cpu外部的事件, 比如外圍設備的請求。

異常則通常在cpu執行指令過程中檢測到錯誤時發生,比如遇到零除的情況。

當它們發生時, 都需要跳轉到相應的處理程序中做相應處理, 對於中斷我們通過中斷向量來表示。

在實模式中的中斷向量具體是怎樣? 這個待研究。

 

在保護模式中, 首先需建立硬件中斷與向量號之間的對應關係, 如鍵盤中斷對應IRQ0, 鼠標中斷對應IRQ1等。 

 

中斷向量通過IDT進行描述,和GDT類似, 它通過lidt命令加載IDT基址。 這個IDT可以理解爲一個數組,其中的每個元素就叫做IDT描述符,描述符的基本結構是目標選擇子, 目標偏移, 屬性。 IDT[0]就表示IRQ0,IDT[1]表示IRQ1, 依此類推, 形成所謂的中斷向量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章