多图警告。
上一章空间管理的问题
- 大量的空闲(free)空间 -
- 这些空闲空间实实在在的占用了物理内存
- 必须为进程的整个虚拟地址空间分配 连续的物理内存 -
- 会导致什么问题?
一、“分段”地址转换
1. 基本原理
- 段是虚拟地址空间中的一个连续片段
- 代码段、栈段、堆段
- 对于每个段来说,都有它的基址和界限
- 只需以段为单位,给进程分配连续物理内存
- 物理地址 = 段基址 + 段内偏移 (段内偏移≠虚拟地址)
![https://cdn.jsdmirror.com/gh/Satori5ama/Figurebed@main/img/28.png)
![https://cdn.jsdmirror.com/gh/Satori5ama/Figurebed@main/img/29.png)
![https://cdn.jsdmirror.com/gh/Satori5ama/Figurebed@main/img/30.png)
- 粗粒度和细粒度的分段
- 粗粒度:只支持少量 段,如code、heap、 stack
- 细粒度:支持很多段, 需要硬件支持段表
- 如何判定非法内存访问?
- 硬件在地址转换时检查
- 如果超出了界限,则会报段错误 (segmentation fault)
- 陷入内核…
2. 段的表示:显式、隐式
(1) 显式方法:用虚拟地址的高位表示
![https://cdn.jsdmirror.com/gh/Satori5ama/Figurebed@main/img/31.png)
// get top 2 bits of 14-bit VA
Segment = (VirtualAddress & SEG_MASK) >> SEG_SHIFT
Offset = VirtualAddress & OFFSET_MASK
if (Offset >= Bounds[Segment])
RaiseException(PROTECTION_FAULT)
else
PhysAddr = Base[Segment] + Offset
//在CPU中将多组基址和界限放到寄存器数组中
(2) 隐式方法:不放在虚拟地址中
根据当前指令类型决定使用 哪个段寄存器

说些什么吧!