首页 理论教育 操作系统实现之路:IA32CPU内存管理机制概述

操作系统实现之路:IA32CPU内存管理机制概述

时间:2023-10-21 理论教育 版权反馈
【摘要】:IA32的内存管理机制由两部分组成:分段和分页。IA32 CPU提供的这种内存管理机制十分灵活。图5-1清楚地表示了这种内存管理机制。图5-1 Intel CPU内存管理机制从图中可以看出,通过分段的方式,把CPU可寻址的整个地址空间分成了若干部分,每部分对应一个段。为了解决这个问题,IA32构架的CPU采用段寄存器来存储段选择子,在访问段内数据的时候,逻辑地址的选择子部分直接从段寄存器中获取。为了进一步提高效率,IA32还实现了影子寄存器的机制。

操作系统实现之路:IA32CPU内存管理机制概述

IA32的内存管理机制由两部分组成:分段和分页。其中,分段提供了一种机制,使得应用程序或操作系统的数据、代码、堆栈等可以相互隔离,避免相互影响,在多任务(多进程)的情况下,每个任务都有自己特定的段,这样每个任务之间也不会相互影响。而分页机制则提供了按需内存分配、虚拟内存等机制,有了这些机制的支持,就可以实现应用程序的部分装入(只加载应用程序的部分代码到内存中,即可以开始执行)等功能。当然,分页机制也可以用于应用程序之间的隔离(或保护)。在IA32体系构架的CPU中,是否启用分页机制是一个可选项,通过设置CR0寄存器(控制寄存器)的某一个比特,可以禁止或启用分页机制,而分段机制则不然,任何情况下都是启用的,没有一种方法可以禁止分段功能。

IA32 CPU提供的这种内存管理机制十分灵活。最简单的情况下,采用平展段模式,禁止分页,可以实现最简单的、与物理内存一样的内存管理模型;最复杂的情况下,采用独立的段管理不同进程(或操作系统)的不同数据(代码、数据、堆栈等),采用分页机制实现虚拟内存、按需内存分配等,可以实现最完整的程序保护,可以确保操作系统不受任何应用程序的影响,且应用程序之间也互不影响,而同一个应用程序内采用段保护机制,也不会出现堆栈溢出、非法访问等异常情况。

图5-1清楚地表示了这种内存管理机制。

978-7-111-41444-5-Chapter05-1.jpg

图5-1 Intel CPU(IA32)内存管理机制

从图中可以看出,通过分段的方式,把CPU可寻址的整个地址空间(此处叫做线性地址空间)分成了若干部分,每部分对应一个段。要描述每个段,就需要知道这个段在线性地址空间中的基地址(起始地址)以及该段的长度(界限),对于不同的段(比如代码段、数据段等),还有不同的访问方式(只读、读写等),所有这些数据存放在一个全局描述符表(GDT)中,全局描述符表的每一项(称为段描述符)描述了一个特定的段。要访问一个段内的特定字节,需要给出两个数据:该段的描述符(用于确定段的基地址)和该字节在段中的偏移(相对于段基地址)。在IA32的实现中,段描述符表存放在物理内存中,整个段描述符表的初始地址存放在一个特定的寄存器GDTR中。因此,在访问段描述符的时候,需要通过GDTR查找到全局描述符表对应的物理内存起始地址,然后再根据描述符在全局描述符表中的索引定位到具体的段描述符的物理地址。段描述符在全局描述符表中的索引,称为段选择子。对于所有的段,由于GDTR是固定的,所以,给出一个段选择子,就可以准确定位到具体的段,也就是说,段描述符和段选择子是一一对应的。因此,要访问特定段内的一个字节,只需要给出一个段选择子和该字节在该段中的偏移位置即可。这两者的组合(段选择子和段内偏移)称为逻辑地址。在IA32的段寄存器(CS、DS等)中,存放的实际上就是段选择子。图5-2示意了逻辑地址和线性地址的关系。(www.xing528.com)

978-7-111-41444-5-Chapter05-2.jpg

图5-2 逻辑地址和线性地址的关系

给出一个逻辑地址后,CPU就根据段选择子查找到对应的段描述符,从段描述符中获得段的基地址(在线性地址空间中),然后把基地址与逻辑地址的字节偏移部分相加,就获得一个线性地址。若没有启用分页机制,这个线性地址就可以直接映射到物理地址了。可以看出,这个过程是复杂的,需要多次访问物理内存,这样势必影响效率。为了解决这个问题,IA32构架的CPU采用段寄存器来存储段选择子,在访问段内数据的时候,逻辑地址的选择子部分直接从段寄存器中获取。按照当前的实现,代码段选择子从CS寄存器内获得,数据段选择子从DS寄存器内获得,堆栈段选择子从SS寄存器内获得。因此,访问具体数据的时候需要根据数据所在的段,先把段选择子装入特定的段寄存器。为了进一步提高效率,IA32还实现了影子寄存器的机制。CS/DS等段寄存器还包含了不可见的影子部分,影子部分存储了当前段的起始地址和段界限,这些数据在初始化CS/DS等段寄存器的时候,由CPU统一初始化,这样在访问段内数据时,就不用再从物理内存中获取段描述符,然后再获得段基地址了,而是直接从影子寄存器内获得段基地址。在这样的机制下,访问一个段内的一个字节,只通过一次内存访问操作就完成了,大大提高了效率。段寄存器和影子寄存器的关系如图5-3所示。

978-7-111-41444-5-Chapter05-3.jpg

图5-3 段寄存器和影子寄存器的关系

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