保护模式(一):段描述符与段选择子
段描述符
结构
P位
P=1:段描述符有效
P=0:段描述符无效
G位
G=0:段寄存器Limit单位为字节,Limit最大值0x000FFFFF
G=1:段寄存器Limit单位为4KB,Limit最大值0xFFFFFFFF
S位
S=1:代码段或数据段描述符
S=0:系统段描述符
Type
如果S位为1
数据段:
A:是否被访问过
W:是否可写
E:是否向下拓展
代码段:
R:是否可读
C:是否为一致代码段
如果S位为0
D/B位
对CS段:
D=1:采用32位寻址方式
D=0:采用16位寻址方式
对SS段:
D=1:隐式堆栈访问命令使用32位堆栈指针寄存器ESP
D=0:隐式堆栈访问命令使用16位堆栈指针寄存器SP
隐式堆栈访问命令(如push,pop,call)
对向下拓展的数据段:
D=1:段上限4GB
D=0:段上限64KB
DPL(描述符特权级别)
值为00或11
段选择子
结构
RPL(请求特权级别)
TI
TI=0:查GDT表
TI=1:差LDT表
windows未使用LDT表
Index
要用的段描述符为GDT/LDT的基地址+Index*8byte
段寄存器
struct SegMent
{
WORD Selecter, //段选择子
WORD Attribute, //段属性
DWORD Base, //段基址
DWORD Limit, //段长度
}
段描述符与段寄存器对应关系
Selecter:段选择子 Attribute:从Type到G位 Base:【Base 31:24】+【Base 23:16】+【Base Address 15:00】 Limit:
G位为0:000 +【Seg Limit 19:16】+【Seg Limit 15:0】
G位为1:【Seg Limit 19:16】+【Seg Limit 15:0】+FFF
权限检查
数据段权限检查
CPL(当前特权级)
CS和SS储存的段选择子后两位
CPL=0:0环
CPL=3:3环
举例
mov ax,000Bh // 1011 RPL=3
mov ds,ax // ax指向的段描述符中DPL
检查
CPL<=DPL && RPL<=DPL
代码段权限检查
非一致代码段:CPL=DPL && RPL<=DPL
一致代码段:CPL>=DPL