您的位置:首页 > 其它

保护模式下三个重要的系统表——GDT、LDT和IDT

2011-11-24 10:40 218 查看
[align=center][/align]
[align=center][/align]

这三个表是在内存中由操作系统或系统程序员所建,并不是固化在哪里,所以从理论上是可以被读写的。

这三个表都是描述符表。描述符表是由若干个描述符组成,每个描述符占用8个字节的内存空间,每个描述符表内最多可以有8129个描述符。描述符是描述一个段的大小,地址及各种状态的。

描述符表有三种,分别为全局描述符表GDT、局部描述符表LDT和中断描述符表IDT。

1. 全局描述符表GDT:

全局描述符表在系统中只能有一个,且可以被每一个任务所共享.

任何描述符都可以放在GDT中,但中断门和陷阱门放在GDT中是不会起作用的.

能被多个任务共享的内存区就是通过GDT完成的,

2. 局部描述符表LDT:

局部描述符表在系统中可以有多个,通常情况下是与任务的数量保持对等,但任务可以没有局部描述符表.

任务间不相干的部分也是通过LDT实现的.这里涉及到地址映射的问题.

和GDT一样,中断门和陷阱门放在LDT中是不会起作用的.

3. 中断描述符表IDT:

和GDT一样,中断描述符表在系统最多只能有一个,中断描述符表内可以存放256个描述符,分别对应256个中断.

因为每个描述符占用8个字节,所以IDT的长度可达2K.

中断描述符表中可以有任务门、中断门、陷阱门三个门描述符,其它的描述符在中断描述符表中无意义。

4. 段选择子

在保护模式下,段寄存器的内容已不是段值,而称其为选择子.

该选择子指示描述符在上面这三个表中的位置,所以说选择子即是索引值。

当我们把段选择子装入寄存器时不仅使该寄存器值,同时CPU将该选择子所对应的GDT或LDT中的描述符装入了不可见部分。

这样只要我们不进行代码切换(不重新装入新的选择子)CPU就会不会对不可见部分存储的描述符进行更新,可以直接进行访问,加快了访问速度。

一旦寄存器被重新赋值,不可见部分也将被重新赋值。

关于选择子的值是否连续

关于选择子的值,我认为不一定要连续。

但是每个描述符的起始地址相对于第一个描述符(即空描述符)的首地址的偏移必须是8的倍数,即二进制最后三位为0。这样通过全局描述符表寄存器GDTR找到全局描述符表的首地址后,使用段选择子的高13位索引到正确的描述符表项(段选择子的高13位左移3位加上GDTR的值即为段选择子指定的段描述符的逻辑首地址)

也就是说在两个段选择符之间可以填充能被8整除个字节值。当然,如果有选择子指向了这些填充的字节,一般会出错,除非你有意填充一些恰当的数值,呵呵。

关于为什么LDT要放在GDT中

LDT中的描述符和GDT中的描述符

除了选择子的bit3一个为0一个为1用于区分该描述符是在GDT中还是在LDT中外,

描述符本身的结构完全一样。

开始我考虑既然是这样,为什么要将LDT放在GDT中而不是像GDT那样找一个GDTR寄存器呢?

后来终于明白了原因——很简单,

GDT表只有一个,是固定的;而LDT表每个任务就可以有一个,因此有多个,并且由于任务的个数在不断变化其数量也在不断变化。

如果只有一个LDTR寄存器显然不能满足多个LDT的要求。因此INTEL的做法是把它放在放在GDT中

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: