段选择子结构
段选择子就是一个数字,一共有16位,结构如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- INDEX:在GDT数组或LDT数组的索引号
- TI:Table Indicator,这个值为0表示查找GDT,1则查找LDT
- RPL:请求特权级。以什么样的权限去访问段。
段描述符结构
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- BASE: 段基址,由上图中的两部分(BASE 31-24 和 BSE23-0)组成
- G:LIMIT的单位,该位 0 表示单位是字节,1表示单位是 4KB
- D/B: 该位为 0 表示这是一个 16 位的段,1 表示这是一个 32 位段
- AVL: 该位是用户位,可以被用户自由使用
- LIMIT: 段的界限,单位由 G 位决定。数值上(经过单位换算后的值)等于段的长度(字节)- 1。
- P: 段存在位,该位为 0 表示该段不存在,为 1 表示存在。
- DPL:段权限
- S: 该位为 1 表示这是一个数据段或者代码段。为 0 表示这是一个系统段(比如调用门,中断门等)
- TYPE: 根据 S 位的结果,再次对段类型进行细分。
limit 的含义是这个段的大小。实际上这么说的点不准确。limit 应该描述为,段大小再减去1字节。(这里的 limit 是换算后的 limit)。后面我用大写的 LIMIT 表示段描述符中的 20bit LIMIT。
如果粒度 G=0,LIMIT= 0x3ff
,这意味着该段的大小是 0x3ff+1=0x400
字节。如果 G=1
,那意味着该段的大小是(0x3ff+1)*4KB=0x400000
字节,所以换算后的 limit = 0x400000-1=0x003fffff
.
再举个例子。LIMIT=0xfffff, G=1
,则该段的大小是 (0xfffff+1)*4KB=0x100000*0x1000=0x100000000
字节,所以换算后的limit=0x100000000-1=0xffffffff
- limit 简算法
如果 G = 0,把段描述符中的 20 bit LIMIT取出来,比如0x003ff
,然后在前面补0
至32bit,即limit = 0x000003ff
.
如果 G=1,把段描述符中的 20 bit LIMIT取出来,比如0x003ff
,然后在后面补f
至 32bit, 即LIMIT = 0x003fffff