在protected mode下,乙個重要的必不可少的資料結構就是gdt(global descriptor table)。
為什麼要有gdt
real mode程式設計模型
我們首先考慮一下在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,記憶體的管理模式分為兩種,段模式和頁模式,其中頁模式也是基於段模式的。也就是說,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描述 GDT詳解(全域性描述符表)
gdt詳解 全域性描述符表 字型大小 小 中 大 在protected mode下,乙個重要的必不可少的資料結構就是gdt global descriptor table 為什麼要有gdt?我們首先考慮一下在real mode下的程式設計模型 在real mode下,我們對乙個記憶體位址的訪問是通過...
gdt描述 GDT描述符表
一直以來,在直流電源埠的雷擊保護器件的選型方面,人們會選擇壓敏電阻mov,但是,由於壓敏電阻mov在失效時會引 災,而選擇常規氣體放電管gdt又會帶來續流問題,因此,結合壓敏電阻和氣體放電管兩種器件便成了電源埠的雷擊保護問題的完美解決方案。壓敏電阻器與氣體放電管串聯,在不影響壓敏保護水平的前提下,可...
GDT表與段描述符
windows核心分析索引目錄 gdt表與段描述符 一 介紹 如果之前學習過 實模式 那很明白 段 的意義,在實模式中採用 段 偏移 的機制定址。現在,我們使用 保護模式 記憶體對於我們來說是平坦的。此時,段 對於我們來說,還有什麼意義呢?這時,段 相當於乙個管理者的角色,它有自己的base,但往往...