-
-
[原创]6.滴水中级班(内核驱动)——段描述符属性之DB位
-
发表于: 2025-9-20 11:28 404
-

DB位是位于高四个字节里的第22位。

这里举了一个例子

8965 E8是32位寻址,分析过程:
段描述符中的 D/B 位决定了该段的默认操作大小,也就是确定是 16 位寻址还是 32 位寻址。
对于您给出的“8965 E8”,重点看第 6 字节 E8(16 进制),它对应的二进制是:
E8h = 11101000b
这个字节中的每一位都代表不同的属性,其中:
- 第 6 位(二进制位从 0 开始计数,即 bit 6,对应十进制64的位置)是 D/B 位
具体位置(从右往左,最低位是 bit 0):
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 |
- 这里,bit 6 = 1
D/B 位的含义是:
- 0 表示段为 16 位操作大小(16 位寻址)
- 1 表示段为 32 位操作大小(32 位寻址)
因此,因为 D/B 位是 1,说明描述符设置的是32位寻址。
总结分析过程:
- 从描述符中定位到第 6 字节(即 Flags 字节),其值为 E8。
- 将 E8 转换成二进制形式 11101000。
- 寻找 D/B 位(bit 6),其值为 1。
- 根据规则 D/B=1 表示 32 位操作大小,所以该段是 32 位寻址。
这就是判断段描述符为 32 位寻址的详细过程。这里再补充一下——为什么重点看第六个字节?
段描述符的结构如下(字节序从低地址到高地址,Intel CPU 是小端序):
字节编号 | 说明 |
0-1 | 段界限低16位(Limit 15:0) |
2~3 | 段基地址低16位 |
4 | 段基地址中间8位 |
5 | Type (4 bit) + S + DPL (2 bit) + P (1 bit) 访问权限和段类型 |
6 | 段界限高4位 + AVL + L + D/B + G 段描述符属性位 |
7 | 段基地址高8位 |
结合这个结构说明:
第六个字节(byte 6)包含了影响段访问的关键标志,比如:
D/B(Default operation size / Big)位,决定默认访问大小为16位还是32位(该位是第6字节中第6位)
G(Granularity)位:段界限粒度(字节或4KB)
L:64位代码段标志(仅x86-64用)
AVL:对操作系统可用位,没有硬件意义
以及段界限高4位
因此,要判断段是16位还是32位寻址,必须查看 第 6 字节中的 D/B 位。
小端存储与字节序解释
小端存储是指多字节数据低位字节存放在低地址,高位字节存放在高地址。
段描述符整体是64位(8字节),其中各字段分散在多个字节中,小端存储保证了低位字节放在前面。
但这不影响对具体字节内容的读取,只要知道对应字节的偏移即可。
段基地址为什么用4字节?
段描述符中的基地址是分散存储的:
低16位基地址在第2、3字节
中间8位基地址在第4字节
高8位基地址在第7字节 合起来就是32 位基地址,这就是段的起始地址。
这时如果在前面加一个前缀67:

那么现在的寻址方式就是16位寻址。
D/B位对CS段的影响是这样的:段加载的时候,如果D位为1,将默认采用32位的寻址,如果D位为0,那么将采用16位的寻址。
接下来是对SS段的影响,这里需要补充一下,我们之前一直说段描述符或者是描述代码段(或数据段)、或者是描述系统段,这里为什么会有一个SS段呢?是因为如果数据段加载到SS段里面去了,那么数据段就变为所谓的SS段了,但这个段仍被称为数据段。
当D位为1的时候,就是隐式堆栈访问指令,即修改ESP的值就是隐式堆栈访问指令,如果D位为0,那么修改的就是SP而不是ESP。
最后就是对向下拓展的数据段有影响。如下图所示,D=1,表示向下拓展的上限是4G,D=0就表示向下拓展的上限是64KB。

以上就是D/B位的影响,只对这三个段有影响,对其他段无影响。