Appearance
虚拟存储器(硬件视角)
考情分析
虚存的硬件机制在组成原理和操作系统中都有考查,408 大题常以虚实地址转换结合 Cache 的形式出现,是跨章节综合题的重点。
大纲定位
考纲第三章(七)「虚拟存储器」四条:
- 虚拟存储器的基本概念
- 页式虚拟存储器 —— 注明「基本原理,页表,地址转换,TLB(快表)」
- 段式虚拟存储器的基本原理
- 段页式虚拟存储器的基本原理
注意深度差:第 2 条大纲给了四个子项,第 3、4 条只有「基本原理」四个字、没有任何子项。所以页式要学到能算,段式/段页式知道结构和翻译步骤即可。
术语先对齐
真题卷面用的是实页号(也叫页框号),不是「物理帧号」。本文两种说法都给,做题时按题面走:
| 本文写法 | 真题常见写法 | 含义 |
|---|---|---|
| 虚页号 VPN | 虚页号 | 虚拟地址的高位段 |
| 实页号 PFN | 实页号 / 页框号 | 物理地址的高位段 |
| 页内偏移 offset | 页内地址 | 低位段,翻译前后不变 |
虚拟地址与物理地址
程序使用虚拟地址(逻辑地址),硬件将其翻译为物理地址后才能访问主存。
虚拟地址结构(分页机制):
页大小
卷面要写位区间。给分点常要求答成
编者注(易错):翻译只换高位段,offset 位数与取值都不变。所以物理地址位数
实页号位数 offset 位数,实页号位数由物理地址位数决定,与虚地址位数无关——两者可以不等。
页表
页表存储在主存中,由操作系统管理。每个进程有一张页表。

图 7.40 主存中的页表示例
图中页表项含装入位、修改位、使用位、访问权限位、禁止缓存位、存放位置。装入位 = 0 的虚页(VP0、VP3、VP4、VP6)在磁盘上,= 1 的(VP1、VP2、VP5、VP7)才在主存里。
页表项(PTE)主要字段:
| 字段 | 别名 | 说明 |
|---|---|---|
| 实页号 | 物理帧号 PFN、页框号 | 对应的主存页框 |
| 有效位 | 装入位、Present | 该页是否在主存中 |
| 脏位 | 修改位、Dirty | 该页是否被修改(换出时决定要不要写回磁盘) |
| 访问位 | 使用位、Referenced | 最近是否被访问(用于页面替换) |
| 保护位 | 访问权限位 | 读/写/执行权限 |
翻译过程:

