本文介绍保护方式下的段定义以及由段选择子及段内偏移构成的二维虚拟地址如何被转换为一维线性地址。 <一>段定义和虚拟地址到线性地址的转换
段是实现虚拟地址到线性地址转换机制的基础。在保护方式下,每个段由如下三个参数进行定义:段基地址(Base Address)、段界限(Limit)和段属性(Attributes)。 逆风编程精品 段基地址规定线性地址空间中段的开始地址。在80386保护方式下,段基地址长32位。因为基地址长度与寻址地址的长度相同,所以任何一个段都可以从32位线性地址空间中的任何一个字节开始,而不象实方式下规定的边界必须被16整除。 段界限规定段的大小。在80386保护模式下,段界限用20位表示,而且段界限可以是以字节为单位或以4K字节为单位。段属性中有一位对此进行定义,把该位成为粒度位,用符号G标记。G=0表示段界限以字节位位单位,于是20位的界限可表示的范围是1字节至1M字节,增量为1字节;G=1表示段界限以4K字节为单位,于是20位的界限可表示的范围是4K字节至4G字节,增量为4K字节。当段界限以4K字节为单位时,实际的段界限LIMIT可通过下面的公式从20 位段界限Limit计算出来: LIMIT=limit*4K 0FFFH=(Limit SHL 12) 0FFFH 所以当粒度为1时,段的界限实际上就扩展成32位。由此可见,在80386保护模式下,段的长度可大大超过64K字节。 基地址和界限定义了段所映射的线性地址的范围。基地址Base是线性地址对应于段内偏移为 0的虚拟地址,段内偏移为X的虚拟地址对应Base X的线性地址。段内从偏移0到Limit范围内的虚拟地址对应于从Base到Base Limit范围内的线性地址。 下图表示一个段如何从虚拟地址空间定位到线性地址空间。图中BaseA等代表段基地址, LimitA等代表段界限。另外,段C接在段A之后,也即BaseC=BaseA LimitA。
例如:设段A的基地址等于00012345H,段界限等于5678H,并且段界限以字节为单位(G=0),那么段A对应线性地址空间中从00012345H-000179BDH的区域。如果段界限以4K字节为单位 (G=1),那么段A对应线性地址空间中从00012345H-0568B344H(=00012345H 5678000H 0FFFH) 的区域。 通过增加段界限,可以使段的容量得到扩展。这对于那些要在内存中扩展容量的普通数据段很有效,但对堆栈段情况就不是这样。因为堆栈底在高地址端,随着压栈操作的进行,堆栈向低地址方向扩展。为了适应普通数据段和堆栈数据段在两个相反方向上的扩展,数据段的段属性中安排了一个扩展方向位,标记为ED。ED=0表示向高端扩展,ED=1表示向低端扩展。一般只有堆栈数据段才使用向低端扩展的属性(堆栈段也可使用向上扩展的段),这是因为,向下扩展的段是为以下两个目的而设计的: 第一,堆栈段被定义为独特段,即DS和SS包含不同的选择器。 第二,一个堆栈段是靠将它复制到一个更大的段来扩充自己(而不是靠将现存的页增加到它的段上)。不打算用这种方法实现堆栈的设计者不需要定义向下扩展的段。 需要注意的是,只有数据段的段属性中才有扩展方向属性位ED,也就是说只有数据段(堆栈段作为特殊的数据段)才有向上扩展和向下扩展之分,其它段都是自然的向上扩展。 数据段的扩展方向和段界限一起决定了数据段内偏移的有效范围。当段最大为1M字节时,在向高端扩展的段内,从0到Limit的偏移是合法有效的偏移,而从Limit 1到1M-1的偏移是非法无效的偏移;在向低端扩展的段内,情形刚好相反,从0到Limit的偏移是非法无效的偏移,而从Limit 1到1M-1的偏移是合法有效的偏移,注意边界值Limit对应地址的有效性。段最大为4G时,情形类似。由此可见,如果一个段是向下扩展的,则所有的偏移必须大于限长,因为其限长是指下限,其基地址从高地址出开始。反之,若一个段是向上扩展的,则所有偏移必须小于等于限长,因为其限长是指上限,基地址从低地址处开始。通过使用段环绕,可以把向下扩展段定义到任何线性地址且可定义为任何大小。
本文章更多内容:1 - 2 - 3 - 下一页>> |