5.2.3 分段机制的应用
IA32构架CPU提供的分段机制十分灵活,从最简单的基本平展段模式到复杂的多段模式,以及多段模式和分页机制的结合,都可以被操作系统采用,以完成不同的需求。在本节中,我们将对不同的段模式进行介绍。
1.基本平展段模式
所谓平展段模式,指的是系统中数据段、代码段、堆栈段等相互重叠,并且每个段都跟整个线性地址空间重叠。这样的段模式,使得应用程序和操作系统可以访问整个线性地址空间,而不用考虑段的存在。实际上,这种应用模式,把IA32 CPU的段机制屏蔽了。图5-5示意了这种基本的平展段模式。
图5-5 平展段应用模式
这种模式下,至少创建两个段描述符:一个为代码段描述符,该描述符的选择子,存放到CS寄存器;另外一个为数据段描述符,其选择子存放到DS和SS寄存器(堆栈段与数据段重合)。这两个数据段的访问方式、基址和界限都相同,唯一不同的是标志字段。
平展段模式是一种最基本的段模式,又是一种最通用的方式,按照这种方式实现的操作系统,可以很容易地移植到其他CPU,甚至是一些没有实现段机制的CPU。目前版本的Hello China就是按照这种模式实现的。
实际上,许多流行的操作系统,都是按照这种方式实现的,只不过额外增加了两个段:
● 用户程序代码段,用来保存用户程序的代码;
● 用户程序数据段,用来保存用户程序的数据。
所有段的基址和界限,都是重叠的,覆盖了整个线性地址空间。为了实现保护功能,这些流行的操作系统采用了IA32的分页机制。
2.保护平展段模式
与基本平展段模式类似的是保护平展段模式,在基本平展段模式中,每个段的界限(Limited)字段被设置为最大(0xFFFFFFFF),这样即使实际物理内存很小,在CPU出现内存访问溢出(访问的物理地址比实际配置的物理地址大)时,也仍然是可行的,不会引起异常。而保护平展段模式则不同,这种模式下,根据需要把段的界限和基址设置为合适的值,但整个系统中仍然存在两个段:代码段和数据段(堆栈段与数据段合一)。图5-6示意了这种结构。
图5-6 保护平展段应用模式
这种段模型也有两个段:
● 代码段,该段的基地址设置为代码的实际开始地址,界限设置为代码段的长度。
● 数据段,该段的基地址设置为数据的实际开始地址(0x00000000),界限设置为数据和堆栈的长度的和。
这样就可以避免两种错误情况的出现:
(1)内存访问越界,若对数据或代码的访问超出了实际配置的物理内存,就会引起异常;
(2)代码段被改写,因为数据段和代码段是不重合的,绝对不会出现代码段被改写的情况。
3.多段模式
多段模式是最复杂的一种模式,对于不同的数据结构采用不同的段来表示。这种模式完整地应用了IA32 CPU提供的段机制,这样可以很好地应用一些基于段机制的保护措施。这种段模式如图5-7所示。
图5-7 多段应用模式
系统中对不同的数据结构(数据、代码、堆栈等)设置了不同的段,每个段具有不同的基址和界限,分别与实际的数据结构在内存中的位置对应,并把不同的段选择子装载到不同的段寄存器。
这种结构可以充分应用CPU提供的段保护基址,比如这种情况下,不可能出现堆栈溢出的情况,因为一旦溢出,就会引发异常。但这种结构也有一个缺点,CPU依赖性太强,按照这种模型实现的操作系统,很难移植到其他与IA32段机制不同的CPU上。