段描述符结构
段描述符的类别
在整个GDT表中的段描述符分为两大类:
- 数据段或代码段描述符。
- 系统段描述符。
S位
S位处于段描述符高4字节的第12位。
- 当S位为0则说明该段描述符是系统段的描述符;
- 当S位为1则说明该段描述符是代码段或数据段的描述符。
TYPE域
TYPE域处于段描述符高4字节的第8至11位。
注意:在数据段或代码段中,TYPE域中的四位的含义是不一样的,在系统段描述符中,它的含义又变成了另外的情况。
小结
当想拆分一个段描述符属性的时候:
- 首先判断P位,P位决定了该段描述符是否有效。
- 其次判断S位,S位决定了该段描述符具体类别。
- 当S位为0则说明该段描述符是系统段的描述符;
- 当S位为1则说明该段描述符是代码段或数据段的描述符。
- 当拆分到S位,在S位的基础上再去了解TYPE域是什么含义。
举例说明
首先回顾一下段描述符结构。
- 前文提到:
- P = 0:段描述符无效。
- P = 1:段描述符有效。
- S位处于高4字节的第12位;
- P位处于高4字节的第15位,且决定了当前段描述符是否有效;
DPL处于高4字节的第13至14位,其在Windows中只会出现两种情况,DPL都是0或者都是1。
扫描二维码关注公众号,回复:
12895658 查看本文章
如上图,想对一个段描述符的代码段/数据段的TYPE域的属性进行分析:
- S位一定是1。
- P位一定是1。
- DPL如果都为0的时候:也就是1001,转换为十进制为9。
- DPL如果都为1的时候:也就是1111,转换为十进制为F。
- 如上图的GDT表,想找代码段/数据段,只需要找到高4字节十六进制的第5位为9或者是F的才是代码段和数据段。
- 其他的就可以不需要管了,它一定不是代码段和数据段。
确定了是代码段/数据段了以后,接下来想分析到底是代码段还是数据段:
- TYPE域的第11位如果为0,那么就是一个数据段。
- TYPE域的第11位如果为1,那么就是一个代码段。
也可以这么理解:
如上图中的 00cf9b00`0000ffff :
- 通过观察段描述符的高4字节的第五位(9或f),能确定是代码段还是数据段。
- 通过观察段描述符的高4字节的第六位(b),b是大于8的,在TYPE域表格中查找发现大于等于8的就是代码段。
如果是数据段
其中有3个值很重要,分别是A、W、E。
- A:是否访问过。如操作系统启动的时候,段描述符是没有被加载过的,那它的A位一定是0。当它被访问过/使用过,那A位会被置1。
- W:是否可写。如果为0,代表当前段虽然是数据段,但是它是不可写的,如果为1就是可写的。
- E:拓展位。如果为0,代表向上扩展。如果为1,代表向下扩展。
- base:指的是段数据从哪里开始,如图1红色的上边框。
- limit:指的是当前描述的段有多长,如图1大括号括起来的部分就是limit。
向上扩展:描述的地址有效范围是:从base开始到base加上limit结束。也就是图1中的红色部分,向上拓展是有效的。
向下扩展:描述的地址有效范围是:除了base开始到base加上limit结束相反的地方,也就是图2中标红的位置。
如果是代码段
其中有3个值很重要,分别是A、R、C。
- A:是否被访问过,同数据段一样,没访问过为0,访问过为1。
- R:可读位,当前段是否可读。
- C:一致位。
- C = 1,一致代码段。
- C = 0,非一致代码段。
系统段描述符
当 S = 0,该段描述符为系统段描述符,系统段描述符有以下类型:
举例:
- 当S位为0的时候,能知道当前的段描述符是一个系统段描述符。
- 再看TYPE域,YTPE域如果拼出来的值如果等于1011,那就可以知道是一个 32-Bit TSS (Busy),并且处于繁忙状态。
练习
首先找到GDT表,并开始拆分:
- 找出所有数据段,并分析该段属性:只读、已访问、可读可写、扩展方向。
- 找出所有代码段,并分析该段属性:只执行,可读可执行、已访问、一致代码。
- 找出所有系统段,并分析属于系统段中的哪一个小类(上图)。