进程线程模型

操作系统分页存储计算:从地址位数到页表大小

分页存储管理是操作系统考试中非常常见的一类题目。公式虽然多,但核心只有三个问题:

  1. 一个地址对应多少字节?
  2. 一页包含多少个地址?
  3. 页号和页内偏移各占多少位?

只要分清“地址数”和“字节数”,大部分题目都可以直接解决。


一、先分清三个基本概念

1. 地址

地址是内存中某个可访问单元的编号。

一个 n 位二进制地址可以表示:

2^n 个不同地址

例如,32 位地址可以表示:

2^32 个地址

2. 编址单位

编址单位表示“一个地址对应多少字节”。

编址方式 一个地址对应的容量
按字节编址 1 字节
按半字编址 2 字节
按字编址 4 字节
按双字编址 8 字节

现代计算机通常按字节编址,但考试题可能明确规定:

每个地址可以访问 4 个字节。

这时一个地址对应 4 字节,计算总容量时必须乘以 4。

3. 页面与页框

分页系统将进程的虚拟地址空间划分为大小相等的“页面”,把物理内存划分为大小相等的“页框”。

虚拟地址空间:页 0、页 1、页 2……
物理内存:    页框 0、页框 1、页框 2……

页面和页框的大小相等,但页号与页框号一般不同,需要通过页表进行映射。


二、逻辑地址的基本结构

逻辑地址通常分成两部分:

┌──────────────────┬──────────────────┐
│       页号        │     页内偏移      │
└──────────────────┴──────────────────┘

假设:

  • 地址总长度为 n 位;
  • 页内偏移为 d 位。

那么:

页号位数 = n - d

页号用于确定访问哪个页面,页内偏移用于确定访问页面中的哪个位置。


三、分页计算的核心公式

设:

  • 地址总长度为 n 位;
  • 页内偏移为 d 位;
  • 每个地址对应 s 字节。

1. 地址总数

地址总数 = 2^n

2. 进程最大地址空间

最大地址空间 = 2^n × s 字节

如果按字节编址,即一个地址对应 1 字节:

最大地址空间 = 2^n 字节

3. 每页包含的地址数

每页地址数 = 2^d

4. 页面大小

页面大小 = 2^d × s 字节

5. 页号位数

页号位数 = n - d

6. 虚拟页面数量

页面数量 = 2^(n-d)

可以用下面的等式检查结果:

页面数量 × 页面大小
= 2^(n-d) × 2^d × s
= 2^n × s
= 进程最大地址空间

四、典型例题解析

采用页式存储管理,每个地址可以访问 4 字节。使用 32 位二进制地址,页内地址占 14 位,进程最大可以有多少字节?

已知:

地址位数 n = 32
偏移位数 d = 14
每地址字节数 s = 4 = 2^2

方法一:直接计算地址空间

32 位地址可以表示 2^32 个地址,每个地址对应 4 字节:

2^32 × 4
= 2^32 × 2^2
= 2^34 字节

所以答案是:

2^34 字节 = 16 GiB

方法二:先计算页面数量和页面大小

页号位数:

32 - 14 = 18 位

页面数量:

2^18 页

每页包含 2^14 个地址,每个地址对应 4 字节,因此页面大小为:

2^14 × 4
= 2^14 × 2^2
= 2^16 字节

进程最大地址空间:

2^18 × 2^16 = 2^34 字节

两种方法得到相同结果。


五、为什么容易误选 2^32?

因为大部分计算机采用按字节编址。看到“32 位地址”,很多人会下意识认为:

2^32 个地址 = 2^32 字节

但这个等式成立的前提是:

1 个地址 = 1 字节

本题明确规定:

1 个地址 = 4 字节

所以必须再乘以 4:

2^32 × 4 = 2^34 字节

记忆要点:

地址位数决定地址数量,编址单位决定一个地址包含多少字节。


六、已知页面大小,怎样计算偏移位数?

1. 按字节编址

如果页面大小是 2^k 字节,那么页内偏移就是 k 位:

偏移位数 = log2(页面大小)

例如,页面大小为 4 KiB:

4 KiB = 4096 字节 = 2^12 字节

所以页内偏移为 12 位。

2. 非字节编址

如果一个地址对应 s 字节,应先计算每页包含多少个地址:

每页地址数 = 页面字节数 ÷ s

然后计算:

偏移位数 = log2(每页地址数)

例如:

  • 页面大小为 64 KiB,即 2^16 字节;
  • 一个地址对应 4 字节,即 2^2 字节。

每页地址数为:

2^16 ÷ 2^2 = 2^14

所以页内偏移为 14 位,而不是 16 位。


七、页表大小怎么计算?

