IA-32 Intel手册学习笔记(一)系统架构概述
IA-32系統級架構是由寄存器、數據結構、指令組成。用來支持系統級別的操作,比如內存管理,終端和異常處理,任務管理和多處理器控制等。可以看出架構的這些部分和操作系統聯系非常緊密,自然而然為操作系統提供了廣泛的支持。
下圖提供了對IA-32中32位系統寄存器和數據結構的整體概述
全局和局部描述符表(Global and Local Descriptor Tables)
傳統的實地址模式下的匯編中,利用CS:IP來訪問內存,CS左移四位加IP獲得物理地址,但是通常不需要關心基地址,只需要偏移地址即可訪問內存,因為實地址模式的基地址通常是固定的。但是在保護模式下,為了達到保護內存的目的,就需要讓不同程序有不同的基地址(基地址如果固定,那么很容易就被他人直到程序的運行位置,很不安全)。
所以,在保護模式下,內存是一段一段分配的,分配的那一段內存頭地址就是基地址,也稱段地址。同時,操作系統也需要記錄分配出去的每一段內存,實際上,每段內存都使用一個8字節的段描述符記錄著,所有的這些段描述符被放在一塊連續內存空間中存儲著,稱為描述符表。
當系統在保護模式下運行時,所有的內存操作都需要通過全局描述符表(GDT)或局部描述符表(LDT)來完成。這兩個描述符表有好多好多段描述符(segment descriptors),段描述符提供了若干信息,包括
- 段的基地址
- 訪問權限
- 類型
- 用法
每個段描述符都有和它相關聯的段選擇符(segment selector),段選擇符提供了如下信息
- 索引,提供段描述符在全局/局部描述符表中的偏移量(下標)
- 全局/局部的標識符,用來標識這個選擇符是指向GDT還是LDT
- 訪問權限信息
總結,全局/局部描述符表相當于一個數組,數組元素是段描述符,而每個段描述符對應一個段選擇符,這個段選擇符就相當于是數組下標,記錄段描述符在全局/局部描述符表中的位置。另外,段選擇符不在描述符表里。
如上所述,段選擇符提供了段描述符的位置,也就是說,如果此刻手里有段選擇符,那么就可以知道與它關聯的那個段描述符在GDT/LDT中的位置。根據開頭的描述,知道段描述符就等于知道內存段的基地址,但是光有基地址是不夠的,訪問內存還需要偏移地址,這就回到了最開始的部分,保護模式下訪問內存,需要基地址和偏移地址兩個地址。
其實,保護模式下的CS仍然是16位的,IP變為EIP,是32位寄存器。此時CS就是段選擇符,而EIP相當于偏移量,通過CS在描述符表中找到段描述符從而找到基地址,加上EIP表示的偏移量,成功尋址。
如果當前運行的處理器特權級(CPL-Current Privilege Level)有訪問段的權限的話,就可以通過這種機制來訪問在GDT(全局描述符表)或LDT(局部描述符表)中的各種合法代碼,數據和堆棧。
注:CPL被定義為當前執行代碼段的保護級
段選擇符提供了段描述符,段描述符提供了基地址,再加上偏移量,就可以找到某個段內存中的某個字節(byte)
此外,段描述符也可以表示LDT段(局部描述符表也是一個段),訪問LDT需要使用段選擇符,找到GDT中的段描述符,從而找到LDT。同時,為了減少訪問LDT時進行的段轉換次數,LDT的段選擇符,段基地址,段限長都會放在LDTR寄存器中。
- 全局描述符表只是一個數據結構,用來存儲描述符,不是段,所以它本身沒有段選擇符和段描述符。
- 局部描述符表是一個段,有段選擇符和段描述符,段描述符存在全局描述符表中。
- 全局描述符表的線性基地址存放在寄存器GDTR中
只要是段,都需要用一個段描述符表示,而每個段描述符也必定會有一個與之關聯的段選擇符
系統段,系統描述符和門(System Segments, Segment Descriptors, and Gates)
除了代碼,數據和堆棧段是構成程序運行的環境外,系統架構還定義了兩個系統段(System Segments):任務狀態段(TSS)和局部描述符表段(LDT)。和上面一樣,每個段都有一個段描述符和段選擇符,TSS和LDT也有,但是,全局描述符表(GDT)沒有段描述符和段選擇符,導致它不是系統段的成員。另外,任務狀態段(TSS)也在GDT中
此外,除了段描述符,系統架構也提供了一些門描述符,包括
- 調用門(call gates)
- 中斷門(interrupt gates)
- 陷阱們(trap gates)
- 任務門(task gates)
門描述符主要由以下幾部分組成
- 選擇子
- 偏移地址
- DPL
調用門用于在不同特權級之間實現受控的程序控制轉移,通常僅用于使用特權級保護機制的操作系統中。本質上調用門只是一個描述符,一個不同于代碼段和數據段的描述符,可以放在GDT或者LDT中,但是不能放在IDT(中斷描述符表)中。選擇子和偏移地址指定了一個線性地址,程序正是通過這個地址進行轉移的。
如圖,程序通常使用call,jmp指令訪問調用門,這些指令中的選擇符可以用來指定調用門,在調用門中使用段基址和偏移值計算代碼程序的入口地址。而指令中提供的偏移值沒有任何用處。
任務狀態段和任務門(Task-State Segment and Task Gates)
任務狀態段(TSS)定義了任務執行環境的狀態。這些狀態包括通用寄存器、段寄存器、EFLAGS寄存器、EIP寄存器、段選擇符以及三個堆棧段(特權級別0,1,2各一個堆棧)的指針狀態。它也包括了與任務相應的LDT的選擇符和頁表基地址。
任務門用于指示任務,任務門的選擇子必須指示GDT中的任務狀態段(TSS)描述符,門中的偏移地址無意義。任務的入口點保存在TSS中。利用段間轉移指令JMP和段間調用指令CALL訪問任務門可以實現任務切換。
在任務切換時,處理器按照下面的次序進行:
中斷和異常處理(Interrupt and Exception Handing)
外部中斷、軟件中斷和異常是通過中斷描述符表(IDT)處理的。IDT包含了訪問中斷和異常處理程序的門描述符表的集合。向GDT一樣,IDT也不是一個段,IDT的線性基地址包含在IDT寄存器(IDTR)中,整個中斷的尋址過程如下:
內存管理(Memory Management)
系統架構既支持物理地址內存,也支持虛擬內存(通過分頁實現)。當使用物理內存時,線性地址就是物理地址。當使用虛擬內存時,所有的代碼,堆棧,系統段,GDT,IDT都可以通過分頁保存在內存中。
處理器提供了4個內存管理寄存器(GDTR、LDTR、IDTR和TR),這些寄存器指明了那些控制分段內存的數據結構的位置。
全局描述符表寄存器(GDTR)
- 保存全局描述符表(GDT)的32位基地址和16位的界限,基地址是GDT的線性地址,界限是GDT表中的字節數。
- 可以通過指令LGDT和SGDT來裝載和保存GDTR寄存器的值。
- 當處理器上電或復位的瞬間,GDTR的基地址被缺省賦值為0,表界限設置為FFFFH(因為上電和復位時還處于實地址模式)。
- 在初始化的過程中,如果是保護模式的操作,那么會為GRTR的基地址賦上新值
局部描述符表寄存器(LDTR)
- 保存了16位段選擇符,32位基地址,16位段限界和LDT描述符屬性。基地址就是LDT的線性地址,段界限是指段中的字節個數。
- 段選擇符用來在GDT中定位局部描述符表
- 可以通過指令LLDT和SLDT來裝載和保存LDTR寄存器的值。
- 當LLDT指令裝載一個LDTR中的段選擇符時,LDT描述符的基地址,界限和描述符屬性就自動裝載到LDTR中。
- 當進行任務切換時,LDTR就會自動被裝載上新任務的段選擇符和描述符。
- LDTR中的段選擇符中保存LDT段描述符在GTR中的位置,通過LDTR的段選擇符可以找到LDT段描述符
- 通過LDT段描述符就可以找到LDT段
中斷描述符表寄存器(IDTR)
- 保存中斷描述符表(IDT)的32位基地址和16位表界限。基地址是IDT的線性地址,表界限是表中的字節個數
- 可以通過指令LIDT和SIDT來裝載和保存IDTR寄存器的值
任務寄存器(TR)
- 保存著16位的段描述符,32位基地址,16位段界限和當前任務的TSS描述符屬性。
- 可以通過指令LTR和STR來裝載和保存任務寄存器段選擇符部分
控制寄存器(Control Registers)
控制寄存器(CR0,CR1,CR2,CR3和CR4)決定了處理器的運行模式和當前正在執行任務的特征,具體如下:
- CR0:包含系統控制標志,這些標志控制著處理器的運行模式和狀態
- CR1:保留
- CR2:包含缺頁的線性地址(引起缺頁的線性地址)
- CR3:包含了頁目錄的基地址和兩個標志(PCD和PWT)
系統寄存器(System Registers)
為了有助于初始化處理器及控制系統的運行,架構在EFLAGES寄存器內提供了系統標志和幾個系統寄存器:
- EFLAGES寄存器內的系統標志和IOPL域,控制著任務和模式切換、中斷處理、指令跟蹤和訪問特權。
- 控制寄存器(CR0、CR2、CR4)包含了若干標志和數據域用 于控制系統級的操作。這些寄存器內的其他標志指明了操作系統對處理器的兼容。
- 調試寄存器允許在調試軟件和系統軟件內設置斷點。
- GDTR、LDTR和IDTR寄存器內包含了各個表的線性地址和界限。
- 任務寄存器包含了當前任務的TSS的線性地址和界限。
- 模式相關的寄存器,主要被操作系統使用的寄存器(代碼運行在特權級別為0下),這些寄存器控制著如何調試擴展、性能監測計數器、機器檢測架構和內存類型范圍這些寄存器的個數和功能。
總結
以上是生活随笔為你收集整理的IA-32 Intel手册学习笔记(一)系统架构概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----找到序
- 下一篇: 每天一道LeetCode-----给定大