《自己動手寫作業系統》讀書筆記 初識保護模式

2021-05-23 17:09:47 字數 2811 閱讀 3602

書本第三章第一節是《認識保護模式》,初步 講解了保護模式下全域性描述符表gdt、段描述符、段選擇子、從實模式進入保護模式等內容。去年看這個的時候,如果不是有以前學習保護模式時做的筆記,還真 不好懂呢,因為作者提供的材料不夠系統,對僅學習過8086組合語言的人來說,是不太好理解的。下面的內容大體以我以前做的筆記為綱,較為簡略,只說明要 點。(本來還可以參考下以前學習保護模式時收集的資料的,很可惜,行動硬碟壞了,資料都沒有了,早就該注意資訊保安了的。)

8086是16位處理器,有16位的暫存器和資料匯流排,20位的位址匯流排,定址能力為1mb。位址由段基址和段偏移兩部分組成,段基址和偏移位址都是16 位的,實體地址的計算方式為:實體地址=段基址×16+段偏移。從80386開始,intel處理器進入了32位時代,位址匯流排為32位,定址能力為 4gb。此時,通用暫存器變成從16位變成了32位,但段暫存器仍然是16位的,原來的基位址加偏移值的實體地址計算方法已經不適用了,需要新的計算方 法。

386以上cpu執行於保護模式時,雖然段暫存器仍然是16位的,但是其意義已經發生了變化:不再是表示段基位址了,而是表示段描述符在描述符表中的索引。此時,段暫存器的值也有了乙個新的名稱:段選擇子。

段描述符

是 描述段屬性的乙個8位元組資料結構,分為三種型別:(資料段和**段)段描述符、系統段描述符和門描述符。書本第43頁給出了描述符的結構圖。書中說「由於 歷史問題,它們(描述符中的段基址和段偏移)都被拆開存放」。我想,這個歷史問題是指為相容80286處理器的設計吧:80286採用24位位址線,定址 能力16mb,所以段基址被拆開成低24位和高8位兩部分;80286已經引入「保護模式」的概念,是推出實模式和保護模式cpu的分水嶺。附兩個粗略介 紹80286的**:http://wiki.ccw.com.cn/80286  ,http://baike.baidu.com/view/193778.htm

描述符表 是記憶體中儲存乙個或者多個描述符的區域,由相關暫存器(gdtr、ldtr、idtr)指示其起始位址。有三種描述符表:

gdt global description table 全域性描述符表

ldt local description table  區域性描述符表

idt interrupt description table 中斷描述符表

段選擇子 是 段暫存器的內容。雖然386處理器中段暫存器還是16位的,但是在保護模式下,其內容的意義已經發生了變化,不再是表示段基位址,而是表示段描述符在描述 符表中的位置。其中第0位和第1位是rpl(request privilege level 請求特權級),用以進行訪問許可權檢查,這個以後再詳細描述;第2位是ti(task indication,任務指示),其值為0表示使用gdt,為1表示使用ldt;第3至15位是段描述符在相應的描述符表中的索引。

實模式下的定址方式同8086:段基位址×16+段偏移位址。

保護模式下使用48位位址指標:16位段選擇子和32位段偏移位址。定址過程為:從相應的段暫存器中取出段選擇子,根據高13位從相應的描述符表中取得段 描述符;用段描述符給出的32位段基位址,加上32位的偏移位址得到32位線性位址;如果沒有啟用分頁,則32位線性位址就是實體地址,否則線性位址再經 過分頁機制轉化成實體地址。當然,定址過程中會根據段描述符給出的段屬性進行各種檢查,如特權級檢查、位址越界檢查、段頁是否存在檢查等。

我覺得,沒有給出386的暫存器模型是本書的一大缺憾。這裡給出386的暫存器模型並作簡要說明。(這張圖我花了好長時間用wps office畫的)

圖中陰影部分是實模式下可用的暫存器。

