天天看點

80x86 cpu的保護模式

轉貼 80x86 cpu的保護模式

對于學習任何程式設計語言的朋友來說掌握CPU的操作模式都是一件非常重要的事,其中就數保護模式這部分最重要了,現在關于保護模式的中文資料就隻有楊季文先生那一家還算全面,但有些人還是覺得看不太懂,為此我就寫了這篇文章,看看是否對您的胃口!

一、保護模式概述

        顧名思義,就是對程式的運作加以保護。我們知道在實模式下通常隻能尋址1M的記憶體空間,且隻能是單任務,就是說同一時間不能有兩個任務被激活。從8086/8088的20根位址線,80286的24根位址線到80386的32根位址線,直至今天Puntium4已經發展到了36根位址線,它們分别可以尋址1M、16M、4G、64G的記憶體空間,然而在實模式下,通常的尋址範圍還是1M。也就是對于在純DOS下運作的Puntium4也隻能是一個快速的8086。

        前面已經說了,保護模式就是對程式的運作加以保護,是以說保護模式較實模式的增強的最主要展現還不是尋址能力而是對多任務的支援,所提到的保護就是對不同任務間和同一任務内的程式加以保護,使它們的運作不受對方“有意”或“無意”影響,但同時也要對兩個任務都要用到的部分代碼實作共享。另外一個重要的增強就是對虛拟存儲器的支援,從一定意義上說可以使程式設計人員不必考慮實體記憶體的大小。

 有了新的模式,當然要有大量的新增寄存器的支援,學習這些寄存器也是學習保護模式的關鍵.

三個重要的系統表GDT、LDT和IDT

 首先說明的是,這三個表是在記憶體中由作業系統或系統程式員所建,并不是固化在哪裡,是以從理論上是可以被讀寫的。

 這三個表都是描述符表.描述符表是由若幹個描述符組成,每個描述符占用8個位元組的記憶體空間,每個描述符表内最多可以有8129個描述符.描述符是描述一個段的大小,位址及各種狀态的.描述符表有三種,分别為全局描述符表GDT、局部描述符表LDT和中斷描述符表IDT。

 1.全局描述符表GDT:

 全局描述符表在系統中隻能有一個,且可以被每一個任務所共享.任何描述符都可以放在GDT中,但中斷門和陷阱門放在GDT中是不會起作用的.能被多個任務共享的記憶體區就是通過GDT完成的,

 2.局部描述符表LDT:

 局部描述符表在系統中可以有多個,通常情況下是與任務的數量保持對等,但任務可以沒有局部描述符表.任務間不相幹的部分也是通過LDT實作的.這裡涉及到位址映射的問題.和GDT一樣,中斷門和陷阱門放在LDT中是不會起作用的.

 3.中斷描述符表IDT:

 和GDT一樣,中斷描述符表在系統最多隻能有一個,中斷描述符表内可以存放256個描述符,分别對應256個中斷.因為每個描述符占用8個位元組,是以IDT的長度可達2K.中斷描述符表中可以有任務門、中斷門、陷阱門三個門描述符,其它的描述符在中斷描述符表中無意義。

段選擇子

在保護模式下,段寄存器的内容已不是段值,而稱其為選擇子.該選擇子訓示描述符在上面這三個表中的位置,是以說選擇子即是索引值.

描述符

 前面已經提到,描述符是描述一個段的大小,位址及各種狀态的8個位元組的結構,在程式設計時它可以定義它.

   根據描述符所描述對象的不同,描述符可分為存儲段描述符、系統段描述符、門描述符三種,而門描述符又可分為調用門、任務門、中斷門和陷阱門四類。下面将分别介紹各描述符作用及其各位的意義:

 一、存儲段描述符

 存儲段描述符是描述程式中的代碼段和資料段的,這其中也包括堆棧段,在保護模式下,應該把堆棧段了解為特殊的資料段。

 分析存儲段描述符時應該把它分成4個域來了解:

