# 第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 道综合题(含地址转换、特权级判定),效果最好。 --- (文件结束)