为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

保护模式

2010-11-20 18页 pdf 227KB 35阅读

用户头像

is_062212

暂无简介

举报
保护模式 一.保护方式简介 80386 有三种工作方式:实模式,保护模式和虚拟 8086 模式。本文介绍保护方式 下的 80386 及相关的程序设计内容。实模式下的 80386 寄存器,寻址方式和指令 等基本概念,除特别说明外在保护方式下仍然保持。 尽管实方式下 80386 的功能要大大超过其先前的处理器 (8086/8088,80186,80286),但只有在保护方式下, 80386 才能真正发挥更大的 作用。在保护方式下,全部 32 条地址线有效,可寻址高达 4G 字节的物理地址空 间;扩充的存储器分段管理机制和可选的...
保护模式
一.保护方式简介 80386 有三种工作方式:实模式,保护模式和虚拟 8086 模式。本文介绍保护方式 下的 80386 及相关的程序设计内容。实模式下的 80386 寄存器,寻址方式和指令 等基本概念,除特别说明外在保护方式下仍然保持。 尽管实方式下 80386 的功能要大大超过其先前的处理器 (8086/8088,80186,80286),但只有在保护方式下, 80386 才能真正发挥更大的 作用。在保护方式下,全部 32 条地址线有效,可寻址高达 4G 字节的物理地址空 间;扩充的存储器分段管理机制和可选的存储器分页管理机制,不仅为存储器共 享和保护提供了硬件支持,而且为实现虚拟存储器提供了硬件支持;支持多任务, 能够快速地进行任务切换和保护任务环境;4 个特权级和完善的特权检查机制, 既能实现资源共享又能保证代码和数据的安全和保密及任务的隔离;支持虚拟 8086 方式,便于执行 8086 程序。 <一>存储管理机制 为了对存储器中的程序及数据实现保护和共享提供硬件支持,为了对实现虚拟存 储器提供硬件支持,在保护方式下,80386 不仅采用扩充的存储器分段管理机制, 而且提供可选的存储器分页管理机制。这些存储管理机制由 80386 存储管理部件 MMU 实现。 1.目标 80386 有 32 根地址线,在保护方式下,它们都能发挥作用,所以可寻址的物理 地址空间高达 4G 字节。在以 80386 及其以上处理器为 CPU 的 PC 兼容机系统中, 把地址在 1M 以下的内存称为常规内存,把地址在 1M 以上的内存称为扩展内存。 80386 还要对实现虚拟存储器提供支持。虽然与 8086 可寻址的 1M 字节物理地址 空间相比,80386 可寻址的物理地址空间可谓很大,但实际的微机系统不可能安 装如此达的物理内存。所以,为了运行大型程序和真正实现多任务,必须采用虚 拟存储器。虚拟存储器是一种软硬件结合的技术,用于提供比在计算机系统中实 际可以使用的物理主存储器大得多的存储空间。这样,程序员在编写程序时不用 考虑计算机中物理存储器的实际容量。 80386 还要对存放在存储器中的代码及数据的共享和保护提供支持。任务甲和任 务乙并存,任务甲和任务乙必须隔离,以免相互影响。但它们又可能要共享部分 代码和数据。所以,80386 既要支持任务隔离,又要支持可共享代码和数据的共 享,还要支持特权保护。 2.地址空间和地址转换 保护方式下的虚拟存储器由大小可变的存储块构成,这样的存储块称为段。80386 采用称为描述符的数据来描述段的位置、大小和使用情况。虚拟存储器的地址(逻 辑地址)由指示描述符的选择子和段内偏移两部分构成,这样的地址集合称为虚 拟地址空间。80386 支持的虚拟地址空间可达 64T 字节。程序员编写程序时使用 的存储地址空间是虚拟地址空间,所以,他们可认为有足够大的存储空间可供使 用。 显然,只有在物理存储器中的程序才能运行,只有在物理存储器中的数据才能访 问。因此,虚拟地址空间必须映射到物理地址空间,二维的虚拟地址必须转化成 一维的物理地址。由于物理地址空间远小于虚拟地址空间,所以只有虚拟地址空 间中的部分可以映射到物理地址空间。由于物理存储器的大小要远小于物理地址 空间,所以只有上述部分中的部分才能真正映射到物理存储器。 每一个任务有一个虚拟地址空间。为了避免多个并行任务的多个虚拟地址空间直 接映射到同一个物理地址空间,采用线性地址空间隔离虚拟地址空间和物理地址 空间。线性地址空间由一维的线性地址构成,线性地址空间和物理地址空间对等。 线性地址 32 位长,线性地址空间容量为 4G 字节。 80386 分两步实现虚拟地址空间到物理地址空间到物理地址空间的映射,也就是 分两步实现虚拟地址到物理地址的转换,但第二步是可选的。下图是地址映射转 换的示意图。 通过描述符和描述符,分段管理机制实现虚拟地址空间到线性地址空间的映 射,实现把二维的虚拟地址转换为一维的线性地址。这一步总是存在的。 分页管理机制把线性地址空间和物理地址空间分别划分为大小相同的块,这样的 块称为页。通过在线性地址空间的页与物理地址空间的页建立之间建立的映射 表,分页管理机制实现线性地址空间到物理地址空间的映射,实现线性地址到物 理地址的转换。分页管理机制是可选的,在不采用分页管理机制时,线性地址空 间就等同于物理地址空间,线性地址就等于物理地址。 分段管理机制所使用的可变大小的块,时分段管理机制比较适宜处理复杂系统的 逻辑分段。存储块的大小可以根据适当的逻辑含义进行定义,而不用考虑固定大 小的页所强加的人为限制。每个段可作为独立的单位处理,以简化段的保护及共 享。分页机制使用的固定大小的块最适合于管理物理存储器,无论是管理内存还 是外存都同样有效。分页管理机制能够有效地支持实现虚拟存储器。 段及分页这两种机制是两种不同的转换机制,是整个地址转换函数的不同的转换 级。虽然两种机制都利用存储在主存储器中的转换表,但这些表具有独立的结构。 事实上,段表存储在线性地址空间,而页表存储在物理地址空间。因此,段转换 表可由分页机制重新进行定位而不需段机制的参与。段转换机制把虚拟地址转换 为线性地址,并在线性地址中访问段转换机制的表格,而不会觉察分页机制已把 线性地址转换为物理地址。类似地,分页机制对于程序产生的地址所使用的虚拟 地址空间一无所知。分页机制只是直接地把线性地址转换为物理地址,并且在物 理地址中访问转换表格,并不知道虚拟地址空间的存在,甚至不知道段转换机制 的存在。 3.虚拟存储器概念 虚拟存储器是一种设计技术,用于提供比在计算机系统中实际可以使用的物理主 存储器大得多的存储空间。使用者会产生一种错觉,好象在程序中可以使用非常 大的物理存储空间。使用虚拟存储器的好处是:一个程序可以很容易地在物理存 储器容量大不一样的、配置范围很广的计算机上运行;编程人员使用虚拟存储器 可以写出比任何实际配置的物理存储器都大得多的程序。虚拟存储器由存储管理 机制及一个大容量的快速硬盘存储器支持。在程序运行的任何时刻,只把虚拟地 址空间的一小部分映射到主存储器,其余部分则存储在磁盘上。因为只有存储在 主存储器中的部分虚拟存储器可由处理器使用,这种虚拟存储技术将依赖程序内 部访问存储器的局部化特性,在程序执行中只需整个虚拟存储器中的少量存储内 容在主存储器中驻留。而当访问存储器的范围发生变化时,有必要把虚拟存储器 的某些部分从磁盘调入主存储器,虚拟存储器的另外的部分,也能从主存储器传 送回磁盘上。 地址转换机制以两种方式支持虚拟存储器。 第一,把实际驻留在主存储器中的那部分虚拟存储器标记为无效,并建立起虚拟 存储器驻留部分的虚拟-- 物理映射关系,把驻留部分的相应虚拟存储器地址, 转换为对应物理存储器的地址。如果程序访问的虚拟地址对应于虚拟存储器未驻 留的部分,将由于无效映射信息而引起异常。操作系统通过把未驻留部分从磁盘 上读入到主存储器中,来处理这种异常,并根据需要更新地址转换表。在引起异 常的原因排除以后,异常处理程序完成异常事件的处理,并返回原来的程序恢复 执行。在后面的文章中将会看到,从异常处理程序返回后,这时要重新执行一次 原来引起异常的指令,而该指令在后一次执行时自然会成功地完成。 第二,地址转换机制通过收集驻留在主存储器中的虚拟存储器部分的使用统计信 息来支持虚拟存储器,这些使用统计信息,在主存储器空间紧缺时,帮助操作系 统决定可以将哪些部分传送回磁盘。 <二>保护机制 为了支持多任务,对各任务实施保护是必需的。从 80286 开始,处理器就具备了 保护机制。保护机制能有效地实现不同任务之间的保护和同一任务内的保护。 1.不同任务之间的保护 保护的一个重要方面是应用程序之间的保护。通过把每个任务放置在不同的虚拟 地址空间的方法来实现任务与任务的隔离,达到应用程序之间保护的目的。虚拟 地址到物理地址的映射函数在每个任务中进行定义,随着任务切换,映射函数也 切换。任务 A的虚拟地址空间映射到物理地址空间的某个区域,而任务 B的虚拟 地址空间映射到物理地址空间的另外区域,彼此独立,互不相干。因此,两个不 同的任务,尽管虚拟存储单元地址相同,但实际的物理存储单元地址可以不同。 每个任务各有一组独立的映射表,即具有不同的地址转换函数。在 80386 上,每 个任务都有自己的段表及页表。当处理器进行切换并执行新的任务时,这种任务 切换的一个重要部分,就是为新任务切换任务的转换表。为了使操作系统与所有 的应用程序相隔离,可以把操作系统存储在一个单一的任务中。然而,我们即将 看到,在一个任务内操作的保护机制,更适合于保护操作系统,使其不被应用程 序破坏。这种机制,使操作系统由所有任务共享,并且可在每一任务中对其进行 访问,而且仍然保护了操作系统,使其不被应用程序破坏。这种保护操作系统的 方法,是把操作系统存储在虚拟地址空间的一个公共区域,然后,再使每一任务 按此区域分配一个同样的虚拟地址空间,并进行同样的虚拟--物理地址映射。各 个任务公用的这部分虚拟地址空间,被称为全局地址空间。 仅由一个任务占有的虚拟地址空间部分,即不被任何其它任务共享的虚拟地址部 分,称为局部地址空间。局部地址空间包含的代码和数据,是任务私有的,需要 与系统中的其它任务相隔离。 再每个任务中有不同的局部地址空间。因此,两个不同的任务中,对同一虚拟地 址的访问,实际上转换为不同的物理地址。这就使操作系统对每个任务的存储器, 可以赋予相同的虚拟地址,仍然保证任务的隔离。另一方面,对全局地址空间中 同一虚拟地址的访问,在所有任务中都转换为同样的物理地址,从而支持公共的 代码及数据的共享,例如对操作系统的共享。 2.同一任务内的保护 在一个任务之内,定义有四种执行特权级别,用于限制对任务中的段进行访问。 按照包含在段中的数据的重要性和代码的可信程度,给段指定特权级别。把最高 的特权级别分配给最重要的数据段和最可信任的代码段。具有最高特权级别的数 据,只能由最可信任的代码访问。给不重要的数据段和一般代码段分配较低的特 权级别。具有最低特权级别的数据,可被具有任何特权级别的代码访问。 特权级别用数字 0、1、2和 3表示,数字 0表示最高特权级别,而数字 3表示最 低特权级别,即数字较大的级别具有较低的特权。为了避免模糊和混淆,在比较 特权级别时,不使用“大于”或“小于”这样的术语,而使用“里面”或“内 层”这样的术语表示较高特权级,级别的数字较小;使用“外面”或“外层”这 样的术语表示较低特权级别,级别的数字较大。0级为最内层的特权级别,3级 为最外层的特权级别,按这样的表示方法,四种特权级的层次关系如下图(图中 右边的数字为特权级)所示。 每一特权级都有各自独立的程序堆栈,以避免与共享栈区有关的保护问题。当一 个程序从一个特权级切换到另一个特权级执行时,程序使用的堆栈,从原特权级 的栈段改变为新特权级的栈段。对于堆栈段寄存器 SS 来说,描述符特权级(DPL) 必须等于当前代码段的特权级(CPL)。从一个特权级切换到另一特权级的方法将 在控制转移方法一文中描述。 每个存储器段都与一个特权级别相联系。特权级别限制是指,只有足够级别的程 序,才可对相应的段进行访问。在任何时候,一个任务总是在四个特权级之一下 运行,任务在特定时刻的特权级称为当前特权级 (Current Privilege level), 标记为 CPL,即当前运行程序的特权级。每当一个程序试图访问一个段时,就把 CPL 与要访问的段的特权级进行比较,以决定是否允许这一访问。对给定 CPL 执 行的程序,允许访问同一级别或外层级别的数据段。如上图所示,CodeK 可访问 同级的数据段 DataK,也可访问外层的 DataOS、 DataAP1 及 DataAP2 等。如果 试图访问内层级别的数据段则是非法的,并引起异常。如上图所示,CodeOS 可 访问同级的 DataOS,也可访问外层的 DataAP1 和 DataAP2 等,但不能访问内层 的 DataK。 虽然应用程序都在最外层,但由于各个不同的应用程序存储在不同的虚拟地址空 间中,所以各应用程序被隔离保护。如上图所示,最外层的 CodeAP1 只能访问 DataAP1,不可能访问同级的另一应用程序的 DataAP2;同样,CodeAP2 只能访问 DataAP2,不可能访问 DataAP1。 这实际上是组合保护。应用程序 1和操作系统构成任务 A,应用程序 2和操作系 统构成任务 B。操作系统被任务 A和任务 B共享,在任务 A和任务 B的两个不同 的虚拟地址空间中,操作系统占用虚拟地址空间相同的部分。 特权级的典型用法是,把操作系统的核心部分放在 0级,操作系统的其余部分放 在 1级,而应用程序放在 3 级,留下的 2级供中间软件使用。对特权级进行这 样的安排,使得在 0级的操作系统核心有权访问任务中的所有存储段;而在 3 级的应用程序只能访问程序本身的存储段,这些存储段也是在 3级(注意, Windows 9X 操作系统只使用了 0级和 3级,以便于移植到精简指令集的计算机 上,如 RS4000 等,这些处理器一般只有两个特权级,即系统级和用户级)。 二.分段管理机制 本文介绍保护方式下的段定义以及由段选择子及段内偏移构成的二维虚拟地址 如何被转换为一维线性地址。 <一>段定义和虚拟地址到线性地址的转换 段是实现虚拟地址到线性地址转换机制的基础。在保护方式下,每个段由如下三 个参数进行定义:段基地址(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 时,情形 类似。由此可见,如果一个段是向下扩展的,则所有的偏移必须大于限长,因为 其限长是指下限,其基地址从高地址出开始。反之,若一个段是向上扩展的,则 所有偏移必须小于等于限长,因为其限长是指上限,基地址从低地址处开始。通 过使用段环绕,可以把向下扩展段定义到任何线性地址且可定义为任何大小。 在每次把虚拟地址转换为线性地址的过程中,要对偏移进行检查。如果偏移不在 有效的范围内,那么就引起异常。 段属性规定段的主要特性。例如上面已经提到的段粒度 G就是段属性的一部分。 在对段进行各种访问时,将对访问是否合法进行检查,主要依据是段属性。例如: 如果向一个只读段进行写入操作,那么不仅不能写入,而且会引起异常。在下面 会详细说明各个段熟属性位的定义和作用。 <二>存储段描述符 用于表示上述定义段的三个参数的数据结构称为描述符。每个描述符长 8个字 节。在保护方式下,每一个段都有一个相应的描述符来描述。按描述符所描述的 对象来划分,描述符可分为如下三类:存储段描述符、系统段描述符、门描述符 (控制描述符)。下面先介绍存储段描述符。 1.存储段描述符的格式 存储段是存放可由程序直接进行访问的代码和数据的段。存储段描述符描述存储 段,所以存储段描述符也被称为代码和数据段描述符。存储段描述符的格式如下 表所示。表中上面一排是对描述符 8个字节的使用的说明,最低地址字节(假设 地址为 m)在最右边,其余字节依次向左,直到最高字节(地址为 m+7)。下一排是 对属性域各位的说明。 从上表可知,长 32 位的段基地址(段开始地址)被安排在描述符的两个域中,其 位 0—位 23 安排在描述符内的第 2—第 4字节中,其位 24—位 31 被安排在描述 符内的第 7字节中。长 20 位的段界限也被安排在描述符的两个域中,其位 0— 位 15 被安排在描述符内的第 0—第 1字节中,其位 16—位 19 被安排在描述符内 的第 6字节的低 4位中。 使用两个域存放段基地址和段界限的原因与 80286 有关。在 80286 保护方式下, 段基地址只有 24 位长,而段界限只有 16 位长。80286 存储段描述符尽管也是 8 字节长,但实际只使用低 6字节,高 2字节必须置为 0。80386 存储段描述符这 样的安排,可使得 80286 的存储段描述符的格式在 80386 下继续有效。 80386 描述符中的段属性也被安排在两个域中。下面对其定义及意义作说明。 (1)P 位称为存在(Present)位。P=1 表示描述符对地址转换是有效的,或者说该 描述符所描述的段存在,即在内存中;P=0 表示描述符对地址转换无效,即该段 不存在。使用该描述符进行内存访问时会引起异常。 (2)DPL 表示描述符特权级(Descriptor Privilege level),共 2位。它规定了 所描述段的特权级,用于特权检查,以决定对该段能否访问。 (3)DT 位说明描述符的类型。对于存储段描述符而言,DT=1,以区别与系统段描 述符和门描述符(DT=0)。 (4)TYPE 说明存储段描述符所描述的存储段的具体属性。 其中的位 0指示描述符是否被访问过(Accessed),用符号 A标记。A=0 表示尚未 被访问,A=1 表示段已被访问。当把描述符的相应选择子装入到段寄存器时, 80386 把该位置为 1,表明描述符已被访问。操作系统可测试访问位,已确定描 述符是否被访问过。 其中的位 3指示所描述的段是代码段还是数据段,用符号 E标记。E=0 表示段为 数据段,相应的描述符也就是数据段(包括堆栈段)描述符。数据段是不可执行的, 但总是可读的。 E=1 表示段是可执行段,即代码段,相应的描述符就是代码段 描述符。代码段总是不可写的,若需要对代码段进行写入操作,则必须使用别名 技术,即用一个可写的数据段描述符来描述该代码段,然后对此数据段进行写入。 在数据段描述符中(E=0 的情况),TYPE 中的位 1指示所描述的数据段是否可写, 用 W标记。 W=0 表示对应的数据段不可写。反之,W=1 表示数据段是可写的。注 意,数据段总是可读的。TYPE 中的位 2是 ED 位,指示所描述的数据段的扩展方 向。ED=0 表示数据段向高端扩展,也即段内偏移必须小于等于段界限。ED=1 表 示数据段向低扩展,段内偏移必须大于段界限。 在代码段描述符中(E=1 的情况),TYPE 中的位 1指示所描述的代码段是否可读, 用符号 R标记。R=0 表示对应的代码段不可读,只能执行。R=1 表示对应的代码 段可读可执行。注意代码段总是不可写的,若需要对代码段进行写入操作,则必 须使用别名技术。在代码段中,TYPE 中的位 2指示所描述的代码段是否是一致 代码段,用 C标记。C=0 表示对应的代码段不是一致代码段(普通代码段),C=1 表示对应的代码段是一致代码段。关于一致代码段的说明,后面的文章将会详细 介绍。 存储段描述符中的 TYPE 字段所说明的属性可归纳为下表: (5)G 为就是段界限粒度(Granularity)位。G=0 表示界限粒度为字节;G=1 表示 界限粒度为 4K 字节。注意,界限粒度只对段界限有效,对段基地址无效,段基 地址总是以字节为单位。 (6)D 位是一个很特殊的位,在描述可执行段、向下扩展数据段或由 SS 寄存器寻 址的段(通常是堆栈段)的三种描述符中的意义各不相同。 在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大 小。D=1 表示默认情况下指令使用 32 位地址及 32 位或 8位操作数,这样的代码 段也称为 32 位代码段;D=0 表示默认情况下,使用 16 位地址及 16 位或 8位操 作数,这样的代码段也称为 16 位代码段,它与 80286 兼容。可以使用地址大小 前缀和操作数大小前缀分别改变默认的地址或操作数的大小。 在向下扩展数据段的描述符中,D位决定段的上部边界。D=1 表示段的上部界限 为 4G;D=0 表示段的上部界限为 64K,这是为了与 80286 兼容。 在描述由 SS 寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如 PUSH 和 POP 指令)使用何种堆栈指针寄存器。D=1 表示使用 32 位堆栈指针寄存器 ESP; D=0 表示使用 16 位堆栈指针寄存器 SP,这与 80286 兼容。 (7)AVL 位是软件可利用位。80386 对该位的使用未左规定,Intel 公司也保证今 后开发生产的处理器只要与 80386 兼容,就不会对该位的使用做任何定义或规 定。 此外,描述符内第 6字节中的位 5必须置为 0,可以理解成是为以后的处理器保 留的。 2.存储段描述符的结构类型表示 根据存储段描述符的结构,可定义如下的汇编语言描述符结构类型: DESC STRUC LIMITL DW 0 ;段界限低 16 位 BASEL DW 0 ;基地址低 16 位 BASEM DB 0 ;基地址中间 8位 ATTRIB DB 0 ;段属性 LIMITH DB 0 ;段界限的高 4位(包括段属性的高 4位) BASEH DB 0 ;基地址的高 8位 DESC ENDS 利用结构类型 DESC 能方便地在程序中说明存储段描述符。例如:下面的描述符 DATAS 描述一个可读写的有效(存在的)数据段,基地址是 100000H,以字节为单 位的界限是 0FFFFH,描述符特权级 DPL=3。 DATAS DESC <0FFFFH,,10H,0F2H,,> 再如:下述描述符 CODEA 描述一个只可执行的有效的 32 位代码段,基地址是 12345678H,以 4K 字节位单位的段界限值是 10H(以字节位单位的界限是 10FFFH),描述符特权级 DPL=0。 CODEA DESC <10H,5678H,34H,98H,0C0H,12H> <三>全局和局部描述符表 一个任务会涉及多个段,每个任务需要一个描述符来描述,为了便于组织管理, 80386 把描述符组织成线性表。由描述符组成的线性表称为描述符表。在 80386 中有三种类型的描述符表:全局描述符表 GDT(Global Descriptor Table)、局 部描述符表 LDT(Local Descriptor Table)和中断描述符表 IDT(Interrupt Descriptor Table)。在整个系统中,全局描述符表 GDT 和中断描述符表 IDT 只 有一张,局部描述符表可以有若干张,每个任务可以有一张。 例如,下列描述符表有 6个描述符构成: DESCTAB LABEL BYTE DESC1 DESC <1234H,5678H,34H,92H,,> DESC1 DESC <1234H,5678H,34H,93H,,> DESC1 DESC <5678H,1234H,56H,98H,,> DESC1 DESC <5678H,1234H,56H,99H,,> DESC1 DESC <0FFFFH,,10H,16H,,> DESC1 DESC <0FFFFH,,10H,90H,,> 每个描述符表本身形成一个特殊的数据段。这样的特殊数据段最多可包含有 8K(8192)个描述符. 关于中断描述符表 IDT 在以后的文章中介绍。 每个任务的局部描述符表 LDT 含有该任务自己的代码段、数据段和堆栈段的描述 符,也包含该任务所使用的一些门描述符,如任务门和调用门描述符等。随着任 务的切换,系统当前的局部描述符表 LDT 也随之切换。 全局描述符表 GDT 含有每一个任务都可能或可以访问的段的描述符,通常包含描 述操作系统所使用的代码段、数据段和堆栈段的描述符,也包含多种特殊数据段 描述符,如各个用于描述任务 LDT 的特殊数据段等。在任务切换时,并不切换 GDT。 通过 LDT 可以使各个任务私有的各个段与其它任务相隔离,从而达到受保护的目 的。通过 GDT 可以使各任务都需要使用的段能够被共享。下图给出了任务 A和任 务 B所涉及的有关段既隔离受保护,又合用共享的情况。通过任务 A的局部描述 符表 LDTA 和任务 B的局部描述符表 LDTB,把任务 A所私有的代码段 CodeA 及数 据段 DataA 与任务 B所私有的代码段 CodeB 和数据段 DataB 及 DataB2 隔离,但 任务 A和任务 B通过全局描述符表 GDT 共享代码段 CodeK 及 CodeOS 和数据段 DataK 及 DataOS。 一个任务可使用的整个虚拟地址空间分为相等的两半,一半空间的描述符在全局 描述符表中,另一半空间的描述符在局部描述符表中。由于全局和局部描述符表 都可以包含多达8192个描述符,而每个描述符所描述的段的最大值可达4G字节, 因此最大的虚拟地址空间可为: 4GB*8192*2=64MMB=64TB <四>段选择子 在实模式下,逻辑地址空间中存储单元的地址由段值和段内偏移两部分组成。在 保护方式下,虚拟地址空间(相当于逻辑地址空间)中存储单元的地址由段选择子 和段内偏移两部分组成。与实模式相比,段选择子代替了段值。 段选择子长 16 位,其格式如下表所示。从表中可见,段选择子的高 13 位是描述 符索引(Index)。所谓描述符索引是指描述符在描述符表中的序号。段选择子的 第 2位是引用描述符表指示位,标记为 TI(Table Indicator),TI=0 指示从全局 描述符表 GDT 中读取描述符;TI=1 指示从局部描述符表 LDT 中读取描述符。 选择子确定描述符,描述符确定段基地址,段基地址与偏移之和就是线性地址。 所以,虚拟地址空间中的由选择子和偏移两部分构成的二维虚拟地址,就是这样 确定了线性地址空间中的一维线性地址。 选择子的最低两位是请求特权级 RPL(Requested Privilege Level),用于特权 检查。 RPL 字段的用法如下: 每当程序试图访问一个段时,要把当前特权级与所访问段的特权级进行比较,以 确定是否允许程序对该段的访问。使用选择子的 RPL 字段,将改变特权级的测试 规则。在这种情况下,与所访问段的特权级比较的特权级不是 CPL,而是 CPU 与 RPL 中更外层的特权级。 CPL 存放在 CS 寄存器的 RPL 字段内,每当一个代码段 选择子装入 CS 寄存器中时,处理器自动地把 CPL 存放到 CS 的 RPL 字段。 由于选择子中的描述符索引字段用 13 位表示,所以可区分 8192 个描述符。这也 就是描述符表最多包含 8192 个描述符的原因。由于每个描述符长 8字节,根据 上表所示选择子的格式,屏蔽选择子低 3位后所得的值就是选择子所指定的描述 符在描述符表中的偏移,这可认为是安排选择子高 13 位作为描述符索引的原因。 有一个特殊的选择子称为空(Null)选择子,它的 Index=0,TI=0,而 RPL 字段可 以为任意值。空选择子有特定的用途,当用空选择子进行存储访问时会引起异常。 空选择子是特别定义的,它不对应于全局描述符表 GDT 中的第 0个描述符,因此 处理器中的第 0个描述符总不被处理器访问,一般把它置成全 0。但当 TI=1 时, Index 为 0 的选择子不是空选择子,它指定了当前任务局部描述符表 LDT 中的第 0 个描述符。 <五>段描述符高速缓冲寄存器 在实模式下,段寄存器含有段值,为访问存储器形成物理地址时,处理器引用相 应的某个段寄存器并将其值乘以 16,形成 20 位的段基地址。在保护模式下,段 寄存器含有段选择子,如上所述,为了访问存储器形成线性地址时,处理器要使 用选择子所指定的描述符中的基地址等信息。为了避免在每次存储器访问时,都 要访问描述符表而获得对应的段描述符,从 80286 开始每个段寄存器都配有一个 高速缓冲寄存器,称之为段描述符高速缓冲寄存器或描述符投影寄存器,对程序 员而言它是不可见的。每当把一个选择子装入到某个段寄存器时,处理器自动从 描述符表中取出相应的描述符,把描述符中的信息保存到对应的高速缓冲寄存器 中。此后对该段访问时,处理器都使用对应高速缓冲寄存器中的描述符信息,而 不用再从描述符表中取描述符。 各段描述符高速缓冲寄存器之内容如下表所示。其中,32 位段基地址直接取自 描述符, 32 位的段界限取自描述符中 20 位的段界限,并根据描述符属性中的 粒度位转换成以字节为单位。其它十个特性根据描述符中的属性而定,“Y”表 示“是”,“N”表示“否” ,“R”表示必须可读,“W”表示必须可写,“P” 表示必须存在,“D”表示根据描述符中属性而定。 段描述符高速缓冲寄存器再处理器内,所以可对其进行快速访问。绝大多数情况 下,对存储器的访问是在对应选择子装入到段寄存器之后进行的,所以,使用段 描述符高速缓冲寄存器可以得到很好的执行性能。 段描述符高速缓冲寄存器之内保存的描述符信息将一直保存到重新把选择子装 载到段寄存器时再更新。程序员尽管不可见段描述符高速缓冲寄存器,但必须注 意到它的存在和它的上述更新时机。例如,在改变了描述符表中的某个当前段的 描述符后,也要更新对应的段描述符高速缓冲寄存器的内容,即使段选择子未作 改变,这可通过重新装载段寄存器实现。 二.分段管理机制
/
本文档为【保护模式】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索