段描述符表
段描述符表简称描述符表,用来存储保护方式下段描述符的一个阵列。80386/80486 CPU 共有3 种描述符表:全局描述符表GDT、局部描述符表LDT 和中断描述符表IDT。描述符表由描述符顺序排列组成,占一定的内存,由系统地址寄存器(GDTR 、LDTR、IDTR) 指示其在物理存储器中的位置和大小。
全局描述符表GDT 是供所有任务使用的描述符表,在物理存储器地址空间中定义全局描述符表GDT。通常操作系统使用的有代码段描述符、数据段描述符、调用门描述符、各个任务的LDT 描述符、任务状态段TSS 描述符、任务门描述符等。
局部描述符表LDT 是每一项任务运行时都要使用的描述符表。在多任务操作系统管理下,每个任务通常包含两部分:与其他任务共用的部分及本任务独有的部分。与其他任务共用部分的段描述符存储在全局描述符表GDT内;本任务独有部分的段描述符存储在本任务的局部描述符表LDT 内。这样,每个任务都有一个局部描述符表LDT,而每个LDT 表又是一个段,它也就必须有一个对应的LDT 描述符。该LDT 描述符存储在全局描述符表中。局部描述符表LDT 中所存储的属于本任务的段描述符通常有代码段描述符、数据段描述符、调用门描述符及任务门描述符等。
GDT 和LDT 段描述符表实际上是段描述符的一个长度不定的数据阵列,如图8.5 所示。描述符表在长度上是可变的,最多容纳213 个描述符,最少包含一个描述符。每个项有8 个字节长,称为一个段描述符。中断描述符表IDT暂不介绍。
段寄存器(中的TI)、GDT、LDT、GDTR、LDTR关系:
1.4 段选择符
段描述符表(GDT、LDT)是通过选择符来索引的,IDT不用通过选择符,直接用中断号索引。
保护模式下段寄存器存放的都是段选择符。
选择符一共16位,格式如下:
Index一共13位,正好可以索引到GDT或者LDT的最大限长。由于描述符表都是8直接对齐的,所以吧index放在高13位,这样把低3位屏蔽后就可以得到表内 偏移地址。
TI(Table Indicator)位是引用描述符表指示位,TI=0指示从全局描述符表GDT中读取描述符;TI=1指示从局部描述符表LDT中读取描述符。
选择子的最低两位是请求特权级RPL(Requested Privilege Level),用于特权检查。CS和SS寄存器中的RPL就是CPL(current privilege level当前特权级)Linux下使用0、3两个别人是内核态、用户态
1.5 段寄存器
80386的段寄存器都包含有一个16位可见部分和一个不可见部分。段寄存器的可见部分由程序来操作,就好像是简单的16位寄存器,存放16位的段选择符。不可见部分由CPU维护,作为高速缓冲。每当段选择符被加载到段寄存器中时,CPU取得段描述符表中相应的描述符,然后把段的属性放入不可见部分中。比如段基地址,限长,以及其他属性。这样避免每次访问内存。
段选择符中TI位为1时的情况,这时从LDT中读取段描述符。需要先从GDT中读取LDT段描述符,然后再从LDT中读取段基地址。(所以系统要先预设GDTR和LDTR的地址)
2.多任务
上面介绍了存储段和LDT段,这里介绍另外一个系统段任务状态段TSS。 为了提供多任务,80386使用了特殊的数据结构,主要有任务状态段TSS(Task State Segmeng)和任务寄存器TR