第一個域為描述符的第0至1位元組,該字是段界線的低16位,段界線是描述段的大小共20位,高4位在第六位元組的低4位中;第二個域為描述符的第2至4位元組,這三個位元組是段基址的低24位;第三個域是描述符的第5、6位元組,該字存放的是段的一些屬性;第四個域是最後一個位元組,該位元組存放的是段基址的高8位。下面對屬性字的每一位進行描述:

 P位說明所描述的段是否存在,P=1表示描述符所描述的段存在于記憶體中,P=0表示描述符所描述的段不在記憶體中。

 DPL為描述符所描述段的特權級,隻有有效特權級EPL大于等于DPL時,才能對段進行通路。

 DT位必有為1以差別于系統段描述符。

 TYPE字段:

 位0表示被描述的段是否被通路過,該位為0表示未被通路過,為1則表示該段先前已經被通路過。

 位1的定義在于描述符所描述段的類型。當所描述的是代碼段時,該位訓示所描述的代碼段是否可讀,為1則可讀,為0則不可讀;當所描述的是資料段時,該位訓示所描述的資料段是否可寫,為1則可寫,為0則不可寫。

 位2的定義也在于描述符所描述段的類型。當所描述的是代碼段時,該位訓示所描述的代碼段是否是一至代碼段,為1表示該代碼段是一至代碼段,為0表示該代碼段不是一至代碼段,即是普通的代碼段。當所描述的是資料段時,該位訓示該段的擴充方向,為1時表示該段向低位址擴充,為0時表示該段向高位址擴充。

 位3訓示所描述的段類型,為1表示所描述的段是代碼段,是可以被執行的,為0表示所描述的段是資料段,是不能被執行的。前面已經說了,在保護模式下應該把堆棧段了解為特殊的資料段,為0時也包括堆棧段。

 G位表示段界限的計數機關,該位為0時表示段界限以位元組為機關,為1時表示以4K為機關。這樣計算下來,20位的段界限就可以描述大小為64K或4G的段了,

 D位說明描述符所描述的段是32位環境還是16位的環境。該決定了指令所使用的操作數以及位址的預設大小,為1時說明是32位位址和32位操作數,即32位段;為0時說明是16位位址和16位操作數,即是16位段。但這時仍可使用操作數及位址大小字首來改變這種預設設定。該位還決定了系統是使用IP還是EIP,使用SP還是ESP

 二、系統段描述符

 系統段描述符是描述兩個特殊的段,它們分别為局部描述符表LDT段和任務狀态段TSS。

 從圖2中可見,系統段描述符與存儲段描述符的差別隻在于DT位,DT=1則為存儲段描述符,DT=0則為系統段描述符,兩種描述符就靠此位區分.但系統段描述符的TYPE字段與存儲段描述符的TYPE卻截然不同.描述如下:

 TYPE字段:

 0、1兩位的定義取決于位2。當位2為1時,說明是門描述符,為0時說明是非門描述符。當位2為1時,0、1兩位确定門描述符的類型,因為兩位可有4種狀态,是以正好描述4個描述符,為0時則是調用門,為1時則是任務門,為2時則是中斷門,為3時則是陷阱門;當位2為0時,低兩位0位、1位為0時未定義,為1時則是可用的286的TSS,為2時則是LDT,為3時則是忙的286的TSS。

 位4為0時,如其它位也為0或低兩位為2或3時則也是未定義,否則該位提示是386還是286描述符,關于段基位址和段界限為何都安排在兩個分開的域中的原因也與此有關,請讀者自己想想!

 三、門描述符

 從系統段描述符的說明中可以看出門描述符是靠TYPE字段與系統段描述符區分的,但從圖2中可見門描述符卻與系統段描述符在結構上也不一至,其實這才是區分二者關鍵。門描述符的第四位元組的低4位為雙字計數字段,該字段是說是在發生特權級變換時,把外層堆棧中的參數拷貝到内層堆棧中的數量,計數以雙字為機關。