首页 > 代码库 > 内存管理中的三种地址

内存管理中的三种地址

一、逻辑地址(有时也称虚拟地址)
  逻辑地址(Logical Address) 是指由程序产生的与段相关的偏移地址部分。例如在C语言指针编程中,可以读取指针变量本身值(&操作)实际上这个值就是逻辑地址,它是相对于当前进程数据段的地址和绝对物理地址无关。
  只有在Intel处理器的实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,CPU不进行自动地址转换)。逻辑地址也就是在Intel 处理器的保护模式下,程序执行代码段限长内的偏移地址(假定代码段数据段完全样)。
  CPU启动保护模式后,程序运行在虚拟地址空间中。注意,并不是所有的“程序”都是运行在虚拟地址中。CPU在启动的时候是运行在实模式的,Bootloader以及内核在初始化页表之前并不使用虚拟地址,而是直接使用物理地址的。
  应用程序仅需与逻辑地址打交道而分段和分页机制仅由系统编程涉及应用程序虽然可以直接操作内存但是也只能在操作系统分配的内存段中操作。
注:
实模式:指寻址采用和8086相同的16位段和偏移量,最大寻址空间1MB(20根地址总线寻址),最大分段64KB(寄存器为16位)。可以使用32位指令,32位的x86 CPU用做高速的8086。
保护模式:寻址采用32位段和偏移量,最大寻址空间4GB,最大分段4GB (Pentium Pre及以后为64GB)。在保护模式下CPU可以进入虚拟8086方式,这是在保护模式下的实模式程序运行环境。
二、线性地址
  线性地址(Linear Address)是逻辑地址到物理地址转换的中间层。程序代码经编译后会产生逻辑地址,或者说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。
  若启用了分页机制,则线性地址会再此转换产生一个物理地址。若没有启用分页机制,则线性地址就是物理地址。Intel 80386的线性地址空间容量为4G(2的32次方,即32根地址总线寻址)。
三、物理地址
  物理地址(Physical Address)是指出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终地址。若启用了分页机制,则线性地址会使用页目录和页表中的项转换为物理地址。若没有启用分页机制,则线性地址直接就是物理地址。
四、虚拟内存
  虚拟内存(Virtual Memory)是指计算机呈现出比实际拥有的内存大得多的存量。因此它允许程序员编写并运行比实际系统拥有的内存大得多的程序。这使得许多大型项目也能够在具有有限内存资源的系统上实现。一个很恰当的比喻是:你不需要很长的轨道就可以让使列火车从上海开到北京,只需要比较长的两段铁轨(比如说3公里)就可以完成这个任务。采取的方法是把后面运行过的的铁轨立刻铺到火车的前面,只要操作的足够快列车就能像在一条完整的轨道上运行一样。这也就是虚拟内存管理需要完成的任务。在Linux 0.11内核中,为每个“程序”(进程)都划分了总容量为64MB的虚拟内存空间,因此程序的逻辑地址范围是0x0000000到0x4000000。
  有时我们也把逻辑地址称为虚拟地址,因为与虚拟内存空间的概念类似,逻辑地址也是与实际物理内存容量无关的。逻辑地址与物理地址的“差距”是0xC0000000,是由于虚拟地址->线性地址->物理地址的映射正好差这个值,这个值是操作系统指定的。