x86總覽

1.x86系統架構總覽

1.1系統級體系結構總覽

全局和局部描述符表

全局描述符表(GDT)是保護模式所必須的數據結構,裏面存放的是段描述符,GDT相當於存放段描述符的數組,而索引則是選擇子,全局則體現在多個程序都可以在GDT中定義自己的段描述符,是公用的,全局可見。GDT在內存中,需要用專門的寄存器GDTR(Global Descriptor Table Register)指引CPU找到GDT。GDTR是48位的寄存器,低16位存放GDT界限,剩餘32位存放GDT起始地址。
局部描述符表(LDT)是爲在硬件一級原生支持多任務而創建的表,按照設想,一個任務對應一個LDT。 每個任務的私有內存段都應該放到自己的段描述符表中,即每個任務都要有自己的LDT,隨着任務的切換,也要切換到相應任務的LDT。LDT需要先在GDT中註冊一個描述符,與GDT不同的是,LDT的第0個段描述符是可用的,因爲選擇子中的TI位爲1才表示在LDT中索引段描述符,TI爲1必然是經過顯式初始化的結果。

選擇子

實模式中,段寄存器存放的是段基地址,而在保護模式下段基址已經存放在段描述符中了。因此,段寄存器的作用就改爲了存儲全局描述符表的索引——選擇子。
其中選擇子的第2位是TI(Table Indicator)位,用來表示選擇子是在GDT中,還是LDT中,該位爲1表示在GDT中,爲0表示在LDT中

段描述符

IA-32架構的處理器訪問內存都是採用“段基址:段內偏移地址”的形式,即使到了保護模式也不例外。其次,實模式脆弱的安全性也是保護模式推出的重要原因。爲了內存安全性,必須爲內存段添加一些額外的安全屬性,如特權級、段界限、段類型等。
段描述符如下

字節 7 6 - 5 4 - 2 1 - 0
內容 31…24段基址2 屬性 23…0段基址1 15…0段界限1

其中屬性包括

15 14 13 12 11 - 8 7 6 - 5 4 3-0
內容 G D/B 0 AVL 19…16段界限2 P DPL S TYPE

一個段描述符是8字節大小,它描述了一個內存段的地址範圍和各種屬性。
保護模式下地址總線寬度是32位,因此段基址需要用32位地址來表示。從上圖看出段基址字段一共有2個部分,分別在第2~4字節和第7字節。這樣劃分的目的是爲了兼容舊式的16位CPU(段界限字段也是如此)。

段界限和G字段:段界限表示段邊界的擴展極值,即最大擴展到多少或最小擴展到多少。擴展方向只有上下兩種,對於數據段和代碼段,段的擴展方向是向上,即從低地址向高地址擴展,此時的段界限用來表示段內偏移的最大值(上界);對於棧段,段的擴展方向是向下,即從高地址向低地址擴展,此時的段界限表示段內偏移的最小值(下界)。無論是向上還是向下,段界限都表示段的邊界。段界限字段給出的只是數值,其單位(或稱粒度)則在G位中給出,G位爲0則粒度爲B,爲1則爲4KB。

內存訪問需要用到“段基址:段內偏移地址”,段界限其實是用來限制段內偏移地址的,段內偏移地址必須位於段描述符給出的範圍之內,否則CPU會拋出異常。任何超範圍的偏移地址都被認爲是非法的,CPU會捕獲這個異常。(這也就是日常寫程序中的報的段錯誤)

S字段:屬性字段中的type字段用來指定段描述符的類型,而S位的數值決定了type字段中不同位的含義。一個段描述符首先分爲兩大類,要麼是系統段(S位置0),要麼是非系統段(S位置1),或稱數據段。對於CPU而言,凡是硬件運行需要用到的東西都可稱之爲系統(如硬件在內存中的映射),凡是軟件需要用到的東西(操作系統也是軟件,對CPU而言在這一層面它與用戶程序無區別)都是數據。無視是代碼還是數據,都是作爲硬件的輸入,因此我們常說的代碼段在段描述符中也屬於數據段(非系統段)。type字段要和S字段配合才能確定段描述符的確切類型,只有S字段的值確定後type字段的值纔有意義。

