我理解的物理地址、虚拟地址、逻辑地址

一. 物理地址

1. 基本概念

  1. 物理存储器(内存/主存/逻辑存储器):由微处理器外部地址总线寻址的存储器

    1. 这里的内存不特指计算机安装的内存条,而是指所有能被cpu直接寻址访问的存储器。包括内存条、显存和一些ROM
    2. 简单说:CPU把所有与cpu总线相连接并受其控制的的存储器,都看作一个统一的整体,对他们统一编址,这其中包括内存、显存、系统ROM等等,统称它们为存储器,存储器中按编址取一个字长的大小,就是一个存储单元。
  2. 物理地址物理存储器按8位的字节序列加以组织,每个字节有唯一的地址与之对应

  3. 物理地址空间物理地址的大小

    1. 物理地址是用外部地址总线寻址的,因此物理地址空间的上限受到总线条数限制,m条地址线对应的物理地址空间为2m2^m,物理地址范围0(2m1)0 到(2^m-1)
    2. 如果cpu工作在保护方式下,实际的物理地址空间除了地址线数量外,还受到系统配置的内存容量限制
    3. 物理地址空间大小不等于实际安装物理内存大小,它描述的是CPU的最大寻址能力

    我理解的物理地址、虚拟地址、逻辑地址

2. 说明

  1. 在CPU实模式下,没有分段或分页机制,Cpu不进行自动地址转换,这时程序员操作的就是物理地址
  2. 无论任何操作,最终都必须要得到物理地址才能在物理内存上进行操作。

二. 逻辑地址

后面会更详细地说明分段管理和逻辑地址,这里先简单引入一下

1. 基本概念

  1. 逻辑地址操作系统或应用程序面对的存储单元地址的表示形式。分段存储管理方式把内存划分为多个逻辑段(代码段、数据段、堆栈段等),从而把不同的数据存储隔离开。这种情况下,用 “段起始地址+段内偏移地址” 这种形式来描述数据地址就是很自然的,这就是所谓的逻辑地址,它的描述形式是段号:偏移地址
    1. 段号用来查找段的起始地址,它被存储在段寄存器中
      1. 实方式下,段号是段值
      2. 保护方式下,段号是段选择子
    2. 偏移地址/有效地址存储单元的物理地址与所在段起始地址的差值

2. 说明

  1. 逻辑地址是面向上层程序员的。用C语言声明一个char数组,我们说两个相邻元素间地址差1,这就是逻辑地址中偏移地址的体现。对于应用程序员或者说对于应用程序来说,他们只需要和逻辑地址打交道,分段分页机制、物理地址转换等更底层的内容对他们是透明的。
  2. 逻辑地址并不一定是元素存储的真实地址,即数组元素的物理地址(在内存条中所处的位置),并非是连续的,只是操作系统通过地址映射,将逻辑地址映射成连续的,这样更符合人们的直观思维
  3. 要注意的一点是,逻辑地址只是一个描述形式,cpu真正用来寻址的是虚拟地址,而虚拟地址是用逻辑地址形式描述的

三. 虚拟地址

1. 为什么有虚拟地址(个人理解)

  • 我们知道物理地址空间受限于地址线数目,但是逻辑地址的描述能力往往更强,可以描述的地址范围常会超过物理地址空间大小,这些多余的地址可以应用吗?如果只限于主存,当然不能,但是如果我们利用外部存储器(磁盘)的话情况就不同了。
  • 所谓虚拟存储器(虚拟内存),它由全部的主存和一部分磁盘空间组成。我们用虚拟地址指示虚拟内存的地址;用虚拟地址空间描述其尺寸,它的大小等于穷尽逻辑地址描述能力的空间大小,这往往比物理地址空间大许多。
  • 借助磁盘等辅助存储器来扩大主存容量,我们就可以编写内存需求更大的程序

2. 基本概念

  1. 虚拟存储器这不是任何实际的物理存储器,而是借助磁盘等辅助存储器来扩大主存容量,使之为更大或更多的程序所使用。
  2. 虚拟地址用于指示虚拟存储器的地址,它是用逻辑地址指示的
  3. 虚拟地址空间表示虚拟地址的范围,其大小为逻辑地址的描述能力极限大小

3. 说明

  1. 只有保护方式才支持虚拟地址,实方式是不支持的
  2. 前面说明过,在保护方式下的逻辑地址用段选择子指示段号,通常段选择子是16位的,其中14位表示地址信息,虚拟地址空间大小如下:
    我理解的物理地址、虚拟地址、逻辑地址
  3. 虽然虚拟地址空间很大,但用逻辑地址指示的一个虚拟地址取值仅限于物理地址空间,这还是由于cpu寻址能力的限制,一共就那么多地址线,你给他更大的地址根本输入不了啊。看到这里大家可能很奇怪,欸,不是说虚拟地址空间很大吗,这咋取值又局限在物理地址空间了?事实上,操作系统会给每个进程分配一块大小为物理地址空间大小的虚拟内存,各个进程之间相互独立,也就是说,甚至有可能两个进程同时请求访问了同一个虚拟地址。看起来会冲突?要知道CPU是通过时间片轮转的方法使不同的程序并发执行的,所以在某一时刻只有一个程序占据CPU资源。MMU(内存管理单元)负责把虚拟地址转换为物理地址,在每一个时刻,它会先在主存中寻找指定的数据,如果发现数据不对,就会触发内存缺页错误,这时就从磁盘中找到缺的页加入内存,如果内存空间不足,还会从内存中置换页出来,从而保证程序的正常执行。
    在别人的文章看到一个比喻挺有意思,搬过来

CPU只需要说找哪一个页面,MMU就将这个页面翻译成物理地址,再通过页面调度机制来讲不在内存中的页加入到内存中。我认为计算机使用的是一种各司其职的方法。CPU老大只需要虚拟地址中的一页,范围在0x00000000到0xFFFFFFFF,因为他的地址总线是32位,4G是他最大的能力,然后他就把任务分配给他的手下,CPU不需要知道他的手下是如何找到这一页,他只负责去要这一页和执行这些代码,然后他就和他的手下说“有招想去,没招死去”,他的手下必须要能找到这一页,然后内存非常有限,而CPU不管这个,只需要你能找到这一页让我执行就好,所以CPU的手下就将硬盘中的一部分当做内存,然后拿来骗CPU说,“这是我从内存中找到的”,然后CPU就去运行。如果访问的地方实在是不能找到,或者是没有权限,那么这个程序就真死了。程序员在开发的时候,因为程序员所编写的代码最终是要让CPU去执行,所以程序员也理所应当认为我有4G的内存空间,程序员把程序交给CPU,CPU就交给他手下。

四、小结

以下是我个人理解的几种地址之间的关系图,欢迎指正
我理解的物理地址、虚拟地址、逻辑地址