——操作系统学习笔记
描述符是如何分类的?按描述符所描述的对象来划分,描述符可分为如下三类:存储段描述符、系统段描述符、门描述符(控制描述符):
1. 存储段描述符又称为一般段描述符,是指段寄存器中使用的描述符;
2. 系统段描述符指的就是LDT描述符和TSS描述符,LDT描述符和TSS描述符放在全局描述符GDT中。每个任务都有自己的局部描述符表LDT和任务状态段TSS,LDT和TSS是内存中特殊的段,它们有起始地址、大小和属性,也需要描述符来描述它们,所有就有了LDT描述符和TSS描述符;
3. 们描述符又称控制描述符,程序在运行中经常会发生转移,转移可能在同一段内进行,更多的段间转移,段间转移就需要改变CS和EIP的值,门描述符中就保存着程序之间进行段间转移的目标地址(即新的CS和EIP值)。
图(1)描述符结构
我们先来看看这8个字节中我感觉最复杂的TYPE这四位标志吧,然后在看看其他的位
__________________________________
| | | | |
| 3 | 2 | 1 | 0 |
| E | | | A |
_________________________________
A=0表示尚未被访问,A=1 表示段已被访问。当把描述符的相应选择子装入到段寄存器时,80386把该位置为1,表明描述符已被访问。操作系统可测试访问位,已确定描述符是否被访问过
E=0表示段为数据段,相应的描述符也就是数据段(包括堆栈段)描述符。数据段是不可执行的,但总是可读的。 E=1表示段是可执行段,即代码段,相应的描述符就是代码段描述符。代码段总是不可写的,若需要对代码段进行写入操作,则必须使用别名技术,即用一个可写的数据段描述符来描述该代码段,然后对此数据段进行写入。
___________________________________
| | | | |
| 3 | 2 | 1 | 0 |
| E=0 | ED | W | A |
_________________________________
TYPE中的位1指示所描述的数据段是否可写,用W标记。 W=0表示对应的数据段不可写。反之,W=1表示数据段是可写的。注意,数据段总是可读的。
TYPE中的位2是ED位,指示所描述的数据段的扩展方向。ED=0表示数据段向高端扩展,也即段内偏移必须小于等于段界限。ED=1表示数据段向低扩展,段内偏移必须大于段界限。
___________________________________
| | | | |
| 3 | 2 | 1 | 0 |
| E=1 | C | R | A |
_________________________________
TYPE中的位1指示所描述的代码段是否可读,用符号R标记。R=0表示对应的代码段不可读,只能执行。R=1表示对应的代码段可读可执行。注意代码段总是不可写的,若需要对代码段进行写入操作,则必须使用别名技术。
在代码段中,TYPE中的位2指示所描述的代码段是否是一致代码段,用C标记。C=0表示对应的代码段是非一致代码段(普通代码段),C=1表示对应的代码段是一致代码段。
图(2) 存储段描述符TYPE属性
从图一我们可以看出基地址长32位,被安排在2,3,4,7字节中,段界限长20位,被安排在0,1字节与第6字节的低4位中。
使用两个域存放段基地址和段界限的原因与80286有关。在80286保护方式下,段基地址只有24位长,而段界限只有16位长。80286存储段描述符尽管也是8字节长,但实际只使用低 6字节,高2字节必须置为0。80386存储段描述符这样的安排,可使得80286的存储段描述符的格式在80386下继续有效。
P=1表示描述符对地址转换是有效的,或者说该描述符所描述的段存在,即在内存中;P=0表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常。
它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问
对于存储段描述符而言,DT=1,以区别与系统段描述符和门描述符(DT=0)。
G=0表示界限粒度为字节;G=1表示界限粒度为4K 字节。注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位
补充:段界限规定段的大小。在80386保护模式下,段界限用20位表示,而且段界限可以是以字节为单位或以4K字节为单位。段属性中有一位对此进行定义,把该位成为粒度位,用符号G标记。G=0表示段界限以字节位位单位,于是20位的界限可表示的范围是1字节至1M字节,增量为1字节;G=1表示段界限以4K字节为单位,于是20位的界限可表示的范围是4K字节至4G字节,增量为4K字节。当段界限以4K字节为单位时,实际的段界限LIMIT可通过下面的公式从20 位段界限Limit计算出来:
LIMIT=limit*4K+0FFFH=(Limit SHL 12)+0FFFH
所以当粒度为1时,段的界限实际上就扩展成32位。由此可见,在80386保护模式下,段的长度可大大超过64K字节。
在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同。
在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小。D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段;D=0 表示默认情况下,使用16位地址及16位或8位操作数,这样的代码段也称为16位代码段,它与80286兼容。可以使用地址大小前缀和操作数大小前缀分别改变默认的地址或操作数的大小。
在向下扩展数据段的描述符中,D位决定段的上部边界。D=1表示段的上部界限为4G;D=0表示段的上部界限为64K,这是为了与80286兼容。
在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器。D=1表示使用32位堆栈指针寄存器ESP;D=0表示使用16位堆栈指针寄存器SP,这与80286兼容。
80386对该位的使用未做规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。
在上面我们讲过对于存储段描述符其DT位为1,当描述符的DT位为0时,那么这个描述符所描述的就是一个系统段描述符了。
系统段是为了实现存储管理机制所使用的一种特别的段。在80386中,有两种系统段:任务状态段TSS和局部描述符表LDT段。用于描述系统段的描述符称为系统段描述符。
系统段描述符与存储段描述符几乎一模一样,但也有一定的差别:
(1)DT位,DT=1表示存储段,DT=0表示系统段。
(2)D位,D位在系统段中不使用。
(3)与存储段最不相同的是TYPE段。系统段描述符的类型字段TYPE仍是4位,其含义与存储段描述符的类型却完全不同。只有类型编码为2、1、3、9和B的描述符才是真正的系统段描述符,它们用于描述系统段LDT和任务状态段TSS
门描述符与系统描述符基本一样,只有系统段描述符的类型字段TYPE不一样,如下图所示,只有类型编码为2、1、3、9和B的描述符才是真正的系统段描述符,其它类型的描述符是门描述符
图(3) 系统段和门描述符的TYPE属性