几种地址的理解

来源:互联网 发布:淘宝天猫女鞋品牌故事 编辑:程序博客网 时间:2024/05/01 20:56

逻辑地址是指汇编后的地址,线性地址(虚拟地址)是指C代码中(汇编前的地址),物理地址是指实际的地址空间。

               

               段式管理                   页式管理

   逻辑地址----------->线性地址------------>物理地址

 

在16位的机器中,逻辑地址(偏移量)+基地址=物理地址 (寄存器为16位的,而地址总线为20根,所以16位地址<<4后得到一个基地址,再加上逻辑地址,得到最终的物理地址)。

 

在32位的机器中,段寄存器存放的是段地址的选择器,用该选择器从内存中得到一个32位的段地址,存储单元的物理地址就是该段地址加上段内偏移量。如下图所示:

 

 

 

 

如果32位的机器用上面的段式管理得到的是线性地址后,则再通过页式管理可以得到实际的物理地址了。页式管理如下图所示:

 

 

 

但是由于是32位的机子,所以段式管理中的基地址就为0,不需要通过段式管理(右移后扩展地址空间的方法)得到4G的线性地址空间(寄存器已经是32位的了),所以linux中基本不用段式管理,逻辑地址和线性地址(虚拟地址)是同一地址。只需要上面的页式管理即可得到对应物地址。

 

 

linux中采用虚拟内存技术,每个用户看到和接触到的都是虚拟地址,无法看到实际的物理地址。利用虚拟内存技术不但能起到保护操作系统的作用,更重要的是用户可使用比实际物理内存更大的物理地址空间。每个进程有4G的地址空间(3G的用户空间和1G的内核空间),用户空间对应的进程,每当进程切换,用户空间就会跟着变化。(注意内核空间是由内核负责映射的,它并不会跟着进程改变,是固定的,也就是内核映射的页表、页目录等信息时固定不变的。)

 

应用程序中的malloc(fork、excute、mmap等)都是申请的虚拟地址空间,实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会由请页机制产生缺页异常,从而进入分配实际页框的程序。(该异常是虚拟内存机制赖以存在的基本保证---它会告诉内核去为进程分配物理页,并建立对应的页表,这之后虚拟内存才实实在在的映射到了物理地址上。)因为每个进程的上图中页目录和页表都是不一样的,所以不同的进程,虽然虚拟地址可以相同,但是页机制后的物理地址都是不一样的。

这就可以理解,内存溢出,是所有的进程用到的虚拟地址被访问时分配到物理地址之和,超过的实际的物理内存,才会溢出。