DPL字段爲描述符特權級,這是保護模式提供的安全解決方案,有4個不同等級(0~3,數值越小特權級越大)。

AVL即Available,表示段是否可用

D/B字段:用來表示有效地址(段內偏移地址)及操作數的大小。對於代碼段來說,此位是D位,若D爲0,表示指令中的有效地址和操作數是16位,使用ip寄存器;否則爲32位,使用eip寄存器。對於棧段來說,此位是B位,用來指定操作數大小,若B爲0,使用的是sp寄存器,也就是棧的起始地址是16位寄存器的最大尋址範圍,0xFFFF;若B爲1則使用esp寄存器,即棧的起始地址是32位寄存器的最大尋址範圍,0xFFFFFFFF。

1.2實模式和保護模式

實模式

實模式的“實”體現在程序中用到的地址都是真實的物理地址,“段基址:段內偏移地址”產生的邏輯地址就是物理地址,即程序員可見的地址完全是真實的內存地址。
實模式下由16位段寄存器的內容乘以16(左移4位)作爲段基址,加上16位段偏移地址形成20位的物理地址,最大尋址空間1MB,最大分段64KB。可以使用32位指令,即32位的x86 CPU也可以兼容實模式,此時的實模式相當於高速的8086(32位CPU的實模式可以使用32位下的資源)。在32位CPU下,系統復位或加電時都是以實模式啓動,然後再切換爲保護模式。在實模式下,所有的段都是可以讀、寫和可執行的。
在實模式下,用戶程序和操作系統擁有同等權利,因爲實模式下沒有特權級。此外,程序可以隨意修改自己的段基址,加上實模式下對地址的訪問就是實實在在的物理地址,因此程序可以隨意修改任意物理地址,甚至包括操作系統所在的內存,這給操作系統帶來極大的安全問題。<

保護模式

爲了改進實模式下內存訪問的不安全性,保護模式給內存段添加了段屬性來限制用戶程序對內存的操作權限。保護模式引入了全局描述符表(Global Descriptor Table,GDT),GDT的表項是描述段類型屬性的數據結構——段描述符。GDT中的每一個段描述符都描述了一個內存段的基本屬性,如段基址、段界限、類型、DPL等等。由於以上概念的提出,使得“段地址:段內偏移地址”的訪問策略從實模式下對物理地址的直接映射變成了保護模式下對GDT或LDT的間接映射

實模式向保護模式切換

CPU啓動環境爲16位實模式,之後可以切換到保護模式。但從保護模式無法切換回實模式,但是可以切換會虛擬實模式

實模式>>保護模式>>實模式
切換流程:
1、設置必要的實模式環境,如實模式下的堆棧等。
2、初始化全局描述符表(GDT)、局部描述符表(LDT)及中斷描述符表(IDT)等。
3、保存實模式下的堆棧地址到某內存處,以便切換回實模式後恢復,如有必要也可保存DS、ES、FS、GS等數據段寄存器的值。 (cs是代碼段寄存器,ds是數據段寄存器,ss是堆棧段寄存器,es是擴展段寄存器,fs是標誌段寄存器,gs是全局段寄存器)
4、加載全局描述符表至全局描述符表寄存器(GDTR),如果未定義中斷描述符表,則關中斷,然後打開地址線A20。
5、修改cr0的PE位爲1,切換到保護模式。
6、使用段間跳轉指令轉到保護模式下的段,如果有局部描述符表,則應首先加載局部描述表段至局部描述符表寄存器(LDTR)。
7、設置保護模式下的堆棧段SS及堆棧指令SP(ESP)。
8、設置DS、ES、FS、GS指向某個數據段,防止無意中使用到未設置的數據段。
9、準備切換回實模式,用於切換回實模式的段必須是16位段且其段描述符必須定義在GDT中,其段限制必須是0FFFFH。
10、修改CR0的PE位爲0切換回實模式。
11、恢復堆棧段至切換到保護模式之前的狀態,如有必要也可恢復DS、ES等數據段。
12、關閉地址線A20。如中斷爲關閉狀態,則打開中斷。

1.3系統指令寄存器

EFLAGS(標誌寄存器)

在這裏插入圖片描述
1、狀態標誌(Status Flags)

