全域性描述符表

2021-09-27 13:47:07 字數 2502 閱讀 4174

全域性描述符表 gdt(global descriptor table)在protected mode下,乙個重要的必不可少的資料結構就是gdt(global descriptor table)。

為什麼要有gdt?我們首先考慮一下在real mode下的程式設計模型:

在real mode下,我們對乙個記憶體位址的訪問是通過segment:offset的方式來進行的,其中segment是乙個段的base address,乙個segment的最大長度是64 kb,這是16-bit系統所能表示的最大長度。而offset則是相對於此segment base address的偏移量。base address+offset就是乙個記憶體絕對位址。由此,我們可以看出,乙個段具備兩個因素:base address和limit(段的最大長度),而對乙個記憶體位址的訪問,則是需要指出:使用哪個段?以及相對於這個段base address的offset,這個offset應該小於此段的limit。當然對於16-bit系統,limit不要指定,預設為最大長度64kb,而 16-bit的offset也永遠不可能大於此limit。我們在實際程式設計的時候,使用16-bit段暫存器cs(code segment),ds(data segment),ss(stack segment)來指定segment,cpu將段積存器中的數值向左偏移4-bit,放到20-bit的位址線上就成為20-bit的base address。

到了protected mode,記憶體的管理模式分為兩種,段模式和頁模式,其中頁模式也是基於段模式的。也就是說,protected mode的記憶體管理模式事實上是:純段模式和段頁式。進一步說,段模式是必不可少的,而頁模式則是可選的——如果使用頁模式,則是段頁式;否則這是純段模 式。

既然是這樣,我們就先不去考慮頁模式。對於段模式來講,訪問乙個記憶體位址仍然使用segment:offset的方式,這是很自然的。由於 protected mode執行在32-bit系統上,那麼segment的兩個因素:base address和limit也都是32位的。ia-32允許將乙個段的base address設為32-bit所能表示的任何值(limit則可以被設為32-bit所能表示的,以2^12為倍數的任何指),而不象real mode下,乙個段的base address只能是16的倍數(因為其低4-bit是通過左移運算得來的,只能為0,從而達到使用16-bit段暫存器表示20-bit base address的目的),而乙個段的limit只能為固定值64 kb。另外,protected mode,顧名思義,又為段模式提供了保護機制,也就說乙個段的描述符需要規定對自身的訪問許可權(access)。所以,在protected mode下,對乙個段的描述則包括3方面因素:[base address, limit, access],它們加在一起被放在乙個64-bit長的資料結構中,被稱為段描述符。這種情況下,如果我們直接通過乙個64-bit段描述符來引用乙個 段的時候,就必須使用乙個64-bit長的段積存器裝入這個段描述符。但intel為了保持向後相容,將段積存器仍然規定為16-bit(儘管每個段積存 器事實上有乙個64-bit長的不可見部分,但對於程式設計師來說,段積存器就是16-bit的),那麼很明顯,我們無法通過16-bit長度的段積存器來直 接引用64-bit的段描述符。

怎麼辦?解決的方法就是把這些長度為64-bit的段描述符放入乙個陣列中,而將段暫存器中的值作為下標索引來間接引用(事實上,是將段暫存器 中的高13 -bit的內容作為索引)。這個全域性的陣列就是gdt。事實上,在gdt中存放的不僅僅是段描述符,還有其它描述符,它們都是64-bit長,我們隨後再 討論。

gdt可以被放在記憶體的任何位置,那麼當程式設計師通過段暫存器來引用乙個段描述符時,cpu必須知道gdt的入口,也就是基位址放在**,所以 intel的設計者門提供了乙個暫存器gdtr用來存放gdt的入口位址,程式設計師將gdt設定在記憶體中某個位置之後,可以通過lgdt指令將gdt的入口 位址裝入此積存器,從此以後,cpu就根據此積存器中的內容作為gdt的入口來訪問gdt了。

gdt是protected mode所必須的資料結構,也是唯一的——不應該,也不可能有多個。另外,正象它的名字(global descriptor table)所揭示的,它是全域性可見的,對任何乙個任務而言都是這樣。

除了gdt之外,ia-32還允許程式設計師構建與gdt類似的資料結構,它們被稱作ldt(local descriptor table),但與gdt不同的是,ldt在系統中可以存在多個,並且從ldt的名字可以得知,ldt不是全域性可見的,它們只對引用它們的任務可見,每個 任務最多可以擁有乙個ldt。另外,每乙個ldt自身作為乙個段存在,它們的段描述符被放在gdt中。

ia-32為ldt的入口位址也提供了乙個暫存器ldtr,因為在任何時刻只能有乙個任務在執行,所以ldt暫存器全域性也只需要有乙個。如果一 個任務擁有自身的ldt,那麼當它需要引用自身的ldt時,它需要通過lldt將其ldt的段描述符裝入此暫存器。lldt指令與lgdt指令不同的 時,lgdt指令的運算元是乙個32-bit的記憶體位址,這個記憶體位址處存放的是乙個32-bit gdt的入口位址,以及16-bit的gdt limit。而lldt指令的運算元是乙個16-bit的選擇子,這個選擇子主要內容是:被裝入的ldt的段描述符在gdt中的索引值——這一點和剛才所 討論的通過段積存器引用段的模式是一樣的

全域性描述符表

局描述符表 gdt global descriptor table 在protected mode下,乙個重要的必不可少的資料結構就是gdt global descriptor table 中文名全域性描述符表 外文名global descriptor table 類 型 資料結構 領 域 科學技術...

全域性描述符表

全域性描述符表 gdt global descriptor table 在protected mode下,乙個重要的必不可少的資料結構就是gdt global descriptor table 為什麼要有gdt?我們首先考慮一下在real mode下的程式設計模型 在real mode下,我們對乙個...

全域性描述符表

處理器將記憶體劃分成邏輯上的段,並在指令中使用段內位址偏移,在保護模式下,對記憶體的訪問,仍然使用段位址和偏移位址,但是每個段在訪問之前,必須先登記。登記的資訊包括段的起始位址,段的界限和段的各種訪問屬性等。這樣每次你的程式和你要訪問的段不符時,就要被阻止,並產生乙個叫做內部異常的中斷。和乙個段有關...