在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中的索引值——这一点和刚才所讨论的通过段积存器引用段的模式是一样的。
LDT只是一个可选的数据结构,你完全可以不用它。使用它或许可以带来一些方便性,但同时也带来复杂性,如果你想让你的OS内核保持简洁性,以及可移植性,则最好不要使用它。
引用GDT和LDT中的段描述符所描述的段,是通过一个16-bit的数据结构来实现的,这个数据结构叫做Segment Selector——段选择子。它的高13位作为被引用的段描述符在GDT/LDT中的下标索引,bit 2用来指定被引用段描述符被放在GDT中还是到LDT中,bit 0和bit 1是RPL——请求特权等级,被用来做保护目的,我们这里不详细讨论它。
前面所讨论的装入段寄存器中作为GDT/LDT索引的就是Segment Selector,当需要引用一个内存地址时,使用的仍然是Segment:Offset模式,具体操作是:在相应的段寄存器装入Segment Selector,按照这个Segment Selector可以到GDT或LDT中找到相应的Segment Descriptor,这个Segment Descriptor中记录了此段的Base Address,然后加上Offset,就得到了最后的内存地址。
以上摘自互动百科
GDT的结构图如下:
G:G=0时,段限长的20位为实际段限长,最大限长为2^20=1MB
G=1时,则实际段限长为20位段限长乘以2^12=4KB,最大限长达到4GB
D/B:当描述符指向的是可执行代码段时,这一位叫做D位,D=1使用32位地址和32/8位操作数,D=0使用16位地址和16/8位操作数。如果指向的是向下扩展的数据段,这一位叫做B位,B=1时段的上界为4GB,B=0时段的上界为64KB。如果指向的是堆栈段,这一位叫做B位,B=1使用32位操作数,堆栈指针用ESP,B=0时使用16位操作数,堆栈指针用SP。
DPL:特权级,0为最高特权级,3为最低,表示访问该段时CPU所需处于的最低特权级
type : 类型
type<8时
type>=8时
分享到:
相关推荐
Hook全局描述符表、使用GDT来实现进程隐藏
描述符表限长度,后 32 位为全局描述符表基地址,其中限 !长度,为 2048,共 256 GDT 项(每项 8 个字节,所以 !2048/8=256)。全局描述符表寄存器(GDTR)为 0x7XXX !处。 127: 128: msg1: 129: .byte 13,10 130: ....
内存管理寄存器,GDTR,LDTR,IDTR和TR,用于指定内存分段管理所用系统表的基地址GDTR [32位线性基地址,16位表长度] IDTR [32位线性基地址,16位表长度] LDTR [16位段选择符,32位线性基地址,段长度],指令LLDT和...
了解intel处理器中的全局描述符,加深对cpu的理解。
javascriptapi开发文档,可以下载后观看,有效的帮助我们
设置gdt全局描述符表 2.设置a20开始访问1M以上内存的必须步骤 3.设置cr0的pe为1,这个表明已经进入了保护模式中。 ; ;protect.ASM ; ; ; SECTION ALIGN=16 VSTART=0x...
操作系统篇-分段机制与GDT、LDT.docx
有3类描述符表,即全局描述符表、局部描述符表及中断描述符表。 29.80386的分段部件是如何将逻辑地址变为线性地址的? 答:分段部件根据段选择符从全局描述符表或局部描述符表中取出对应的段描述符。把段描述符32位...
Kinux内核是32和64位系统的内核。 它支持许多功能,例如GDT,IDT,ISR,键盘驱动程序等。 您可以阅读以基于此内核创建自己的操作系统。 编译中 要编译内核,请按照下列步骤操作: Linux: 在系统上安装 。 从...
参考资料-EMC器件设计之GDT.zip
GDT2000点型可燃气体探测器安装使用说明书
GDT 位置公差符号字体,拷贝到C:\WINDOWS\Fonts即可
好玩的Phillip's Oppermann的功能完备的x86-64内核:概述...内容该表列出了目录及其用途: 目录描述src / 带有好玩的内核实现的目录src / allocator.rs 堆src / gdt.rs 全局描述符表,用于在内核/用户空间之间切换并加
- Fix MTRR configuration (prevented boot of modern Linux kernels) - Fix interrupt vectors for INT 60h-66h (reserved for user interrupt) by setting them to zero - Fix BIOS INT13 function 08 when ...
GDT 几何公差 奥曼克形位公差培训 http://blog.sina.com.cn/jianhongwei1989
几何公差 GDT GG-GC-GX-GN的正确理解
一个强大的手工杀毒工具,XueTr(简称XT)是一个强大的系统信息查看软件,也是一个强大的手工杀毒软件,用它可以方便揪出电脑中的病毒木马,目前它支持32位的2000、XP、2003、Vista、2008、Win7系统。 XueTr-火眼合作...
gdt自述文件 这是扩展名“ gdt”的自述文件。 写下简短描述后,我们建议包括以下各节。 特征 描述扩展程序的特定功能,包括扩展程序的屏幕截图。 图像路径是相对于此README文件的。 例如,如果扩展项目工作空间下有...