EFLAGS寄存器的狀態標誌(0、2、4、6、7以及11位)指示算術指令(如ADD, SUB, MUL以及DIV指令)的結果,這些狀態標誌的作用如下

CF(bit 0) [Carry flag] 若算術操作產生的結果在最高有效位(most-significant bit)發生進位或借位則將其置1,反之清零。這個標誌指示無符號整型運算的溢出狀態,這個標誌同樣在多倍精度運算(multiple-precision arithmetic)中使用。
PF(bit 2) [Parity flag] 如果結果的最低有效字節(least-significant byte)包含偶數個1位則該位置1,否則清零。
AF(bit 4) [Adjust flag] 如果算術操作在結果的第3位發生進位或借位則將該標誌置1,否則清零。這個標誌在BCD(binary-code decimal)算術運算中被使用。
ZF(bit 6) [Zero flag] 若結果爲0則將其置1,反之清零。
SF(bit 7) [Sign flag] 該標誌被設置爲有符號整型的最高有效位。(0指示結果爲正,反之則爲負)
OF(bit 11) [Overflow flag] 如果整型結果是較大的正數或較小的負數,並且無法匹配目的操作數時將該位置1,反之清零。這個標誌爲帶符號整型運算指示溢出狀態。

2、DF標誌位

這個方向標誌(位於EFLAGS寄存器的第10位)控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。設置DF標誌使得串指令自動遞減(從高地址向低地址方向處理字符串),清除該標誌則使得串指令自動遞增。STD以及CLD指令分別用於設置以及清除DF標誌。

3、系統標誌

EFLAGS寄存器中的這部分標誌用於控制操作系統或是執行操作,它們不允許被應用程序所修改。這些標誌的作用如下:
TF(bit 8) [Trap flag] 將該位設置爲1以允許單步調試模式,清零則禁用該模式。
IF(bit 9) [Interrupt enable flag] 該標誌用於控制處理器對可屏蔽中斷請求(maskable interrupt requests)的響應。置1以響應可屏蔽中斷,反之則禁止可屏蔽中斷。
IOPL(bits 12 and 13) [I/O privilege level field] 指示當前運行任務的I/O特權級(I/O privilege level),正在運行任務的當前特權級(CPL)必須小於或等於I/O特權級才能允許訪問I/O地址空間。這個域只能在CPL爲0時才能通過POPF以及IRET指令修改。
NT(bit 14) [Nested task flag] 這個標誌控制中斷鏈和被調用任務。若當前任務與前一個執行任務相關則置1,反之則清零。
RF(bit 16) [Resume flag] 控制處理器對調試異常的響應。
VM(bit 17) [Virtual-8086 mode flag] 置1以允許虛擬8086模式,清除則返回保護模式。
AC(bit 18) [Alignment check flag] 該標誌以及在CR0寄存器中的AM位置1時將允許內存引用的對齊檢查,以上兩個標誌中至少有一個被清零則禁用對齊檢查。
VIF(bit 19) [Virtual interrupt flag] 該標誌是IF標誌的虛擬鏡像(Virtual image),與VIP標誌結合起來使用。使用這個標誌以及VIP標誌,並設置CR4控制寄存器中的VME標誌就可以允許虛擬模式擴展(virtual mode extensions)
VIP(bit 20) [Virtual interrupt pending flag] 該位置1以指示一箇中斷正在被掛起,當沒有中斷掛起時該位清零。與VIF標誌結合使用。
ID(bit 21) [Identification flag] 程序能夠設置或清除這個標誌指示了處理器對CPUID指令的支持

