分段机制
实模式下的分段机制
也就是8086的16位模式,16位的段寄存器左移4位(变为20位大小)作为段基址,再加上相应的段偏移值就得到了最终的地址。
比如对于代码段(code segment),计算%cs<<4+%ip就是当前实际要寻址的代码地址。
保护模式下的分段机制
这时,段寄存器的值并不是直接作为段偏移,而是分为了三部分:

- 索引(Index):在描述符表中的下标值,最多\(2^{13}=8192\)个描述符。
- 表指示位(Table Indicator):表示该访问哪一个描述符表,0表示全局描述符表(GDT),1表示局部描述符表(LDT)。
- 要求的特权级(Requested Previlege Level):0表示内核态,3表示用户态。
段描述符一共64bit,其中包括32位的段基地址,20位的段大小,段的类型等。

- Base:段基址。
- Limit:段限长。
- G:段限长的颗粒度,为0表示1B,段限长最大1MB,1表示4KB,段限长最大4GB。
- D/B:0表示16位模式,1为32位模式。代码段为0则使用寄存器
%ip,为1使用%eip。栈段为0使用寄存器%sp,为1使用%esp。 - L:是否为64位代码段。
- AVL:系统软件可用位。
- P:存在位,如果这一位为0,则此描述符为非法的,不能被用来实现地址转换。如果一个非法描述符被加载进一个段寄存器,处理器会立即产生异常。
- DPL:段特权级。
- S:为0表示为系统段,为1表示为普通段。
当S为0时,记录的是系统段,具体类型由type的值确定。
| 系统段类型 | type值 | 说明 |
|---|---|---|
| 未定义 | 0000 | 保留 |
| 可用的80286TSS | 0001 | 仅限80286,任务状态段 |
| LDT | 0010 | 局部描述符表 |
| 忙碌的80286TSS | 0011 | 仅限80286 |
| 80286调用门 | 0100 | 仅限80286 |
| 任务门 | 0101 | |
| 80286中断门 | 0110 | 仅限80286 |
| 80286陷阱门 | 0111 | 仅限80286 |
| 未定义 | 1000 | 保留 |
| 可用的80386TSS | 1001 | 386以上的CPU的任务状态段 |
| 未定义 | 1010 | 保留 |
| 忙碌的80386TSS | 1011 | |
| 80386调用门 | 1100 | 386以上CPU的调用门 |
| 未定义 | 1101 | 保留 |
| 中断门 | 1110 | 386以上CPU的中断门 |
| 陷阱门 | 1111 | 386以上CPU的陷阱门 |
当S为1时,记录的是数据段或者代码段,对于数据段和代码段type的值每一位有不同的含意。
代码段如下,type的值由高到低每一位分别为XCRA。
| X | C | R | A | 说明 |
|---|---|---|---|---|
| 1 | 0 | 0 | * | 可执行代码段 |
| 1 | 1 | 0 | * | 可执行,一致代码段 |
| 1 | 0 | 1 | * | 可执行,可读代码段 |
| 1 | 1 | 1 | * | 可执行,可读,一致代码段 |
数据段如下,type的值由高到低每一位分别为XEWA。
| X | E | W | A | 说明 |
|---|---|---|---|---|
| 0 | 0 | 0 | * | 只读数据段 |
| 0 | 1 | 0 | * | 只读,向低地址扩展的数据段 |
| 0 | 0 | 1 | * | 可读写数据段 |
| 0 | 1 | 1 | * | 可读写,向低地址扩展的数据段 |
浙公网安备 33010602011771号