每个进程通常有自己的页表。每个页表项记录一个虚拟页面对应的物理页框等信息。

设:

  • 虚拟页面数量为 N;
  • 每个页表项大小为 e 字节。

页表大小为:

页表大小 = N × e

示例

已知:

  • 32 位虚拟地址;
  • 页面大小为 4 KiB;
  • 按字节编址;
  • 每个页表项为 4 字节。

页面大小为 2^12 字节,所以页内偏移为 12 位。

页号位数 = 32 - 12 = 20 位
虚拟页面数量 = 2^20
页表大小 = 2^20 × 4
           = 2^22 字节
           = 4 MiB

页表项通常不仅保存页框号,还可能包含:

  • 有效位;
  • 访问权限位;
  • 修改位;
  • 访问位;
  • 缓存控制位。

因此,题目如果明确给出页表项大小,应直接使用给定值。


八、逻辑地址如何转换为物理地址?

假设:

  • 每页包含 P 个地址单元;
  • 逻辑地址为 A。

页号和页内偏移分别为:

页号 = A ÷ P 的整数部分
页内偏移 = A mod P

操作系统通过页表找到对应的物理页框号 F,然后计算:

物理地址 = F × P + 页内偏移

示例

已知:

  • 页面大小为 1024 字节;
  • 按字节编址;
  • 逻辑地址为 2500;
  • 逻辑页 2 对应物理页框 5。

计算:

页号 = 2500 ÷ 1024 的整数部分 = 2
页内偏移 = 2500 mod 1024 = 452

物理地址:

5 × 1024 + 452 = 5572

地址转换过程中,页内偏移保持不变,只需要把虚拟页号替换为物理页框号。


九、页表、TLB 和缺页的区别

1. 页表

页表保存虚拟页到物理页框的映射:

虚拟页号 → 物理页框号

2. TLB

TLB 是页表项的高速缓存,用来加快地址转换。

没有 TLB 时,一次普通访存通常需要:

  1. 访问页表,找到物理页框号;
  2. 访问目标数据。

因此通常需要两次内存访问。TLB 命中时,可以直接获得页框号,减少一次页表访问。

3. TLB 未命中不等于缺页

  • TLB 未命中:TLB 中没有记录,但页表中可能存在;
  • 缺页:目标页面当前不在物理内存中,需要从外存调入。

两者关系如下:

TLB 未命中
    ↓
查询页表
    ↓
如果页表显示页面不在内存
    ↓
发生缺页中断

十、分页系统的碎片问题

分页系统通常不存在外部碎片,因为所有页框大小相同,任意空闲页框都能分配给页面。

但分页系统存在内部碎片。

例如,页面大小为 4 KiB,进程最后一页只使用了 1 KiB,那么剩余的 3 KiB 无法分配给其他进程,属于内部碎片。

一般情况下,最后一页平均浪费约半页空间:

平均内部碎片 ≈ 页面大小 ÷ 2

十一、考试中的常见陷阱

陷阱 1:把地址数直接当成字节数

只有按字节编址时,地址数才等于字节数。

总字节数 = 地址数 × 每地址字节数

陷阱 2:把页号位数当成页面数量

页号有 18 位,表示:

2^18 个页面

而不是 18 个页面。

陷阱 3:把偏移位数直接当成页面字节数

偏移为 14 位,只能说明每页有 2^14 个地址。

如果一个地址对应 4 字节,页面大小是:

2^14 × 4 = 2^16 字节

陷阱 4:混淆页面与页框

  • 页面属于虚拟地址空间;
  • 页框属于物理内存;
  • 页面和页框大小相等;
  • 页面数量与页框数量不一定相等。

陷阱 5:把 TLB 未命中当成缺页

TLB 中没有记录,不代表页面一定不在物理内存中。


十二、做题万能步骤

遇到分页计算题,可以按以下顺序处理:

  1. 判断一个地址对应多少字节;
  2. 找到地址总位数;
  3. 找到页内偏移位数;
  4. 计算页号位数;
  5. 计算页面数量;
  6. 计算页面大小;
  7. 根据题目要求计算地址空间、页表大小或物理地址。

最核心的三个公式是:

总容量 = 2^地址位数 × 编址单位

页面大小 = 2^偏移位数 × 编址单位

页面数量 = 2^(地址位数 - 偏移位数)

最后用下面的等式检查答案:

页面数量 × 页面大小 = 进程最大地址空间

只要等式两边一致,计算通常就没有问题。

posted @ 2026-07-29 17:15  ziziranran  阅读(4)  评论(0)    收藏  举报
下面这份是完整代码,已经把《失语者 - 蔡健雅》放在第一首,并把 `loop` 改成 `none`,这样播完第一首会继续切到后面的歌。 ```html
```