80386控制寄存器和地址寄存器如下表所示。它们用于控制工作方式,控制分段管理机制及分页管理机制的实施。
控 制 寄存器 |
CRx |
BIT31 |
BIT30—BIT12 |
BIT11—BIT5 |
BIT4 |
BIT3 |
BIT2 |
BIT1 |
BIT0 |
CR0 |
PG |
0000000000000000 |
ET |
TS |
EM |
MP |
PE |
CR1 |
保留 |
CR2 |
页故障线性地址 |
CR3 |
页目录表物理页码 |
000000000000 |
|
BIT47—BIT16 |
BIT15—BIT0 |
全局描述符表寄存器GDTR |
基地址 |
界限 |
中断描述符表寄存器IDTR |
基地址 |
界限 |
|
BIT15—BIT0 |
局部描述符表寄存器LDTR |
选择子 |
任务状态段寄存器TR |
选择子 | |
|
BIT31—BIT0 |
BIT31—BIT0 |
BIT11—BIT0 |
基地址 |
界限 |
属性 |
基地址 |
界限 |
属性 | |
<一>控制寄存器
从上表可见,80386有四个32位的控制寄存器,分别命名位CR0、CR1、CR2和CR3。但CR1被保留,供今后开发的处理器使用,在80386中不能使用CR1,否则会引起无效指令操作异常。CR0包括指示处理器工作方式的控制位,包含启用和禁止分页管理机制的控制位,包含控制浮点协处理器操作的控制位。CR2及CR3由分页管理机制使用。CR0中的位5—位30及CR3中的位0至位11是保留位,这些位不能是随意值,必须为0。
控制寄存器CR0的低16位等同于80286的机器状态字MSW。
1.保护控制位
控制寄存器CR0中的位0用PE标记,位31用PG标记,这两个位控制分段和分页管理机制的操作,所以把它们称为保护控制位。PE控制分段管理机制。PE=0,处理器运行于实模式;PE=1,处理器运行于保护方式。PG控制分页管理机制。PG=0,禁用分页管理机制,此时分段管理机制产生的线性地址直接作为物理地址使用;PG=1,启用分页管理机制,此时线性地址经分页管理机制转换位物理地址。关于分页管理机制的具体介绍在后面的文章中进行。
下表列出了通过使用PE和PG位选择的处理器工作方式。由于只有在保护方式下才可启用分页机制,所以尽管两个位分别为0和1共可以有四种组合,但只有三种组合方式有效。PE=0且PG=1是无效组合,因此,用PG为1且PE为0的值装入CR0寄存器将引起通用保护异常。
需要注意的是,PG位的改变将使启用或禁用分页机制,因而只有当所执行的的代码和至少有一部分数据在线性地址空间和物理地址空间具有相同的地址的情况下,才能改变PG位。
PG和PE 位与处 理器工 作模式 |
PG |
PE |
处理器工作方式 |
0 |
0 |
实模式 |
0 |
1 |
保护模式,禁用分页机制 |
1 |
0 |
非法组合 |
1 |
1 |
保护方式,启用分页机制 |
2.协处理器控制位
控制寄存器CR0中的位1—位4分别标记为MP(算术存在位)、EM(模拟位)、TS(任务切换位) 和ET(扩展类型位),它们控制浮点协处理器的操作。
当处理器复位时,ET位被初始化,以指示中数字协处理器的类型。如果中存在 80387协处理器,那么ET位置1;如果中存在80287协处理器或者不存在协处理器,那么ET位清0。
EM位控制浮点指令的执行是用软件模拟,还是由硬件执行。EM=0时,硬件控制浮点指令传送到协处理器;EM=1时,浮点指令由软件模拟。
TS位用于加快任务的切换,通过在必要时才进行协处理器切换的方法实现这一目的。每当进行任务切换时,处理器把TS置1。TS=1时,浮点指令将产生设备不可用(DNA)异常。 MP位控制WAIT指令在TS=1时,是否产生DNA异常。MP=1和TS=1时,WAIT产生异常;MP=0时,WAIT指令忽略TS条件,不产生异常。
3.CR2和CR3
控制寄存器CR2和CR3由分页管理机制使用。
CR2用于发生页异常时报告出错信息。当发生页异常时,处理器把引起页异常的线性地址保存在CR2中。操作中的页异常处理可以检查CR2的内容,从而查出线性地址空间中的哪一页引起本次异常。
CR3用于保存页目录表的其始物理地址。由于目录是页对齐的,所以仅高20位有效,低12 位保留未用。向CR3中装入一个新值时,低12位必须为0;但从CR3中取值时,低12位被忽略。每当用MOV指令重置CR3的值时,会导致分页机制高速缓冲区的内容无效,用此方法,可以在启用分页机制之前,即把PG位置1之前,预先刷新分页机制的高速缓存。CR3寄存器即使在CR0寄存器的PG位或PE位为0时也可装入,如在实模式下也可设置CR3,以便进行分页机制的初始化。在任务切换时,CR3要被改变,但是如果新任务中CR3的值与原任务中CR3的值相同,那么处理器不刷新分页高速缓存,以便当任务共享也表时有较快的执行速度。
<二>地址寄存器
全局描述符表GDT、局部描述符表LDT和中断描述符表IDT等都是保护方式下非常重要的特殊段,它们包含有为段机制所用的重要表格。为了方便快速地定位这些段,处理器采用一些特殊的寄存器保存这些段的基地址和段界限。我们把这些特殊的寄存器称为地址寄存器。
1.全局描述符表寄存器GDTR
如本文开始处的表格所示,GDTR长48位,其中高32位为基地址,低16位为界限。由于GDT 不能有GDT本身之内的描述符进行描述定义,所以处理器采用GDTR为GDT这一特殊的段提供一个伪描述符。GDTR给定了GDT,如下图所示。
GDTR中的段界限以字节为单位。由于段选择子中只有13位作为描述符索引,而每个描述符长8个字节,所以用16位的界限足够。通常,对于含有N个描述符的描述符表的段界限设为8*N-1。
利用结构类型可定义伪描述符如下:
PDESC STRUC
LIMIT DW 0
BASE DD 0
PDESC ENDS
2.局部描述符表寄存器LDTR
局部描述符表寄存器LDTR规定当前任务使用的局部描述符表LDT。如本文开始处的表格所示,LDTR类似于段寄存器,由员可见的16位的寄存器和员不可见的高速缓冲寄存器组成。实际上,每个任务的局部描述符表LDT作为的一个特殊段,由一个描述符描述。而用于描述符LDT的描述符存放在GDT中。在初始化或任务切换过程中,把描述符对应任务LDT的描述符的选择子装入LDTR,处理器根据装入LDTR可见部分的选择子,从GDT中取出对应的描述符,并把LDT的基地址、界限和属性等信息保存到LDTR的不可见的高速缓冲寄存器中。随后对LDT的访问,就可根据保存在高速缓冲寄存器中的有关信息进行合法性检查。
LDTR寄存器包含当前任务的LDT的选择子。所以,装入到LDTR的选择子必须确定一个位于GDT中的类型为LDT的段描述符,也即选择子中的TI位必须是0,而且描述符中的类型字段所表示的类型必须为LDT。
可以用一个空选择子装入LDTR,这表示当前任务没有LDT。在这种情况下,所有装入到段寄存器的选择子都必须指示GDT中的描述符,也即当前任务涉及的段均由GDT中的描述符来描述。如果再把一个TI位为1的选择子装入到段寄存器,将引起异常。
3.中断描述符表寄存器IDTR
中断描述符表寄存器IDTR指向中断描述符表IDT。如本文开始处的表格所示,IDTR长48 位,其中32位的基地址规定IDT的基地址,16位的界限规定IDT的段界限。由于80386只支持256个中断/异常,所以IDT表最大长度是2K,以字节位单位的段界限为7FFH。IDTR 指示IDT的方式与GDTR指示GDT的方式相同。
4.任务状态段寄存器TR
任务状态段寄存器TR包含指示描述当前任务的任务状态段的描述符选择子,从而规定了当前任务的状态段。任务状态段的格式在后面的文章中介绍。如本文开始处的表格所示,TR也有员可见和不可见两部分。当把任务状态段的选择子装入到TR可见部分时,处理器自动把选择子所索引的描述符中的段基地址等信息保存到不可见的高速缓冲寄存器中。在此之后,对当前任务状态段的访问可快速方便地进行。装入到TR的选择子不能为空,必须索引位于GDT中的描述符,且描述符的类型必须是TSS。