X86保護模式下的記憶體定址

2021-05-22 17:51:01 字數 1393 閱讀 1219

段選擇器:32位彙編中16位段暫存器(cs、ds、es、ss、fs、gs)中不再存放段基址,而是段描述符在段描述符表中的索引值,d3-d15位是索引值,d0-d1位是優先順序(rpl)用於特權檢查,d2位是描述符表引用指示位ti,ti=0指示從全域性描述表gdt中讀取描述符,ti=1指示從區域性描述符中ldt中讀取描述符。這些資訊總稱段選擇器(段選擇子).

段描述符:8個位元組64位,每乙個段都有乙個對應的描述符。根據描述符描述符所描述的物件不同,描述符可分為三類:儲存段描述符,系統段描述符,門描述符(控制描述符)。在描述符中定義了段的基址,限長和訪問內型等屬性。其中基址給出該段的基礎位址,用於形成線性位址;限長說明該段的長度,用於儲存空間保護;段屬性說明該段的訪問許可權、該段當前在記憶體中的存在性,以及該段所在的特權級。

段描述符表:ia-32處理器把所有段描述符按順序組織成線性表放在記憶體中,稱為段描述符表。分為三類:全域性描述符表gdt,區域性描述符表ldt和中斷描述符表idt。gdt和idt在整個系統中只有一張,而每個任務都有自己私有的一張區域性描述符表ldt,用於記錄本任務中涉及的各個**段、資料段和堆疊段以及本任務的使用的門描述符。gdt包含系統使用的**段、資料段、堆疊段和特殊資料段描述符,以及所有任務區域性描述符表ldt的描述符。

gdtr全域性描述符暫存器:48位,高32位存放gdt基址,低16為存放gdt限長。

ldtr區域性描述符暫存器:16位,高13為存放ldt在get中的索引值。

ia-32處理器仍然使用***x:yyyyyyyy(段選擇器:偏移量)邏輯方式表示乙個線性位址,那麼是怎麼得到段的基址呢?在上面說明中我們知道,要得到段的基址首先通過段選擇器***x中ti位指定的段描述符所在位置:

ti=0時表示段描述符在gdt中,如下圖所示:① 先從gdtr暫存器中獲得gdt基址。② 然後再gdt中以段選擇器高13位位置索引值得到段描述符。③ 段描述符符包含段的基址、限長、優先順序等各種屬性,這就得到了段的起始位址(基址),再以基址加上偏移位址yyyyyyyy才得到最後的線性位址。

ti=1時表示段描述符在ldt中,如下圖所示:① 還是先從gdtr暫存器中獲得gdt基址。② 從ldtr暫存器中獲取ldt所在段的位置索引(ldtr高13位)。③ 以這個位置索引在gdt中得到ldt段描述符從而得到ldt段基址。④ 用段選擇器高13位位置索引值從ldt段中得到段描述符。⑤ 段描述符符包含段的基址、限長、優先順序等各種屬性,這就得到了段的起始位址(基址),再以基址加上偏移位址yyyyyyyy才得到最後的線性位址。

x86保護模式筆記

以下為自己的總結的x86保護模式知識 x86虛擬位址空間64tb,通過分段 分頁對映到物理記憶體。而linux 實際上只是有限的使用了分段機制 比如使用了段的特權級保護 並沒有利用分段機制實現虛擬化,所以linux下每個程序的虛擬空間,或者說程式設計空間只有4gb,而不是64tb。假設現在我們要利用...

x86記憶體定址

最近又研究了一下記憶體定址,沒有乙份資料能講的透徹,不是不細緻,而是缺乏整體感,都不全面,讓人看完後沒有乙個整體模型,現就我關心的問題記錄如下,如果要很全面很細緻的記錄的話會花費我很多精力,所以只是記錄大概流程,以後再慢慢修正吧。所有貼圖皆來自網路 一 分段的由來 1.8086 分段的產生主要是因為...

X86保護模式程式設計總結(1)

系統設計的步驟 1,初始化相關硬體.並裝入系統.2,取得並測試相應硬體的引數.並初始化如x387等硬體.3,載入gdt到gdtr 第乙個描述符必須為0,至少需要乙個 段和乙個資料段 4,載入idt到idtr 必須先關中斷,載入完後可開啟 5,設定cr0中pe 1 也可和pg位一起設,並用jmp大跳 ...