内存寻址:逻辑地址到物理地址的转化
在计算机里,内存地址分为虚拟内存地址和物理内存地址。
数据存放在物理内存中,程序运行时使用的是虚拟内存,并通过虚拟内存地址访问数据和代码。
那操作系统是如何将虚拟内存映射为物理内存地址呢?
一 虚拟内存布局
以X86的32位系统位例,在32系统中,系统的虚拟内存地址范围为4GB。低2GB给应用程序(Ring3级别)使用。
高2GB给系统内核(Ring0)使用。
每个程序都有属于自己的一个私有2GB虚拟内存空间,如下图:
其中的0000-ffff前64KB地址为NULL地址区域,0x0000ffff-0x7fff0000为进程空间,
0x7fff0000-0x7fffffff为非法区域,禁止程序访问,禁止Ring3级别的应用程序不小心访问到后面2GB的内核内存空间。
① X86的虚拟内存布局
X86支持32位寻址,因此可以支持2的32次方即4GB的虚拟内存空间。虚拟地址再通过页表机制映射到物理地址以便存取物理内存中的数据和指令。
PS: 也可以通过PAE模式将寻址空间扩大到64GB,PAE是物理地址扩展,在4GB的虚拟地址空间中,Windows系统的
4GB内存主要分为2GB的内核空间和2GB的应用层空间。
② X64的虚拟内存布局
X64(AMD64)的内存布局与X86的内存布局类似,不同的地方在于各自空间的范围和大小不同,同时X64下还存在一些空洞。
在X64系统,理论上支持最大2的64次方字节寻址空间,空间太大了根本用不完。所以实际上X64系统一般只支持到40多位
Windows支持44位最大寻址空间位16TB,Linux支持48位最大寻址空间位256TB。这些TB的空间并不都是可用的,存在所谓的空洞。
二 逻辑地址转化为物理地址
程序在执行时,传递给CPU的地址是逻辑地址,逻辑地址由二部分组成,一部分是段选择符(比如cs和ds等段寄存器的值),
另一部分为有效地址(即偏移地址,比如eip寄存器的值)。
逻辑地址必须经过转化变成线性地址,线性地址再经过一次映射转为物理地址,才能访问真正的物理内存。