eax、ebx、ecx、edx:8086中的通用暫存器已經擴充套件成32位的了。當然,還是可以使用ax、bx、cx、dx訪問低16位;或者用ah、al等分別訪問低16位的高低兩個位元組。

cs、ds、ss、es、fs、gs:新增了fs和gs這兩個16位的段暫存器。cs、ds、ss、es的用途不變,還是**段、資料段、堆疊段和擴充套件段暫存器;fs和gs也可以看作是方便程式設計師使用的擴充套件段暫存器。

eip:位址變成32位了,指令指標當然也要擴充套件成32位的了。

esp、ebp、esi、edi:堆疊指標、基址指標、源變址、目標變址暫存器,名字前面加上字母e表示擴充套件成32位了。

eflags:標誌暫存器也變成32位的了。

以下是386新增的暫存器:

idtr、gdtr和ldtr:idtr和gdtr是48位的,分別用以儲存中斷描述符表和全域性描述符表的基位址(32位)和限長(16位)。ldtr保 存區域性描述符的段選擇子,其使用方式為:1 在ldtr中裝入段選擇子,cpu自動從gdt中取出區域性描述符,放入快取記憶體中,為當前任務建立ldt;2 以後使用段暫存器中的選擇子時,若發現ti位為1,則從ldt中找到相應的段描述符進行定址操作。

tr:任務暫存器,存放任務狀態段選擇子,指示任務狀態段描述符在gdt中的位置(類似ldtr)。使用方式類似ldtr:在tr中裝入段選擇子,cpu 自動從gdt中取出任務狀態段描述符,放入快取記憶體中,為當前任務建立tss。tss是task state segment(任務狀態段)的簡寫,它定義了啟動任務所需要的資訊,簡言之(不太準確),就是乙個程序的相關資訊。

cr0、cr1、cr2、cr3、cr4:控制暫存器,儲存了系統的各種標誌位。其中cr0的低16位就是8086中的msw(machine state word,機器狀態字)。這裡需要關注的是cr0的第0位pe標誌,其值為0表示當前執行在實模式下;為1表示執行於保護模式下。

書本上給出了進入保護模式的**,還有詳細的說明,我就不給自己的**了,只對乙個地方進行簡要說明:為什麼要在gdt的起始位置處定義乙個沒有使用的空的描述符?  

這個問題我想了好久也沒想通,後來在網上找到了答案:gdt中索引為0的描述符是特殊的空描述符,是不能使用的,如果使用它進行儲存器訪問,會引發genernal protection異常。關於這個問題,可以參考http://leonstar.bokee.com/36918.html

《自己動手寫作業系統》讀書筆記

a 熟悉8086的機制 b 了解pc機的介面 c 有過彙編 程式設計的經歷 d 對程式語言有敏感性 e 對作業系統原理熟悉,最好有dos windows和linux的使用經驗 不過這些也不是絕對的,只要有興趣,都可以開始,不過就需要多準備幾本書,開列書單如下 ibm組合語言程式設計 作業系統dos篇...

自己動手寫作業系統讀書筆記系列導引

自己動手寫作業系統讀書筆記系列導引 天之痕 http blog.csdn.net lingang 刺蝟 http blog.csdn.net littlehedgehog 自己動手讀書筆記系列 本來只是些天之痕和我在這乙個多月研究 自己動手寫作業系統 時且看且記的小段筆記批註而已,文章裡都是記錄些環...

自己動手寫作業系統讀書筆記系列 導引

自己動手寫作業系統讀書筆記系列導引 刺蝟 自己動手讀書筆記系列 本來只是些天之痕和我在這乙個多月研究 自己動手寫作業系統 時且看且記的小段筆記批註而已,文章裡都是記錄些環境搭建 程式設計所感的自娛自樂文字,沒想過今天還會來整訂成乙個小系列。是時,天之痕還忙著添上他的 自己動手寫作業系統 環境配置 呵...