虚拟内存是什么(虚拟内存怎么清理)( 二 )


当CPU开始执行一个代码段的第一条指令时,会将代码段的选择器放入CS段寄存器,然后CPU从段寄存器中获取选择器,然后截取选择器的高13位得到索引,然后根据全局描述符表寄存器的地址找到全局描述符表的起始地址,根据起始地址索引*8找到段描述符,然后根据段描述符得到段的基址 。段的基址加上ip寄存器中的偏移地址就是指令的物理地址 。
定位指令
当CPU执行0x00600000的代码指令时,指令为MOV AX,[0],表示地址0的数据存放在AX寄存器中,这个0就是数据段的偏移地址 。这时CPU会将数据段的选择器加入到DS段寄存器中,然后CPU获取段选择的高13位得到索引 。然后根据全局描述符表寄存器的地址找到全局描述符表的起始地址,根据起始地址索引*8找到段描述符,再根据段描述符得到段的基址 。数据段的基址加上数据段的偏移地址就是数据的物理地址,如下面的步骤1-6所示 。
定位器数据
以上过程就是【段选分段偏移地址】的定位方法 。
虚拟地址现代操作系统和CPU不开放分页时,使用【段选子段偏移地址】来访问代码和数据 。一旦开启分页,通过【段选子段偏移地址】得到的地址就不再是物理地址,而是虚拟地址,默认是开启分页 。
现代操作系统和CPU采用的扁平化模型是指整个内存只有一个段,所以段基址为0,段偏移地址等于虚拟地址 。
以下将从以下几个方面来阐述与虚拟地址相关的话题 。
1.什么是虚拟地址,物理地址,虚拟地址空,物理地址空,虚拟内存,物理内存?
2.什么是进程虚拟地址空?
3.什么是虚拟页面,物理页面?
4.什么是页表?
5.虚拟地址如何访问物理内存?
什么是虚拟地址,物理地址,虚拟地址空间,物理地址空间,虚拟内存,物理内存?虚拟地址空是虚拟地址的集合 。假设虚拟地址空为n位,其地址范围为{0~2的n次方-1},即有2的n次方个虚拟地址,例如16位虚拟地址空,其地址范围为{0 ~ 6555] 。
物理地址空是物理地址的集合 。假设物理地址之间有M个字节空,其地址范围为{0 ~ m-1} 。M不一定是2的幂,比如M=100,也就是说物理地址空之间的大小是100字节,它的地址
物理内存可以看作一个新的物理字节数组,每个物理地址都指向这个物理字节数组中的一个项 。
虚拟内存也是如此,也可以认为是物理字节数组,但这个字节数组是存储在磁盘上的 。
物理地址空是物理内存的范围,虚拟地址空是虚拟内存的范围 。物理地址空中的每个物理地址实际上都指向一个特定的存储单元 。虚拟地址空中每个虚拟地址指向的情况有三种:
A.未分配,这个虚拟地址只是一个数字,没有意义 。
B.无缓冲,这个虚拟地址指向磁盘的一个字节存储单元,它存储指令或数据 。
C.缓冲后,这个虚拟地址指向物理内存中的一个字节存储单元,它存储指令或数据 。
2.什么是进程虚拟地址空间?操作系统加载可执行文件后,创建一个进程,这个进程有自己的虚拟地址空,每个进程的虚拟地址空都是一样的,如下图所示 。
虚拟地址之间空
如上图所示,一个进程的虚拟地址空被统一划分为几个固定的区域,比如代码区、数据区、堆区、共享区、堆栈区、内核区 。
代码区和数据区:从可执行文件来看,代码区和数据区是挨着的,代码区总是在地址0x0040000之上,但在地址0x0040000之下用于其他用途 。
运行时堆区域:其初始大小为0 。使用内存动态分配(malloc)时,运行时堆不断向高地址扩展,一个指针brk指向堆的最高地址 。
共享库的内存映射区:这个区域是一些标准的系统库 。这个共享库在物理内存中只存储一个副本,每个进程都将这个区域的虚拟地址映射到同一个共享库物理内存中 。
用户堆栈区:这个区域紧挨着内核区,位于高位地址 。随着用户栈的推出、推入和动态扩展,推入会向低地址方向扩展,而推出会向高地址方向收缩,顶指针存储在栈寄存器(ESP)中 。
内核区:这个区域是操作系统本身的代码、数据、栈空 。内核只在物理内存中存储一个副本,每个进程都将这个区域的虚拟地址映射到同一个内核物理内存中 。
内核和共享库的映射
3.什么是虚拟页,物理页?现代操作和CPU将物理内存按照一个固定的页大小分成很多部分,每个部分称为物理页(PP),每个部分都有一个编号,称为物理页号(PPN) 。这个物理页面大小通常是4KB 。比如一个物理内存是20KB,这个物理内存可以分成五个物理页,所以物理页号(PPN)是0,1,2,3,4 。


推荐阅读