段描述符是GDT和LDT表中的一个数据结构项,用于向处理器提供有关一个段的位置和大小信息以及访问控制的状态信息。通常由编译器,链接器,加载器,或操作系统或执行体,但不由应用程序创建。
简介
每个段描述符的长度是8字节,含有3个主要字段:段基地址、段限长和段属性。段描述符通常由
编译器、
链接器、加载器或者操作系统来创建,但绝不是应用程序。图一给出了所有类型段描述符的一般格式。
描述
如图一所示,一个段描述符中各字段和标志的含义如下:
(1)段限长字段Limit(Segment limit field):用于指定段的长度。处理器会把段描述符中两个段限长字段组合成一个20位的值,并根据颗粒度标志G来指定段限长Limit值的实际含义。
根据段类型中的段扩展方向标志E,处理器以两种不同方式使用段限长Limit:对于向上扩展的段(expand-up segment,简称上扩段),
逻辑地址中的偏移值范围可以从0到段限长值Limit。大于段限长Limit的偏移值将产生一般保护性异常(general-protection exceptions, #GP, SS段寄存器除外)或产生栈错误异常(stack-fault exceptions, #SS)。对于向下扩展的段(expand-down segment,简称下扩段),段限长Limit的含义相反。根据默认栈
指针大小标志B的设置,偏移值范围可从段限长Limit+1到0xFFFFFFFF或0xFFFF。而小于等于段限长Limit的偏移值将产生一般保护性异常或栈错误异常。对于下扩段,减小段限长字段中的值会在该段
地址空间底部分配新的内存,而不是在顶部分配。IA-32架构的栈总是向下扩展的,因此这种实现方式很适合扩展
堆栈。
(2)基地址字段Base(Base address field):该字段定义在4GB
线性地址空间中一个段字节0所处的位置。处理器会把3个分立的基地址字段组合形成一个32位的值。段基地址应该对齐16字节边界。16字节对齐不是必须的,但对齐在16字节边界上使得程序能最大化程序性能。
(3)段类型字段TYPE(Type field):指定段或门(Gate)的类型、说明段的访问类型以及段的扩展方向。该字段的解释依赖于描述符类型标志S指明是一个应用(代码或数据)描述符还是一个系统描述符。TYPE字段的编码对代码、数据或系统描述符都不同,如图二所示。
(4)描述符类型标志S(Descriptor type flag):用于指明一个段描述符是系统段描述符(当S=0)还是代码或
数据段描述符(当S=1)。
(5)描述符
特权级字段DPL(Descriptor privilege level):用于指明描述符的
特权级。
特权级范围从0到3。0级
特权级最高,3级最低。DPL用于控制对段的访问。
(6)段存在标志P(Segment present):用于指出一个段是在内存中(P=1)还是不在内存中(P=0)。当一个段描述符的P标志为0时,那么把指向这个段描述符的选择符加载进
段寄存器将导致产生一个段不存在异常(segment-not-present exception,#NP)。内存管理软件可以使用这个标志来控制在某一给定时间实际需要把那个段加载进内存中。这个功能为
虚拟存储提供了除分页机制以外的控制。图三给出了当P=0时的段描述符格式。当P标志为0时,操作系统可以自由使用格式中标注为可用(Available)的字段位置来保存自己的数据,例如有关不存在段实际在什么地方的信息。如图三所示的 当存在位P=0时的段描述符格式
(7)D/B标志(默认操作大小/默认栈
指针大小和/或上界限,Default operation size/default stack pointer size and/or upper bound):根据段描述符描述的是一个
可执行代码段、下扩
数据段还是一个
堆栈段,这个标志具有不同的功能。(对于32位代码和
数据段,这个标志应该总是设置为1;对于16位代码和数据段,这个标志被设置为0。)
(8)粒度标志G(Granularity):该字段用于确定段限长字段Limit值的单位。如果颗粒度标志为0,则段限长值的单位是字节;如果设置了颗粒度标志,则段限长值使用4KB单位。(这个标志不影响段基地址的颗粒度,基地址的颗粒度总是字节单位。)若设置了G标志,那么当使用段限长来检查偏移值时,并不会去检查偏移值的12位
最低有效位。例如,当G=1时,段限长为0表明有效偏移值为0~4095。
(9)64位代码段标志L(64-bits code segment):在IA-32模式,第二个双字的第21字节指示一个代码的是否包含本地64位代码。L置1表示这个代码段的指令执行在64位模式,置0表示执行在兼容模式。如果L位被设置了,那么D标志一定要置0。当不处于IA-32e模式时,和对于非代码段,这个位被保留并且总是应该被置0。
(10)可用和保留位AVL(Available and reserved bits):段描述符第2个双字的第20字节可供系统软件使用;