段描述符是位于GDT或LDT中8字节的项,给处理器提供一个段的位置、界限、访问特权级等信息。
段描述符的结构:
# G:粒度标志。Segment Limit 字段的大小比例。G=0,Segment Limit 以字节为单位;G=1,Segment Limit 以4KB为单位,计算:实际段界限 = 描述符中的段界限 * 0x1000 + 0xFFF。该标志不影响Base字段的粒度,Base字段永远以字节为单位。
# Segment Limit:表示该段的大小/界限。处理器用G标志位来解释该字段。当G=0,段的大小是1B~MB,以1字节为单位增长;当G=1,段的大小是4KB~4GB,以4KB为单位增长。对于段的扩展方向,如果是向上扩展段,逻辑地址的偏移量是0~Segment Limit;如果是向下扩展段,逻辑地址的偏移量是Segment Limit(最小值)~FFFFFFFFh或FFFFh。实模式下,处理器将Limit预置成0xFFFF,以防出错。
# Base:段在线性地址空间中的开始位置。段基址应当是16字节边界对齐的,提高程序性能。
# DPL:该描述符的特权级,0 ~ 3。用于控制对该段的访问。
# P:表示该段是否在内存。P=1,该段在内存中;P=0,该段不在内存中,处理器产生一个#NP异常,操作系统可以自由地使用Available域。
# D:处理器默认操作尺寸,表示该段按16位还是32位尺寸操作。对于代码段,D/B位是D位,表示默认的操作尺寸。当D=0,表示16位默认操作尺寸;当D=1,表示32位默认操作尺寸。
# B:对于数据段,D/B位是B位。当栈段的B位=0,使用sp;B位=1,使用esp。
# L:用于IA-32e模式下。表示一个代码段是否包含原生64位代码。L=1,表示该代码段中的指令运行在IA-32e下,D位必须为0;L=0,表示该代码段中的指令运行在兼容模式下,该位作为保留位。
# AVL:是否可以被系统软件使用。
# S:确定段描述符是系统/门段描述符(S=0)还是代码/数据段描述符(S=1)。
# Type:表示段的类型(代码段、数据段、门、系统段)和它们的权限和信息。具体是什么段先由S位决定再根据Type域的二进制决定。
参考资料
Combined Volume Set of Intel® 64 and IA-32 Architectures Software Developer’s Manuals