当前位置:首页 > 技术 > 正文内容

虚拟地址与物理地址的转换机制解析

访客 技术 2026年5月26日 4

程序如何访问内存?

在执行指令或读写数据时,CPU需要与内存交互。它会发出请求:"请将地址0x10000处的数据返回"或"将计算结果写入0x20000"。这些地址通常来自指令中的立即数或寄存器值。

早期单任务系统中,程序可在固定物理地址(如0x8000)加载运行,无需担心冲突。但随着多任务需求出现——多个程序轮流执行——直接使用物理地址的方式暴露出严重问题:

  • 地址冲突:不同程序可能使用相同内存区域,导致相互覆盖。
  • 内存不足:大型程序无法完全载入有限物理内存。
  • 可移植性差:程序需适配不同机器的内存布局。

解决方案:引入虚拟地址空间

现代操作系统为每个进程提供独立的虚拟地址空间。每个程序都"认为"自己独占从0开始的完整内存空间,而实际使用的物理内存由系统统一调度。这种逻辑上的地址称为虚拟地址(Virtual Address),它是抽象的、不真实存在的。

例如,通过objdump反汇编一个ELF可执行文件,可以看到类似输出:

0000000000401000 <main>:
  401000:   55                      push   %rbp
  401001:   48 89 e5                mov    %rsp,%rbp
  401004:   48 8d 3d fb 0f 00 00    lea    0xffb(%rip),%rdi
  40100b:   e8 d0 fe ff ff          callq  400ee0 <puts@plt>

左侧列即为虚拟地址。所有用户程序的代码段通常起始于高位虚拟地址(如0x400000),这是链接器在生成可执行文件时设定的。

物理地址的作用

物理地址(Physical Address)是最终用于寻址硬件存储单元的真实地址。它被送至地址总线,经译码电路选择目标设备,包括主内存、显存、I/O寄存器等。

虚拟到物理的转换机制

地址转换本质上是一个映射函数:PA = f(VA),其中VA为虚拟地址,PA为物理地址。若纯用软件实现效率低下;若全靠硬件则缺乏灵活性。因此采用软硬协同方案——MMU(Memory Management Unit)

MMU是集成在CPU中的专用硬件模块,其工作依赖于保护模式或长模式的启用。实模式下无法激活分页功能。

分页管理模型

现代系统普遍采用分页机制进行地址映射。将虚拟和物理内存划分为固定大小的块——称为"页",常见尺寸有4KB、2MB、1GB等。

映射关系由页表(Page Table)维护,记录虚拟页号到物理页帧号的对应。由于虚拟地址空间巨大,页表采用分级结构以节省空间:

  • 一级:页全局目录(PGD)
  • 二级:页上级目录(PUD)
  • 三级:页中间目录(PMD)
  • 四级:页表项(PTE)

每级索引若干比特位,逐层查找直至定位具体页框。

启用MMU的关键步骤

  1. 切换CPU至保护模式或64位长模式。
  2. 在物理内存中构建多级页表结构。
  3. 将根级页目录的物理地址写入控制寄存器CR3:
mov rax, 0x100000        ; 假设页目录位于物理地址1MB处
mov cr3, rax
  1. 设置CR0寄存器,开启分页模式:
mov rax, cr0
or  rax, 0x80000001     ; 设置PG(分页)和PE(保护模式)标志位
mov cr0, rax

地址转换失败的处理

并非所有虚拟地址都能成功映射。以下情况会导致页错误(Page Fault)

  • 访问未分配的虚拟页面
  • 试图修改只读页面
  • 权限越界(如用户态访问内核页)

当发生错误时,MMU会:

  1. 暂停当前指令执行;
  2. 将出错的虚拟地址存入CR2寄存器;
  3. 触发中断号14(#PF异常);
  4. CPU跳转至预设的异常处理程序。

操作系统内核负责分析CR2内容及错误类型,可能采取如下措施:

  • 分配新物理页并建立映射
  • 终止非法访问进程
  • 从磁盘加载缺页(支持虚拟内存)

进程间地址隔离原理

每个进程拥有独立的页表集。尽管两个进程可能使用相同的虚拟地址(如main函数都在0x401000),但经各自页表翻译后,指向不同的物理内存区域,从而实现地址空间隔离

同时,操作系统可通过共享某些页表项来实现进程通信(IPC),比如共享内存机制就是让多个进程的部分虚拟地址映射到同一物理页。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。