图 7.42 分页式虚存的地址转换
图中四步:① 页表基址寄存器给出页表首址 → ② 虚页号作下标定位到页表项 → ③ 取出实页号 → ④ 与页内地址拼接成物理地址。
这里的
谁来检查这些控制位
这一问真题直接考过。地址翻译由 MMU(Memory Management Unit,存储管理部件,含 TLB)完成:
| 检查项 | 由谁检查 | 违反后果 |
|---|---|---|
| 有效位 = 0 | MMU | 触发缺页异常,转 OS 处理 |
| 保护位不符 | MMU | 触发访问越权异常 |
| Cache 是否命中 | Cache 控制器 | 在 MMU 交出物理地址之后才登场 |
顺序是固定的:MMU 先把虚地址翻成物理地址(这期间可能触发 TLB 缺失、缺页、越权),拿到物理地址后 Cache 才开始查。
缺页之后会发生什么
缺页是异常(exception),不是中断——它是同步的,与当前这条指令绑定,习惯上也被称作「缺页中断」,但判断题里要按异常算。
关键的一条:缺页处理完毕后,返回点是引发缺页的那条指令本身,该指令被重新执行一遍。
这条不只是概念题。它有可计数的后果:同一次访存因为重做,TLB 会被查两次——统计访问次数的大题里漏掉这一次就会差 1。
编者注(易错):别把「缺页由 OS 处理」当成「这是操作系统的考点、组成原理不考」。缺页的触发机制、返回点、重新执行带来的计数变化都在组成原理卷面上出现过。
多级页表
32 位地址空间,4 KB 页,单级页表需要
两级页表:把 VPN 再切成两段——高段作页目录索引,低段作页表索引:
翻译要走两跳:页目录基址寄存器 → 页目录项(给出该页表的基址)→ 页表项(给出实页号)。所以TLB 缺失时,两级页表要访问 2 次主存才拿到实页号,再加 1 次取数据。
64 位系统通常用 4 级页表(x86-64 的四级依次是页全局目录、页上级目录、页中间目录、页表,常写作 PML4 / PDPT / PD / PT)。
TLB(快表)
问题:每次地址翻译都要访问主存中的页表,一次访存变成"一次翻译 + 一次取数",效率低下。
TLB(Translation Lookaside Buffer,快表/地址翻译缓存):页表的 Cache,存放最近使用的页表项,容量小(64~1024 项),速度极快(SRAM)。
TLB 的映射方式:全相联或组相联
TLB 项数少,常采用全相联,查找时并行比较所有项的标记。但组相联的 TLB 也考过,别把"TLB 一定是全相联"当结论。
组相联 TLB 的字段切法与 Cache 完全同构,只是被切的对象是虚页号而不是整个地址:
其中 TLB 组数
编者注(易错):TLB 组号取的是虚页号的低位,不是虚拟地址的低位。虚拟地址的低位是页内偏移,与 TLB 无关。
举例:虚地址 30 位、页大小 4 KB、TLB 共 16 项 2 路组相联。
- offset
VA ,VPN VA (18 位) - TLB 组数
→ TLB 组号 3 位 VA - TLB 标记
位 VA
TLB 表项里有什么
和页表项不完全一样——TLB 是"带标记的页表项副本":
| 字段 | 宽度由谁决定 |
|---|---|
| TLB 标记 | 虚地址位数(VPN 位数减去组号位数) |
| 实页号 | 物理地址位数 |
| 有效位 / 脏位 / 替换算法位 | 与地址位数无关 |
所以真题问"虚地址加宽 2 位,TLB 每项增加几位"时,答案是只有标记 +2 位,实页号和控制位都不变。
TLB 也要替换
TLB 装满后再来新项就要替换,常用 LRU。命中时也要更新最近使用顺序——这一点漏掉,后面该换谁就会判错。
地址翻译流程(含 TLB)
虚拟地址
↓
查 TLB(极快)
↓
TLB 命中?
是(TLB Hit)→ 直接得到物理地址
否(TLB Miss)→ 查主存页表
↓
装入位 = 1?
是 → 得到物理地址 → 更新 TLB
否 → 缺页异常 → OS 调页 → 重新执行本指令
↓
用物理地址访问数据
↓
查 Cache
↓
Cache 命中?
是 → 从 Cache 返回数据
否 → 访问主存,装入 Cache完整的 TLB + 页表 + Cache 联合访问

图 7.43 TLB 和 cache 的访问过程
这张图把三级画全了:上半部主存中的页目录与页表,中间 TLB(虚页号切成标记 + 组索引,两路并行比较后经 MUX 输出实页号),下半部 Cache(物理地址切成标记 + 组索引 + 块内地址)。注意页内地址那 12 位从头到尾没进 TLB,直接旁路到物理地址的低位。
八种组合,三种不可能
只列 TLB × Cache 两维是不够的,页表命中与否是独立的第三维:
| TLB | Page(页表) | Cache | 可能? | 说明 |
|---|---|---|---|---|
| Hit | Hit | Hit | ✓ | 最快 |
| Hit | Hit | Miss | ✓ | 访存取数据 |
| Hit | Miss | Hit | ✗ | TLB 项是页表项的副本,命中即说明页在主存 |
| Hit | Miss | Miss | ✗ | 同上 |
| Miss | Hit | Hit | ✓ | 查页表得地址,数据恰在 Cache |
| Miss | Hit | Miss | ✓ | 查页表 + 访存 |
| Miss | Miss | Hit | ✗ | 页都不在主存,其内容不可能在 Cache |
| Miss | Miss | Miss | ✓ | 缺页,最慢 |
两条判据记住就够:
- TLB 命中 ⇒ 页必在主存(所以 TLB hit + Page miss 不可能)。反过来,OS 把某页换出时必须同步让对应的 TLB 项失效,否则这条判据就被破坏了。
- 页不在主存 ⇒ Cache 不可能命中(Cache 缓存的是主存内容)。
交互可视化
段式虚拟存储器
页式是把地址空间等分成固定大小的页;段式是按程序的逻辑结构分成长度不等的段(代码段、数据段、栈段……)。
虚拟地址是二维的:

