全域性描述符表gdt是為了實現32位模式的分段,跟16位模式的分段是乙個概念。只是實現方式不一樣。
在32位中,描述乙個段需要以下資訊:
我們用64位(8位元組)來標識乙個段的基位址,及其屬性。可是cpu並沒有乙個這樣的64位段暫存器,我們能是用的依然只有16位的段暫存器。而且由於cpu設計缺陷,段暫存器的低3位還不能用。
所以我們就需要做乙個13位到64位的對映。段暫存器的13位最多能標識 8192 個段,那麼就把 這8192個 8位元組整齊的排列在記憶體裡。並將起始位址儲存在gdtr暫存器中。
如果想訪問第1000個段,其段位址 = (gdtr + 1000 * 8) 中的 段起始位址的值
//設定全域性描述符表
void set_segmdesc(struct segment_descriptor *sd, unsigned int limit, int
base, int ar)
sd->limit_low = limit & 0xffff; // limit 低16位
sd->base_low = base& 0xffff; // base 低16位
sd->base_mid = (base >> 16) & 0xff; // base 中8位
sd->access_right = ar & 0xff; // 屬性低8位
sd->limit_high = ((limit >> 16) & 0xf) | ((ar >> 8) & 0xf0); // limit高4位 | 屬性高8位
sd-base_high = (base >> 24) & 0xff; // base 高8位
}
void load_gdtr(int limit, int addr) 函式無法用c語言實現,只能求助彙編了
_load_gdtr: ; void load_gdtr(int limit, int addr);
mov ax,[esp+4] ; limit
mov [esp+6],ax
lgdt [esp+6]
ret
中斷描述符 和 全域性描述符 的實現方式相似
//設定全域性描述符表
void set_segmdesc(struct segment_descriptor *sd, unsigned int limit, int
base, int ar)
sd->limit_low = limit & 0xffff; // limit 低16位
sd->base_low = base& 0xffff; // base 低16位
sd->base_mid = (base >> 16) & 0xff; // base 中8位
sd->access_right = ar & 0xff; // 屬性低8位
sd->limit_high = ((limit >> 16) & 0xf) | ((ar >> 8) & 0xf0); // limit高4位 | 屬性高8位
sd->base_high = (base >> 24) & 0xff; // base 高8位
return;
}
_load_idtr: ; void load_idtr(int limit, int addr);
mov ax,[esp+4] ; limit
mov [esp+6],ax
lidt [esp+6]
ret
全域性描述符表
局描述符表 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下,我們對乙個...
全域性描述符表
全域性描述符表 gdt global descriptor table 在protected mode下,乙個重要的必不可少的資料結構就是gdt global descriptor table 為什麼要有gdt?我們首先考慮一下在real mode下的程式設計模型 在real mode下,我們對乙個...