內存管理控制寄存器

  • GDTR
    全局描述符表寄存器GDTR,48位寄存器。 用於存放全局描述符表GDT的32位的線性基地址和16位的表限長值。基地址指定GDT表中字節0在線性地址空間中的地址,表長度指明GDT表的字節長度值。指令LGDTSGDT分別用於加載和保存GDTR寄存器的內容。在機器剛加電或處理器復位後,基地址被默認地設置爲0,而長度值被設置成0xFFFF。在保護模式初始化過程中必須給GDTR加載一個新值。

  • LDTR
    局部描述符表寄存器LDTR,16位寄存器。 其內保存的是16位的選擇符。LDTR和GDTR有所不同,定義也有所不同,對於LDT來說,首先要根據16位的選擇符從GDT中選擇一個LDT描述符(換句話說,LDT的描述符放在GDT中),送入描述符高速緩衝寄存器(64位)中,以確定當前局部描述符LDT所在的位置的基地址和界限值。

  • IDTR
    中斷描述符表寄存器IDTR,48位寄存器。 與GDTR的作用類似,IDTR寄存器用於存放中斷描述符表IDT的32位線性基地址和16位表長度值。指令LIDT和SIDT分別用於加載和保存IDTR寄存器的內容。在機器剛加電或處理器復位後,基地址被默認地設置爲0,而長度值被設置成0xFFFF。80486爲每個中斷或異常都定義了一箇中斷描述符

  • TR
    任務寄存器TR,16位寄存器。 其內保存的是任務狀態段TSS的16位段選擇符。每項任務都配有一個任務狀態段TSS,用來描述該任務的運行狀態。就用16位的選擇符來檢索任務狀態段。總是將當前任務的TSS的選擇符放在TR中,而TSS的描述符放在TSS描述符高速緩衝寄存器中

控制寄存器

控制寄存器CR0-CR3
1、CR0

0位是保護允許位PE(Protedted Enable),用於啓動保護模式,如果PE位置1,則保護模式啓動,如果PE=0,則在實模式下運行。

控制寄存器CR0中的位0用PE標記,位31用PG標記,這兩個位控制分段和分頁管理機制的操作

PE=0,處理器運行於實模式;PE=1,處理器運行於保護方式。PG控制分頁管理機制。PG=0,禁用分頁管理機制,此時分段管理機制產生的線性地址直接作爲物理地址使用;PG=1,啓用分頁管理機制,此時線性地址經分頁管理機制轉換位物理地址。由此可知,如果要啓用分頁機制,那麼PE和PG標誌都要置位。

2、CR2

CR2用於發生頁異常時報告出錯信息。當發生頁異常時,處理器把引起頁異常的線性地址保存在CR2中。操作系統中的頁異常處理程序可以檢查CR2的內容,從而查出線性地址空間中的哪一頁引起本次異常。

3、CR3

CR3 用於保存頁目錄表頁面的物理地址,因此被稱爲PDBR。由於目錄是頁對齊的,所以僅高20位有效,低12 位保留供更加高級的處理器使用。向CR3中裝入一個新值時,低12位必須爲0;但從 CR3中取值時,低12位被忽略。每當用MOV指令重置CR3的值時,會導致分頁機制高速緩衝區的內容無效,用此方法,可以在啓用分頁機制之前,即把PG 位置1之前,預先刷新分頁機制的高速緩存。CR3寄存器即使在CR0寄存器的PG位或PE位爲0時也可裝入,如在實模式下也可設置CR3,以便進行分頁機制的初始化。在任務切換時,CR3要被改變,但是如果新任務中CR3的值與原任務中CR3的值相同,那麼處理器不刷新分頁高速緩存,以便當任務共享頁表時有較快的執行速度。

1.4系統指令

系統指令

系統指令: 系統指令用於處理系統級別功能,例如加載系統寄存器,管理中斷等。大多數系統指令只能由處於特權級0的操作系統軟件執行,其餘一些指令可以在任何特權級上執行,因此應用程序也能使用,表4-2 中列出了我們將用到的一些系統指令,其中還指出了它們是否受到保護

操作碼 指令 是否受保護 說明
0F 00 /0 SLDT r/m16 存儲段選擇子LDTR至r/m16
0F 00 /1 STR r/m16 存儲段選擇子TR至r/m16
0F 00 /2 LLDT r/m16 加載段選擇子r/m16至LDTR
0F 00 /3 LTR r/m16 加載r/m16至TR
0F 01 /0 SGDT m 存儲GDTR到m
0F 01 /1 SIDT m 存儲IDTR到m
0F 01 /2 LGDT m16&32 將m加載到GDTR
0F 01 /2 LGDT m16&64 將m加載到GDTR
0F 01 /3 LIDT m16&32 將m加載到IDTR
0F 01 /3 LIDT m16&64 將m加載到IDTR
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章