687 lines
31 KiB
Markdown
687 lines
31 KiB
Markdown
# 第5章 Pentium 微处理器保护模式存储管理(期末复习总结)
|
||
|
||
> 本章是《微机系统》课程的**核心难点**:Pentium 在保护模式下通过"分段 + 分页"两套机制,把程序员使用的虚地址最终转换为物理地址,同时提供内存保护、特权级保护和虚拟存储器。本章概念抽象、字段众多,是期末考试必考章节。
|
||
|
||
---
|
||
|
||
## 一、详细内容分析
|
||
|
||
### 1.1 虚拟存储器及其工作原理
|
||
|
||
#### 1. 虚拟存储器定义
|
||
|
||
虚拟存储器(Virtual Memory) = **主存储器 + 辅助存储器 + 辅助硬件 + 操作系统管理软件**组成的一种存储体系。
|
||
|
||
- **目标**:增加主存的存储容量
|
||
- **性能特点**:速度接近主存,单位造价接近辅存,性价比极高
|
||
|
||
#### 2. 虚拟存储器 vs Cache 存储器
|
||
|
||
| 比较项 | 虚拟存储器 | Cache 存储器 |
|
||
|---|---|---|
|
||
| 存储层次 | 主存 ↔ 辅存 | Cache ↔ 主存 |
|
||
| 主要功能 | 增加主存速度与容量 | 增加 CPU 速度与主存容量 |
|
||
| 信息传送单位 | 信息块(段/页),长度较大 | 信息块(块/行),长度较小且固定 |
|
||
| 结构差别 | CPU ↔ 主存 ↔ 辅存,主存不命中时由 OS 调度 | CPU ↔ Cache ↔ 主存,CPU 与主存间有直接通路 |
|
||
| 实现方式 | 部分硬件 + OS 软件 | 全部硬件 |
|
||
| 透明性 | 对应用程序员透明;对存储管理软件程序员不透明 | 对所有程序员透明 |
|
||
|
||
> 这一点常考简答题:**虚拟存储器和 Cache 的区别**。
|
||
|
||
#### 3. 三种地址空间及三种地址(重要概念)
|
||
|
||
| 地址空间类型 | 又称 | 用途 | 对应地址 |
|
||
|---|---|---|---|
|
||
| 虚拟地址空间 | 虚存地址空间 | 应用程序员编写程序用的地址空间 | 虚地址 / 逻辑地址 |
|
||
| 主存地址空间 | 实存地址空间 | 存储、运行程序的空间 | 主存物理地址 / 实地址 |
|
||
| 辅存地址空间 | 磁盘地址空间 | 存放程序及数据 | 辅存地址 / 磁盘地址 |
|
||
|
||
**三者关系**:程序先编写在虚拟空间;运行时由系统调入主存;若主存不够,部分内容调入辅存。
|
||
|
||
#### 4. 虚拟存储器工作原理(存储管理方式)
|
||
|
||
Pentium 处理器支持的 3 种存储管理方式:**段式、页式、段页式**。
|
||
|
||
Pentium 的存储管理部件由两部分组成:
|
||
- **分段部件**:将逻辑地址 → 连续的不分段的线性地址
|
||
- **分页部件**:将线性地址 → 物理地址
|
||
|
||
工作流程(参考图 5.1.1):
|
||
|
||
```
|
||
逻辑地址 ──► 分段部件 ──► 线性地址 ──► 分页部件 ──► 物理地址 ──► 主存
|
||
│ │
|
||
▼ 不分页时省略 ▼ 不命中时
|
||
(线性地址 = 物理地址) OS 调度 + 替换算法 → 辅存
|
||
```
|
||
|
||
转换失败 → 外部地址变换 → 检查主存是否有空闲区 → 无空闲则启动替换算法 → 把辅存内容调入主存,再访问。
|
||
|
||
### 1.2 实模式 vs 保护模式(基础对比)
|
||
|
||
| 项目 | 实模式 | 保护模式 |
|
||
|---|---|---|
|
||
| 地址位数 | 段基址 16 位 + 偏移 16 位,最大 1 MB | 48 位存储指针(选择符+偏移),32 位偏移 |
|
||
| 段基址来源 | 段寄存器内容直接当基址(左移 4 位) | 由段描述符(8 字节,含 32 位基址)提供 |
|
||
| 最大可寻址空间 | 1 MB(20 位地址) | 4 GB(32 位物理地址)+ 64 TB 虚拟空间 |
|
||
| 段长度 | 固定 64 KB,由 16 位偏移限定 | 可变,最大 4 GB(限长 20 位 + G 粒度位) |
|
||
| 段描述符 | 无 | 每个段有一个 8 字节描述符,由 GDT/LDT 管理 |
|
||
| 特权级 | 无 | 4 级(0~3)保护 |
|
||
| 内存保护 | 基本没有 | 段限长 / 类型 / 特权级 多重保护 |
|
||
| 段寄存器内容 | 即段基址(高 16 位) | 段选择符(可见)+ 段描述符缓存(不可见) |
|
||
| 适用场景 | DOS、早期 8086 程序 | 现代操作系统(Windows/Linux) |
|
||
|
||
> **关键差异**:实模式下"段寄存器内容 = 段基址";保护模式下"段寄存器内容只是索引,要靠描述符表查出真正的段基址"。
|
||
|
||
保护模式如何进入:通过 CR0 的 PE 位(Protection Enable)= 1 进入。
|
||
|
||
### 1.3 分段存储管理
|
||
|
||
#### 1. 分段基本思想
|
||
|
||
- **段式管理**:把主存按"段"分配的存储管理方式
|
||
- 每个段由 **段描述符** 描述(含基址、界限、属性),组成 **段描述符表**
|
||
- 程序中每个逻辑段 → 经描述符表 → 映射到主存的任意位置(不一定连续)
|
||
|
||
#### 2. 虚拟地址(逻辑地址)构成
|
||
|
||
Pentium 保护模式下使用 **48 位存储器指针**,但参与寻址的只有 **46 位**(RPL 2 位不参与寻址),可寻址空间 64 TB。
|
||
|
||
```
|
||
虚拟地址 (48 位) = 16 位段选择符 + 32 位偏移量
|
||
|
||
┌─────────────────┬─────────────────────────┐
|
||
位: │ 段选择符 │ 偏移量 │
|
||
│ 16 位 │ 32 位 │
|
||
└─────────────────┴─────────────────────────┘
|
||
47 ... 32 31 ... 0
|
||
|
||
段选择符 (16 位):
|
||
┌─────────────────┬─────┬─────┐
|
||
位: │ INDEX │ TI │ RPL │
|
||
│ 13 位 │ 1 位 │ 2 位│
|
||
└─────────────────┴─────┴─────┘
|
||
15 ... 3 2 1 0
|
||
```
|
||
|
||
例:逻辑地址 `0207:11223344H` = 16 位选择符 0207H + 32 位偏移量 11223344H
|
||
|
||
#### 3. 虚实地址转换(分段阶段)
|
||
|
||
转换流程(图 5.2.3):
|
||
|
||
```
|
||
步骤 1: 取段选择符 (16 位) → 段寄存器
|
||
步骤 2: 拆分 INDEX(13) + TI(1) + RPL(2)
|
||
步骤 3: 若 TI=0 查 GDTR;若 TI=1 查 LDTR
|
||
步骤 4: 描述符地址 = GDTR/LDTR 基址 + INDEX × 8
|
||
步骤 5: 取出 8 字节段描述符(含 32 位基址)
|
||
步骤 6: 32 位基址 + 32 位偏移量 = 32 位线性地址
|
||
步骤 7:(若分页使能) 线性地址经分页 → 物理地址
|
||
(若未分页) 线性地址即为物理地址
|
||
```
|
||
|
||
> 关键公式:**线性地址 = 段描述符中的段基址 + 偏移量**
|
||
> 8 字节对齐:因每个描述符占 8 字节,所以 ×8。
|
||
|
||
#### 4. 段描述符分类
|
||
|
||
```
|
||
段描述符
|
||
├── 程序段描述符 (S=1)
|
||
│ ├── 代码段描述符
|
||
│ ├── 堆栈段描述符
|
||
│ └── 数据段描述符
|
||
└── 系统段描述符 (S=0)
|
||
├── 任务状态段 (TSS) 描述符
|
||
├── 局部描述符表 (LDT) 描述符
|
||
└── 门描述符
|
||
├── 调用门描述符
|
||
├── 任务门描述符
|
||
├── 中断门描述符
|
||
└── 陷阱门描述符
|
||
```
|
||
|
||
描述符由编译程序、连接程序、装入程序或操作系统产生。
|
||
|
||
### 1.4 段描述符的格式(高频考点)
|
||
|
||
#### 1. 程序段描述符(8 字节)
|
||
|
||
| 字节偏移 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 含义 |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| 0 | 段界限 7~0 |||||||||| 段限低 8 位 |
|
||
| 1 | 段界限 15~8 |||||||||| 段限次高 8 位 |
|
||
| 2 | 段基址 7~0 |||||||||| 基址低 8 位 |
|
||
| 3 | 段基址 15~8 |||||||||| 基址次高 8 位 |
|
||
| 4 | 段基址 23~16 ||||||||| 基址 |
|
||
| 5 | P(1) | DPL(2) || S(1) | TYPE(4) |||||| 存在/特权级/类型 |
|
||
| 6 | G(1) | D/B(1) | 0(1) | AVL(1) | 段界限 19~16 |||||| 粒度与段限高 4 位 |
|
||
| 7 | 段基址 31~24 |||||||||| 基址高 8 位 |
|
||
|
||
各字段含义:
|
||
|
||
1. **基址(Base Address)**:32 位,给出本段在 4 GB 物理地址空间中的起始位置
|
||
2. **段界限(Segment Limit)**:20 位,本段的长度,单位由 **G 位** 决定
|
||
3. **粒度位 G**:G=0 时单位为字节;G=1 时单位为 4 KB
|
||
- G=0:段长最大 `1 MB`
|
||
- G=1:段长最大 `4 GB`
|
||
4. **分类 S**:S=0 表示系统段描述符;S=1 表示非系统段描述符
|
||
5. **存在位 P**:P=1 该段在内存中;P=0 该段不在内存中(页面会调度)
|
||
6. **系统可用位 AVL**:AVL=1 系统软件可用本段;AVL=0 系统软件不能用本段
|
||
7. **特权级 DPL**:2 位,定义段的特权级(4 级:00、01、10、11)
|
||
- 0 级最高(内核),3 级最低(用户)
|
||
- 用 DPL 字段控制对这个段的访问
|
||
8. **类型 TYPE**:在不同段描述符中格式不同
|
||
- **数据段/堆栈段 (E=0)**:ED(扩展方向)、W(可写)、A(已访问)
|
||
- **代码段 (E=1)**:C(一致性)、R(可读)、A(已访问)
|
||
9. **D/B 位**:默认操作数 / 地址类型选择
|
||
- 代码段称 D 位:指示操作数长度和有效地址长度
|
||
- 堆栈段称 B 位:指示 ESP 或 SP
|
||
- 数据段称 B 位:指示操作数长度
|
||
|
||
#### 2. 系统段描述符 / 门描述符
|
||
|
||
分类 S=0 是系统段描述符,**TYPE 类型含义与程序段不同**:
|
||
|
||
| TYPE | 段/门类型 | TYPE | 段/门类型 |
|
||
|---|---|---|---|
|
||
| 0000 | 未定义 | 1000 | 未定义 |
|
||
| 0001 | 286 TSS,非忙 | 1001 | TSS 描述符,非忙 |
|
||
| 0010 | **LDT 描述符** | 1010 | 未定义(保留) |
|
||
| 0011 | 286 TSS,忙 | 1011 | TSS 描述符,忙 |
|
||
| 0100 | 286 调用门 | 1100 | 386 调用门 |
|
||
| 0101 | 任务门 | 1101 | 未定义 |
|
||
| 0110 | 286 中断门 | 1110 | 中断门 |
|
||
| 0111 | 286 陷阱门 | 1111 | 陷阱门 |
|
||
|
||
#### 3. 门描述符
|
||
|
||
- **门**:用来控制从一段程序到另一段程序 / 从一个任务到另一个任务的转移
|
||
- 门描述符给出一个**逻辑地址**及转入此地址的**约束**,用于控制转入目标代码段的入口点
|
||
|
||
门描述符的格式(8 字节):
|
||
|
||
| 字节 | 内容 |
|
||
|---|---|
|
||
| 0 | 偏移地址 7~0 |
|
||
| 1 | 偏移地址 15~8 |
|
||
| 2 | 段选择符 7~0 |
|
||
| 3 | 段选择符 15~8 |
|
||
| 4 | 字计数(Word Count) |
|
||
| 5 | P(存在) + DPL(2) + S(分类) + TYPE(类型) |
|
||
| 6 | 偏移地址 23~16 |
|
||
| 7 | 偏移地址 31~24 |
|
||
|
||
- 字计数:指示调用门要从调用者堆栈复制多少字参数到被调用程序堆栈(仅用于特权级变化的调用门)
|
||
- P=1:描述符内容有效;P=0:描述符内容无效
|
||
|
||
### 1.5 各种描述符表及寄存器
|
||
|
||
#### 1. 全局描述符表 GDT
|
||
|
||
- **GDT**:由段描述符组成,系统程序产生
|
||
- 系统中**只有一个 GDT**
|
||
- **GDT 中保存的描述符类型**:除中断门、陷阱门外的各类描述符(含 LDT 描述符、TSS 描述符、各种程序段描述符)
|
||
- **GDTR 寄存器**:48 位,含 32 位基址 + 16 位界限
|
||
|
||
**GDT 寻址公式**:
|
||
```
|
||
段描述符地址 = INDEX × 8 + GDTR 中基址 (当 TI=0 查 GDT)
|
||
```
|
||
|
||
> 注意:GDTR 中已存好 GDT 的基址和界限;段选择符 × 8 用于索引(每个描述符 8 字节)。
|
||
|
||
#### 2. 局部描述符表 LDT
|
||
|
||
- **LDT**:每个任务一个;除可访问全局描述符表外,每个任务还可访问自己的局部描述符表
|
||
- 起到**任务间隔离、保护**的作用
|
||
- **LDTR 寄存器**:指向当前 LDT,由 **16 位段选择符** + **32 位基址** + **20 位界限** + **12 位属性** 组成(程序可见部分仅 16 位选择符)
|
||
- **LDT 中通常没有 TSS、LDT、中断门、陷阱门**
|
||
|
||
LDT 寻址(图 5.2.6):
|
||
1. LDTR 中装入段选择符
|
||
2. 该选择符指向 GDT 中的一个 LDT 描述符
|
||
3. 通过 LDT 描述符得到 LDT 的基址与界限
|
||
4. 实际访问:LDT 中再以"INDEX × 8 + LDT 基址"得到段描述符
|
||
|
||
#### 3. 中断描述符表 IDT
|
||
|
||
- **IDT**:保存中断处理程序入口的门描述符
|
||
- 整个系统**只有一个** IDT,含中断门、陷阱门、任务门(通常无调用门)
|
||
- **IDTR 寄存器**:48 位,含 32 位基址 + 16 位界限
|
||
|
||
**IDT 寻址公式**:
|
||
```
|
||
门描述符地址 = 中断类型码 × 8 + IDTR 中 IDT 基址
|
||
```
|
||
|
||
每个门与一个中断类型码对应。
|
||
|
||
#### 4. 任务状态段 TSS
|
||
|
||
- **TSS**:保存任务执行时机器状态(各寄存器、CR3 等)及任务间关联信息
|
||
- 支持任务管理(任务切换)
|
||
- **TR(任务寄存器)**:由 16 位段选择符、32 位基址、20 位界限、12 位属性组成
|
||
- TSS 描述符由 TR 寻址:先把 TR 中选择符指向 GDT 中的 TSS 描述符,再由描述符找到 TSS
|
||
|
||
TSS 加载触发任务切换的途径:
|
||
- LTR(装入任务寄存器指令)
|
||
- STR(保存任务寄存器指令)
|
||
- 保护模式下远跳转 JMP / 远调用 CALL
|
||
- 任务门
|
||
|
||
### 1.6 段选择符详解
|
||
|
||
#### 1. 段选择符结构(再次强调,高频考点)
|
||
|
||
| 段选择符 | 索引字段 INDEX | 表选择位 TI | 请求特权级 RPL |
|
||
|---|---|---|---|
|
||
| 总位数 | 13 位 | 1 位 | 2 位 |
|
||
|
||
各字段含义:
|
||
|
||
- **INDEX(13 位)**:索引值 ×8 = 相对 GDT/LDT 首地址的偏移量;再加描述符表的基址(来自 GDTR 或 LDTR)= 段描述符在表中的地址
|
||
- **TI(1 位)**:
|
||
- TI=0:选全局描述符表 GDT
|
||
- TI=1:选局部描述符表 LDT
|
||
- **RPL(2 位)**:4 个特权级 00、01、10、11(0 级最高,3 级最低);不参与寻址;表示请求这个段的程序自身的特权级
|
||
|
||
#### 2. 段选择符如何装入段寄存器
|
||
|
||
**(1)直接加载段寄存器指令**:MOV、POP 指令等(显式加载)
|
||
|
||
**(2)隐含装段寄存器指令**:段间调用 CALL、段间跳转 JMP 等(隐式修改 CS)
|
||
|
||
### 1.7 保护模式下的访问操作与保护机制
|
||
|
||
#### 1. 保护机制分类
|
||
|
||
**(1) 任务间存储空间的保护**
|
||
- 通过任务的 LDT,每个任务确定自己的虚拟存储器空间
|
||
- 起到**任务间隔离、保护**的作用
|
||
|
||
**(2) 段属性和界限的保护**
|
||
- 段寄存器加载时,进行 **段存在性**、**类型**、**段限**等检查
|
||
- 保证正确的访问
|
||
|
||
**(3) 特权级与特权级保护**
|
||
- 4 个特权级别:0 级、1 级、2 级、3 级(对应 CPL/DPL/RPL)
|
||
- 3 种形式的特权管理:
|
||
- **当前特权级 CPL**:当前正在执行的代码段所具有的访问特权级(= CS 寄存器的低 2 位)
|
||
- **描述符特权级 DPL**:段固有的特权级,存放在段描述符的 DPL 字段
|
||
- **请求特权级 RPL**:新装入段寄存器的段选择符的特权级,存放在段选择符的低 2 位;一般为生成这个选择符的程序的特权级
|
||
|
||
**特权管理规则(核心规则)**:
|
||
- 特权级为 P 的段中存储的数据 → 只能由**特权级高于或等于 P** 的段中运行的程序访问
|
||
- 特权级为 P 的代码段/过程 → 只能由在**低于或等于 P 的特权级**下执行的程序调用
|
||
|
||
> 记忆口诀:**数据访问"低 → 高受限";代码调用"高 → 低受限"**。即数据访问要求调用者特权级不低于数据段 DPL;调用代码段则反过来要求调用者特权级不高于目标段 DPL。
|
||
|
||
#### 2. 数据段访问及其特权级检查
|
||
|
||
数据段访问流程(图 5.3.2):
|
||
1. 选择符装入数据段寄存器 DS,同时触发取描述符(从 GDT 或 LDT 装入 DS 的不可见部分)
|
||
2. 进行:段是否存在、段类型、特权级等检查
|
||
3. 特权级要求:
|
||
- **数据段**:`DPL ≥ MAX(CPL, RPL)` (数据段"保护"自己,不让低特权级访问)
|
||
- **堆栈段**:`CPL = RPL = DPL` (堆栈特权级三者必须完全一致)
|
||
4. 对于不改变段的存储器数据访问,直接从 DS 不可见部分取段基址
|
||
5. 与偏移量相加形成线性地址
|
||
6. 段限检查:偏移不能超过段限
|
||
|
||
#### 3. 任务内的段间转移及其特权级检查
|
||
|
||
**控制转移分类树(图示)**:
|
||
|
||
```
|
||
转移
|
||
├── 任务内转移
|
||
│ ├── 段内 (NEAR)
|
||
│ └── 段间 (FAR)
|
||
│ ├── 同一特权级:直接转移,用段描述符(JMP/CALL/RET/IRET)
|
||
│ └── 不同特权级:间接转移,用调用门(调用),中断门/陷阱门(中断)
|
||
└── 任务间切换
|
||
├── 直接:用 TSS 描述符
|
||
└── 间接:用任务门
|
||
```
|
||
|
||
**任务内段间控制转移的描述符访问规则(表 5.3.1)**:
|
||
|
||
| 控制转移类型 | 操作类型 | 引用的描述符 | 涉及的描述符表 |
|
||
|---|---|---|---|
|
||
| 同一个特权级 | JMP、CALL、RET、IRET | 代码段 | GDT / LDT |
|
||
| 同一个特权级 | CALL | 调用门 | GDT / LDT |
|
||
| 或转移到更高特权级 | 中断指令、异常、外部中断 | 陷阱门、中断门 | IDT |
|
||
| 转移到较低特权级 | RET、IRET | 代码段 | GDT / LDT |
|
||
|
||
> 注:使用 IRET 控制转移时,需嵌套任务位 NT=0。
|
||
|
||
**(1) 段间直接转移的操作过程**:
|
||
- 送入 CS 的是代码段选择符 → 触发段间直接转移
|
||
- 操作过程类似访问数据段
|
||
- 保护检查:段是否存在、段类型、特权级、段限
|
||
- 特权级:
|
||
- `CPL = DPL`,或
|
||
- `CPL > DPL`,且目标段描述符 **C 位 = 1**(一致性代码段)→ 在 CPL 级上执行目标段
|
||
|
||
**(2) 段间间接转移(使用调用门)**:
|
||
- 当送入 CS 的选择符选择了调用门描述符,触发段间间接转移
|
||
- **调用门按数据段保护**:调用门的特权级 DPL 必须满足数据段的规则
|
||
- **目标地址的段选择符装入 CS**,触发类似段间直接转移
|
||
- **目标段按代码段保护**
|
||
|
||
### 1.8 分页存储管理(重点/难点)
|
||
|
||
#### 1. 分页基本思想
|
||
|
||
- 分页:将程序分成若干个**大小相同(4 KB)**的连续区域(页)
|
||
- **段长可变,页长固定**
|
||
- 缺点:每次分配最少 1 页,即使所需容量小于 1 页
|
||
|
||
#### 2. 两级页表结构(Pentium 二级页表)
|
||
|
||
```
|
||
线性地址 (32 位)
|
||
──────────────────────────────────────────────────
|
||
页目录索引 DIR 页表索引 PAGE 页内偏移 OFFSET
|
||
10 位 10 位 12 位
|
||
(A31~A22) (A21~A12) (A11~A0)
|
||
```
|
||
|
||
**两级页表的层次结构**:
|
||
|
||
```
|
||
CR3 ────► 页目录(一级页表)
|
||
├── 页目录项 0 ─► 页表 0 ────► 物理页 0(4KB)
|
||
├── 页目录项 1 ─► 页表 1 ────► 物理页 1(4KB)
|
||
├── ...
|
||
└── 页目录项 1023 ─► 页表 1023 ─► 物理页 1023(4KB)
|
||
```
|
||
|
||
每个页目录 / 页表含 **1024 项**,每项 **4 字节**,故一个页目录 / 页表占 **4 KB**。
|
||
|
||
#### 3. 页目录与页表项格式
|
||
|
||
**(1) 页目录项(4 字节)**
|
||
|
||
| D31 ~ D12 | D11 ~ D10 | D9 | D8 ~ D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||
|---|---|---|---|---|---|---|---|---|---|---|
|
||
| 页表基址(20 位) | AV(2) | 0 | L | A | PCD | PWT | U/S | R/W | P |
|
||
| | 系统保留 | | | 访问 | Cache 禁止 | 写直达 | 用户/系统 | 读/写 | 存在 |
|
||
|
||
**(2) 页表项(4 字节)**
|
||
|
||
| D31 ~ D12 | D11 ~ D10 | D9 | D8 ~ D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|
||
|---|---|---|---|---|---|---|---|---|---|---|
|
||
| 页面基址(20 位) | AV(2) | 0 | L | D | A | PCD | PWT | U/S | R/W | P |
|
||
| | 系统保留 | | | 修改 | 访问 | Cache 禁止 | 写直达 | 用户/系统 | 读/写 | 存在 |
|
||
|
||
主要字段:
|
||
- **基址 20 位**:页表 / 页面的物理起始地址(4 KB 对齐)
|
||
- **P(存在位)**:P=1 存在,P=0 不存在
|
||
- **R/W(读/写)**:R/W=0 只读;R/W=1 可写
|
||
- **U/S(用户/系统)**:U/S=0 系统级;U/S=1 用户级
|
||
- **A(访问位)**:访问过置 1
|
||
- **D(修改位)**:写过置 1(脏位)
|
||
|
||
#### 4. 分页转换机制(详细步骤)
|
||
|
||
分页通过查表实现 **32 位线性地址 → 32 位物理地址** 的转换。具体步骤(参考图 5.5.3):
|
||
|
||
1. **第 1 步**:4 KB 长的页目录存储在 CR3 寄存器所指物理地址("根地址"),该地址是 4 K 的倍数
|
||
2. **第 2 步**:取线性地址的最高 10 位(A31~A22),作为页目录索引:
|
||
- 实际地址 = CR3 中页目录基址 + DIR × 4
|
||
- 读出对应 **页目录项**(4 字节),得到下一级页表的基址
|
||
3. **第 3 步**:取线性地址的中间 10 位(A21~A12),作为页表索引:
|
||
- 实际地址 = 页表基址 + PAGE × 4
|
||
- 读出对应 **页表项**(4 字节),得到物理页的基址(4 KB 的倍数)
|
||
4. **第 4 步**:取线性地址的低 12 位(A11~A0)作为 **页内偏移**:
|
||
- 物理地址 = 物理页基址 + OFFSET
|
||
|
||
**转换算法**:
|
||
|
||
```
|
||
DIR = linear_addr[31:22]
|
||
PAGE = linear_addr[21:12]
|
||
OFFSET = linear_addr[11:0]
|
||
|
||
页目录项地址 = CR3 + DIR × 4
|
||
页表基址 = (页目录项 & 0xFFFFF000) // 取高 20 位
|
||
页表项地址 = 页表基址 + PAGE × 4
|
||
物理页基址 = (页表项 & 0xFFFFF000) // 取高 20 位
|
||
物理地址 = 物理页基址 | OFFSET // 低 12 位 = OFFSET
|
||
```
|
||
|
||
#### 5. TLB(转换旁视缓冲)
|
||
|
||
- **TLB**:缓存"线性地址(高 20 位)"与"物理页基址"的对应关系
|
||
- 目的:提高地址转换效率,避免每次都查两级页表
|
||
- 转换时,用线性地址高 20 位作关键字查 TLB:命中 → 直接得到物理页基址;不命中 → 查两级页表
|
||
|
||
#### 6. 页保护
|
||
|
||
- 通过页表项中的 **R/W** 和 **U/S** 位实现
|
||
- **R/W**:R/W=0 只读;R/W=1 可写
|
||
- **U/S**:U/S=0 系统特权级(0、1、2)可访问;U/S=1 用户特权级(3)也可访问
|
||
- 与 CPL(当前特权级)配合:
|
||
- 0/1/2 级程序访问 U/S=0 的页 → 允许
|
||
- 任何级程序访问 U/S=1 的页 → 允许
|
||
- 0/1/2 级程序访问 U/S=1 的页做写且 R/W=0 → 禁止
|
||
- 3 级程序访问 U/S=0 的页 → 禁止
|
||
|
||
### 1.9 段页式存储管理的寻址过程(图 5.6.1,综合性最强)
|
||
|
||
**完整转换流程**:
|
||
|
||
```
|
||
虚拟地址 (48 位)
|
||
│
|
||
│ 16 位段选择符 + 32 位偏移量
|
||
▼
|
||
【分段阶段】
|
||
段选择符 ──► 段描述符表(GDT/LDT)──► 32 位段基址 ──┐
|
||
│
|
||
32 位偏移量 ─────────────────────────────────────►(+)───► 32 位线性地址
|
||
▼
|
||
【分页阶段】
|
||
32 位线性地址 = DIR(10) + PAGE(10) + OFFSET(12)
|
||
│
|
||
▼
|
||
CR3 ──► 页目录 ──► 页表 ──► 物理页 ──► 物理地址
|
||
[DIR][PAGE]
|
||
索引 ×4 索引 ×4
|
||
+ OFFSET
|
||
▼
|
||
32 位物理地址 ──► 主存
|
||
```
|
||
|
||
**Pentium 三种存储管理模式的特点**:
|
||
|
||
| 模式 | 特点 |
|
||
|---|---|
|
||
| 分段不分页 | 二维虚地址 → 32 位线性地址 = 物理地址 |
|
||
| 分段分页 | 由分段部件和分页部件共同管理(最常用) |
|
||
| 不分段分页 | 程序不提供段选择符,只用 32 位有效地址(直接作为线性地址) |
|
||
|
||
---
|
||
|
||
## 二、考点总结(期末复习必看)
|
||
|
||
### A. 高频考点(一定要掌握)
|
||
|
||
- 【高频】 **实模式 vs 保护模式的区别**
|
||
- 实模式:段寄存器内容即基址(左移 4 位),地址线 20 位,最大 1 MB,固定 64 KB 段,无保护
|
||
- 保护模式:段选择符 + 段描述符(8 字节),32 位偏移,最大 4 GB 段,4 级特权,多重保护
|
||
|
||
- 【高频】 **段选择符 16 位结构:INDEX(13) + TI(1) + RPL(2)**
|
||
- TI=0 选 GDT;TI=1 选 LDT
|
||
- RPL 表示请求特权级,不参与寻址
|
||
- INDEX × 8 = 相对描述符表首地址的偏移
|
||
|
||
- 【高频】 **段描述符 8 字节结构:基址 32 位 + 限长 20 位 + 属性(G/D/B/AVL/P/DPL/S/TYPE)**
|
||
- 32 位基址分布在第 2、3、4、7 字节;20 位限长分布在第 0、1、6 字节高 4 位
|
||
- G=0 单位字节;G=1 单位 4 KB
|
||
|
||
- 【高频】 **GDT vs LDT 区别**
|
||
- GDT:整个系统唯一,含除中断门/陷阱门外的所有描述符;由 GDTR 直接指向
|
||
- LDT:每个任务一个,含代码/数据/堆栈/任务门/调用门,但**不含 TSS/LDT/中断门/陷阱门**;由 LDTR 中的选择符指向 GDT 中的 LDT 描述符来找到
|
||
|
||
- 【高频】 **分页机制两级页表结构**
|
||
- 页目录 1024 项 × 4B = 4 KB,由 CR3 指向
|
||
- 页表 1024 项 × 4B = 4 KB
|
||
- 每页 4 KB
|
||
- 总可寻址空间 = 1024 × 1024 × 4 KB = **4 GB**
|
||
|
||
- 【高频】 **线性地址 → 物理地址转换步骤**
|
||
- DIR(A31~A22,10 位) → 页目录索引
|
||
- PAGE(A21~A12,10 位) → 页表索引
|
||
- OFFSET(A11~A0,12 位) → 页内偏移
|
||
- 公式:物理地址 = (页目录项[DIR]→页表基址 + PAGE×4 → 页表项基址) & 0xFFFFF000 | OFFSET
|
||
|
||
- 【高频】 **虚拟地址、线性地址、物理地址三者关系**
|
||
- 虚拟地址(48 位 = 16 位选择符 + 32 位偏移) —[分段]→ 线性地址(32 位)—[分页]→ 物理地址(32 位)
|
||
- 不分页时:线性地址 = 物理地址
|
||
|
||
- 【高频】 **特权级划分与保护规则**
|
||
- 4 级:0(最高,内核)→ 1 → 2 → 3(最低,用户)
|
||
- CPL(当前特权级)= CS 低 2 位
|
||
- DPL(描述符特权级)= 描述符字段
|
||
- RPL(请求特权级)= 段选择符低 2 位
|
||
- 规则 1:数据段 `DPL ≥ MAX(CPL, RPL)`
|
||
- 规则 2:堆栈段 `CPL = RPL = DPL`
|
||
- 规则 3:代码段 `CPL = DPL`,或 `CPL > DPL` 且 C 位 = 1(一致性代码段)
|
||
- 控制转移特权规则:特权高的段能访问特权低的数据;调用特权低的代码段需通过调用门
|
||
|
||
### B. 其他常考要点
|
||
|
||
- **Pentium 支持的 3 种存储管理**:段式、页式、段页式
|
||
- **段描述符分类**:程序段描述符(代码/堆栈/数据)、系统段描述符(TSS/LDT/门);门又分调用门/任务门/中断门/陷阱门
|
||
- **门描述符**:含 16 位选择符、32 位偏移、P/DPL/S/TYPE/字计数
|
||
- **TSS**:保存任务切换所需的全部寄存器状态,由 TR 寻址
|
||
- **IDT 寻址**:中断类型码 × 8 + IDTR 基址
|
||
- **GDT 寻址**:INDEX × 8 + GDTR 基址
|
||
- **TSS 入口**:TR 选择符 → GDT 中的 TSS 描述符 → 得到 TSS 基址
|
||
- **Pentium 段段最大长度**:G=0 时 1 MB;G=1 时 4 GB
|
||
- **Pentium 段空间**:可寻址 64 TB 虚拟空间(48 位指针)
|
||
- **CR3 必须为 4 K 倍数**:因页目录按页对齐
|
||
- **段属性保护检查**:段存在性、段类型、段限、特权级
|
||
- **保护机制 3 类**:任务间存储保护、段属性界限界限保护、特权级保护
|
||
- **任务内段间控制转移**:同特权级 JMP/CALL/RET/IRET + 代码段;同或更高特权级 CALL + 调用门;中断/异常 → 陷阱门/中断门;较低特权级 RET/IRET
|
||
- **任务间切换**:直接用 TSS 描述符;间接用任务门
|
||
|
||
### C. 常见题型
|
||
|
||
#### 1. 计算 / 分析题(数值题)
|
||
|
||
- **给定段选择子求段描述符位置**
|
||
- 例:选择子 = `0023H`(即 0000 0000 0010 0011 B),INDEX = 0000 0000 0100 = 4,TI = 0,RPL = 3
|
||
- 段描述符地址 = GDTR 基址 + 4 × 8 = GDTR 基址 + 32
|
||
- 属于 GDT(TI=0)
|
||
|
||
- **给定 GDTR 内容求选择子对应的描述符**
|
||
- 设 GDTR 基址 = 1000_0000H,限长 = 0FFFH(最多 2048 项描述符)
|
||
- 选择子 = 0050H → INDEX = 010 0000B = 32 → 描述符地址 = 1000_0000H + 32×8 = 1000_0100H
|
||
|
||
- **给定线性地址求物理地址**
|
||
- 例:线性地址 = 00C02098H
|
||
- DIR = 0000 0000 11 = 3
|
||
- PAGE = 0000 0000 10 = 2
|
||
- OFFSET = 0000 1001 1000 = 098H
|
||
- 假设 CR3 = 0023_0000H,页目录项 [3] = 0101_0003H(含 PCD/PWT/U/S/RW/P),有效基址 = 0101_0000H
|
||
- 页表基址 = 0101_0000H
|
||
- 页表项 [2] = 0016_0005H(页面 2),有效基址 = 0016_0000H
|
||
- 物理地址 = 0016_0000H + 098H = 0016_0098H
|
||
|
||
- **特权级判定**
|
||
- 若 CPL=3,DPL=2,访问数据段 → DPL(=2) ≥ MAX(CPL,RPL=3)=3?否,禁止
|
||
- 若 CPL=0,DPL=2,访问数据段 → 2≥MAX(0,0)=0,允许
|
||
|
||
#### 2. 简答题
|
||
|
||
- **简述分页机制的优点 / 缺点**
|
||
- 优点:① 页大小固定,便于管理;② 实现虚拟存储器,提高主存利用率;③ 支持内存保护(R/W、U/S);④ 便于共享
|
||
- 缺点:① 每次分配至少 1 页,存在内部碎片;② 需要两级页表,访存两次(TLB 缓解);③ 地址转换开销大
|
||
|
||
- **保护模式的主要特点**
|
||
- ① 32 位地址空间,段最大 4 GB
|
||
- ② 通过描述符实现段的基址、限长、属性管理
|
||
- ③ 4 级特权级保护
|
||
- ④ 支持分页机制,可实现虚拟存储器
|
||
- ⑤ 支持多任务切换(TSS)
|
||
- ⑥ 通过门机制实现受控的特权级转移
|
||
|
||
- **特权级的意义**
|
||
- 实现资源的分层保护
|
||
- 内核(0 级)独占关键资源,用户程序(3 级)受限访问
|
||
- 通过 CPL/DPL/RPL 三层特权共同控制访问授权
|
||
|
||
- **GDT/LDT/IDT 各自的作用与区别**
|
||
- GDT:全局描述符表,整个系统一个,存所有公共描述符
|
||
- LDT:局部描述符表,每个任务一个,存本任务私有描述符
|
||
- IDT:中断描述符表,整个系统一个,存中断/陷阱/任务门描述符
|
||
|
||
- **段式、页式、段页式存储管理的比较**
|
||
- 段式:按逻辑分段,长度可变,易于共享,但碎片大
|
||
- 页式:固定大小,无外部碎片,但分配至少 1 页
|
||
- 段页式:兼具两者优点(先分段再分页),是 Pentium 的主流方案
|
||
|
||
---
|
||
|
||
## 三、本章知识结构图(速记版)
|
||
|
||
```
|
||
第5章 保护模式存储管理
|
||
├── 5.1 虚拟存储器
|
||
│ ├── 定义、目标
|
||
│ ├── 3 种地址空间(虚地址/主存/辅存)
|
||
│ └── 工作原理(分段+分页部件)
|
||
├── 5.2 分段存储管理
|
||
│ ├── 5.2.1 基本思想、虚拟地址构成(16+32)
|
||
│ ├── 5.2.2 段描述符(程序段、系统段、门)
|
||
│ │ └── 8 字节格式:基址32+限长20+属性
|
||
│ ├── 5.2.3 GDT + GDTR(48 位 = 32+16)
|
||
│ ├── 5.2.4 LDT + LDTR
|
||
│ ├── 5.2.5 IDT + IDTR
|
||
│ ├── 5.2.6 TSS + TR
|
||
│ └── 5.2.7 段选择符(INDEX13+TI1+RPL2)
|
||
├── 5.3 保护机制与访问操作
|
||
│ ├── 任务间存储保护(LDT 隔离)
|
||
│ ├── 段属性/界限保护
|
||
│ ├── 特权级保护(CPL/DPL/RPL)
|
||
│ ├── 数据段访问检查
|
||
│ └── 段间转移检查(JMP/CALL/中断门/陷阱门)
|
||
├── 5.5 分页存储管理
|
||
│ ├── 两级页表(CR3 → 页目录 → 页表 → 物理页)
|
||
│ ├── 线性地址 = DIR(10)+PAGE(10)+OFFSET(12)
|
||
│ ├── 转换 4 步法
|
||
│ ├── TLB(转换旁视缓冲)
|
||
│ └── 页保护(R/W、U/S)
|
||
└── 5.6 段页式存储管理
|
||
├── 三种工作模式:分段不分页 / 分段分页 / 不分段分页
|
||
└── 完整寻址流程:虚地址→[分段]→线性→[分页]→物理
|
||
```
|
||
|
||
---
|
||
|
||
## 四、易混淆点对比表
|
||
|
||
| 对比项 | 关键区别 |
|
||
|---|---|
|
||
| GDT vs LDT | 系统唯一 vs 每任务一个;GDT 不含 IDT,LDT 不含 TSS/LDT/IDT |
|
||
| CPL vs DPL vs RPL | CPL 是当前代码段的特权级;DPL 是被访问段固有的;RPL 是请求者的 |
|
||
| 段基址 vs 物理页基址 | 段基址 32 位任意值;物理页基址 20 位(4 KB 对齐) |
|
||
| 数据段访问 vs 代码段调用 | 数据访问:低 → 高受限;代码调用:高 → 低受限 |
|
||
| IDT 中门 vs GDT/LDT 中门 | IDT 中的门用于中断/异常;GDT/LDT 中的门用于任务内调用 |
|
||
| 段描述符 vs 门描述符 | 段描述符描述一个段;门描述符描述一个跳转入口(含目标地址) |
|
||
| TSS vs GDT/LDT | TSS 是任务状态段(程序可见);GDT/LDT 是描述符表 |
|
||
| TLB 命中 vs 不命中 | 命中:1 次访问得物理页;不命中:查两级页表(2 次额外访问) |
|
||
|
||
---
|
||
|
||
> **复习建议**:本章是《微机系统》期末考试的核心难点,重点复习**段选择符结构、段描述符结构、GDT/LDT 区别、线性地址到物理地址的两级页表转换、特权级检查规则、段式/页式/段页式三种存储管理方式**。建议配套做 3~5 道综合题(含地址转换、特权级判定),效果最好。
|
||
|
||
---
|
||
|
||
(文件结束)
|