來源:https://www.cnblogs.com/longintchar/p/5224406.html
在進入保護模式之前,我們先要學習一些基礎知識。今天我們看一下全局描述符表(Global Descriptor Table, 簡稱GDT)。
同實模式一樣,在保護模式下,對內存的訪問仍然使用段地址加偏移地址。但是,在保護模式下,在每個段能夠訪問之前,必須先登記。這就好比像C語言中,“對變量的使用必須先定義”一樣。
每個段在能夠使用之前,都要為這個段建立一個描述符。每個描述符占8個字節,這些描述符集中存放在內存的某個區域,一個挨着一個,就構成了一張“表”。
80x86中有兩種描述符表:
- 全局描述符表(Global Descriptor Table, 簡稱GDT)
- 局部描述符表(Local Descriptor Table,簡稱LDT)
LDT我們以后再說,今天的重點是GDT.
在進入保護模式之前,必須要定義GDT,也就是說,我們要在內存中構建出一張表。
需要說明的是:在整個系統中,全局描述符表GDT只有一張(一個處理器對應一個GDT);GDT可以被放在內存的任何位置,但CPU必須知道GDT的入口。
你也許會問:CPU如何知道GDT的入口呢?別擔心,在處理器內部,有一個48位的寄存器,名叫GDTR,也就是全局描述符表寄存器。其結構如下圖:
該寄存器分為2部分:
- 32位的線性基地址:GDT在內存中的起始線性地址(我們還沒有涉及到分頁,所以這里的線性地址等同於物理地址,下同,以后同);
- 16位的表界限:在數值上等於表的大小(總字節數)減去1;
注意:在處理器剛上電的時候,基地址默認為0,表界限默認為0xFFFF; 在保護模式初始化過程中,必須給GDTR加載一個新值。
因為表界限是16位的,最大值是0xFFFF,也就是十進制的65535,那么表的大小就是65535+1=65536.又因為一個描述符占用8個字節,所以65536字節相當於8192個描述符(65536/8=8192).故理論上最多可以定義8192個描述符。實際上,不一定這么多,具體多少根據需要而定。
理論上,GDT可以放在內存中的任何地方。但是,我們必須在進入保護模式之前就定義GDT(不然就來不及了),所以GDT一般都定義在1MB以下的內存范圍中。當然,允許在進入保護模式后換個位置重新定義GDT。