描述符
前面已经提到,描述符是描述一个段的大小,地址及各种状态的8个字节的结构,在编程时它可以定义它.
如图2所示,根据描述符所描述对象的不同,描述符可分为存储段描述符、系统段描述符、门描述符三种,而门描述符又可分为调用门、任务门、中断门和陷阱门四类。下面将分别介绍各描述符作用及其各位的意义:
一、存储段描述符
存储段描述符是描述程序中的代码段和数据段的,这其中也包括堆栈段,在保护模式下,应该把堆栈段理解为特殊的数据段。
分析存储段描述符时应该把它分成4个域来理解:
第一个域为描述符的第0至1字节,该字是段界线的低16位,段界线是描述段的大小共20位,高4位在第六字节的低4位中;第二个域为描述符的第2至4字节,这三个字节是段基址的低24位;第三个域是描述符的第5、6字节,该字存放的是段的一些属性;第四个域是最后一个字节,该字节存放的是段基址的高8位。下面对属性字的每一位进行描述:
如图2所示:
P位说明所描述的段是否存在,P=1表示描述符所描述的段存在于内存中,P=0表示描述符所描述的段不在内存中。
DPL为描述符所描述段的特权级,只有有效特权级EPL大于等于DPL时,才能对段进行访问。
DT位必有为1以区别于系统段描述符。
TYPE字段:
位0表示被描述的段是否被访问过,该位为0表示未被访问过,为1则表示该段先前已经被访问过。
位1的定义在于描述符所描述段的类型。当所描述的是代码段时,该位指示所描述的代码段是否可读,为1则可读,为0则不可读;当所描述的是数据段时,该位指示所描述的数据段是否可写,为1则可写,为0则不可写。
位2的定义也在于描述符所描述段的类型。当所描述的是代码段时,该位指示所描述的代码段是否是一至代码段,为1表示该代码段是一至代码段,为0表示该代码段不是一至代码段,即是普通的代码段。当所描述的是数据段时,该位指示该段的扩展方向,为1时表示该段向低地址扩展,为0时表示该段向高地址扩展。
位3指示所描述的段类型,为1表示所描述的段是代码段,是可以被执行的,为0表示所描述的段是数据段,是不能被执行的。前面已经说了,在保护模式下应该把堆栈段理解为特殊的数据段,为0时也包括堆栈段。
G位表示段界限的计数单位,该位为0时表示段界限以字节为单位,为1时表示以4K为单位。这样计算下来,20位的段界限就可以描述大小为64K或4G的段了,
D位说明描述符所描述的段是32位环境还是16位的环境。该决定了指令所使用的操作数以及地址的默认大小,为1时说明是32位地址和32位操作数,即32位段;为0时说明是16位地址和16位操作数,即是16位段。但这时仍可使用操作数及地址大小前缀来改变这种默认设置。该位还决定了系统是使用IP还是EIP,使用SP还是ESP,
二、系统段描述符
系统段描述符是描述两个特殊的段,它们分别为局部描述符表LDT段和任务状态段TSS。
从图2中可见,系统段描述符与存储段描述符的区别只在于DT位,DT=1则为存储段描述符,DT=0则为系统段描述符,两种描述符就靠此位区分.但系统段描述符的TYPE字段与存储段描述符的TYPE却截然不同.描述如下:
TYPE字段:
0、1两位的定义取决于位2。当位2为1时,说明是门描述符,为0时说明是非门描述符。当位2为1时,0、1两位确定门描述符的类型,因为两位可有4种状态,所以正好描述4个描述符,为0时则是调用门,为1时则是任务门,为2时则是中断门,为3时则是陷阱门;当位2为0时,低两位0位、1位为0时未定义,为1时则是可用的286的TSS,为2时则是LDT,为3时则是忙的286的TSS。
位4为0时,如其它位也为0或低两位为2或3时则也是未定义,否则该位提示是386还是286描述符,关于段基地址和段界限为何都安排在两个分开的域中的原因也与此有关,请读者自己想想!
三、门描述符
从系统段描述符的说明中可以看出门描述符是靠TYPE字段与系统段描述符区分的,但从图2中可见门描述符却与系统段描述符在结构上也不一至,其实这才是区分二者关键。门描述符的第四字节的低4位为双字计数字段,该字段是说是在发生特权级变换时,把外层堆栈中的参数拷贝到内层堆栈中的数量,计数以双字为单位。关于特权级变换请参阅《保护模式下的特权级检查》一文.
(待续)
本文地址:http://com.8s8s.com/it/it29379.htm