第5天 結構體、文字顯示與GDT/IDT初始化

1、分段

GDT,IDT都是與CPU有關的設定。爲了讓操作系統能夠使用32位模式,需要對CPU做各種設定。

在彙編語言中,有一個指令叫做org。它指定了程序要裝載的地址,而當CPU讀到這段地址時,程序便會運行。現在的操作系統能同時運行多個程序,但如果出現內存的使用範圍重疊了怎麼辦?必須讓某個程序放棄執行,同時報出一個“內存衝突”的錯誤。但實際上是有某種方法能解決這個問題的。這個方法就是分段。

所謂分段,打個比方說,就是按照自己喜歡的方式,將合計4GB的內存分成很多塊,每一塊的起始地址都看作0來處理。有了這個功能,任何程序都可以先寫上org 0。這樣的塊就稱爲段。當然,還有一種分頁的方法。

分段的時候,使用的還是16位中的段寄存器ds。在16位模式時,地址是通過ds * 16 + offset來計算的。那麼在32位模式下,已經不是這樣來計算了,而是offset加上ds所表示的段地的起始地址來表示。按這種分段方法,爲了表示一個段,我們需要有以下信息:

(1)段的大小

(2)段的起始地址

(3)段的管理屬性(禁止寫入,禁止執行,系統專用等)

CPU用8個字節的數據來表示這些信息。但是,我們知道,ds只是16位的,根本放不入這些信息。怎麼辦呢?我們可以先有一個段號,存放在段寄存器裏,然後預告設定好段號與段的對應關係。段號我們就用0 ~ 8191這些數,ds是16位,能夠處理的數範圍是0 ~ 65535,但由於CPU設計上的原因,段寄存器的低3位不能使用,因此,能夠使用的只有13位,所以,剛好能處理0 ~ 8191這些數。

因爲能處理8192個段,設定這多麼段就需要8192 * 8 = 64kb的空間。CPU無法存儲這麼大的數據,那麼就需要將它們放入內存。這64KB的數據就稱爲GDT。

2、GDT

GDT,即global segment descriptor table,翻譯成全局段號記錄表。將這些數據整齊地排列在內存的某個地方,然後將內存的起始地址和有效設定個數放在CPU內被稱作GDTR的特殊寄存器中,設定就完成了。在GDTR寄存器中,低16位是段上限,即GDT的有效字節數 - 1,高32位代表GDT的開始地址。

說到底,分段與CPU的內部機制有關。

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