图 7.45 分段式虚存的地址转换
翻译过程:段表基址寄存器 → 加上段号定位到段表项 → 取出段首址,与段内地址相加得到物理地址。
段表项的关键字段:
| 字段 | 作用 |
|---|---|
| 段首址(段基址) | 该段在主存中的起始地址 |
| 段长 | 该段的长度 |
| 装入位 | 该段是否已调入主存 |
段长是段式相对页式在硬件上的唯一实质增量:因为段是变长的,必须检查「段内地址
还有一处和页式不同:物理地址是段首址
段页式虚拟存储器
先分段、段内再分页,虚拟地址是三段:
翻译要走两张表:
- 用段号查段表,取出的是该段页表的基址(注意:不是段基址)
- 用段内页号查该段的页表,取出实页号
- 实页号与页内偏移拼接成物理地址
所以无 TLB 时,一次访存要 3 次主存访问:查段表 1 次 + 查页表 1 次 + 取数据 1 次。
编者注(易错):段页式常见的干扰项是"只需一次访存"。段表项存的是页表基址而不是最终地址,两级表必须都查。
三者对比
| 页式 | 段式 | 段页式 | |
|---|---|---|---|
| 划分依据 | 等长,硬件定 | 变长,程序逻辑定 | 先段后页 |
| 虚地址切几段 | 2 | 2 | 3 |
| 表项关键字段 | 实页号 | 段首址 | 段表存页表基址;页表存实页号 |
| 地址合成 | 拼接 | 相加(需越界检查) | 拼接 |
| 无 TLB 时访存次数 | 2 | 2 | 3 |
| 对程序员 | 透明(页号不可见) | 不透明(段号是程序结构的一部分) | 段不透明、页透明 |
| 碎片 | 内碎片 | 外碎片 | 内碎片 |
段的共享与保护策略、外碎片紧凑、页置换算法属于操作系统部分的内容,这里不展开。
地址翻译计算例题
题:32 位虚拟地址,页大小 4 KB,物理地址 24 位。虚拟地址 0x00082840,页表内容如下(装入位 = 1 才有效):
| 虚页号(十进制) | 装入位 | 实页号 |
|---|---|---|
| 128 | 1 | 0x00A |
| 129 | 0 | —— |
| 130 | 1 | 0x018 |
| 131 | 1 | 0x0C3 |
解:
Step 1. 定各字段位数与位区间。 页大小 4 KB
- offset
VA - VPN
位 VA - 实页号
位
Step 2. 切出字段的值。
Step 3. 把 VPN 换成十进制再查表。
查页表第 130 项(不是第 82 项),装入位 = 1,实页号 0x018。
编者注(易错):页表的虚页号列通常按十进制编号,而地址是十六进制。必须先换算再查表——直接拿
0x82当行号去查是这类题最常见的失分点。
Step 4. 拼接成物理地址。
算术验算:
解题动作清单
地址翻译题的固定起手式,五步走:
- 由页大小定 offset 位数:offset
(页大小),写成 - 由虚/物理地址位数分别定 VPN 和实页号位数——两者不必相等,各减各的 offset
- 写出位区间,别只写位数
- 若考 TLB:把 VPN(不是虚地址)再切成 TLB 标记
TLB 组号,组号位数 (项数 路数) - 若接 Cache:把物理地址切成 tag
index 块内偏移
若题目问访存次数,再叠一层:查表次数(一级页表 1、两级 2、段页式 2)
考点清单
- 虚拟地址
VPN offset,物理地址 实页号 offset,offset 位数与取值都不变 - 实页号位数由物理地址位数定,与虚地址位数无关,两者可不等
- TLB 是页表的 Cache,常用全相联,但组相联也考过;组号取虚页号的低位
- TLB 表项
标记 实页号 控制位;虚地址加宽只影响标记宽度 - TLB 命中
页必在主存;页不在主存 Cache 不可能命中 - 缺页是同步异常,处理完重新执行原指令(该次访存会查两遍 TLB)
- MMU 查有效位和保护位,Cache 控制器在物理地址产生后才登场
- 段式:段表项
段首址 段长,物理地址靠相加并需越界检查 - 段页式:三段切分,段表存页表基址,无 TLB 时访存 3 次
- 页表虚页号列是十进制、地址是十六进制,查表前先换算
教材出处
- 袁春风《计算机组成与系统结构(第 3 版)》§7.6 虚拟存储器:图 7.40(p256)、图 7.42(p259)、图 7.43(p260)、图 7.45(p263)