一、 基于微处理器的微机系统软件模型
所谓微机系统软件模型,就是从软件编程的角度去看待微型计算机系统,也就是从编程使用的角度来考量危急中的微处理器、存储器及I/O系统,而不深究其内部电路结构的硬件细节。
微机系统软件模型所描述的对象包括微处理器的寄存器模型、存储器模型和I/O地址空间模型。这些都是用户可以用程序的方法访问和使用的危机系统资源,而那些用户不可以用程序的方法访问和使用的硬件资源(如微处理器的运算部件,流水线等)则不属于微机系统软件模型的范围。
微机系统软件模型概述
①从编程的观点来看待微机系统的硬件资源,可以简化对内部硬件细节的了解。例如,对微处理器,就只需着重了解他的可编程的寄存器的功能、使用方法,而对微处理器内部电路结构不必在意。
②使用微处理器的汇编语言编程,也必须从软件的观点去了解微处理器及其存储器子系统和I/O子系统的操作。掌握软件模型中寄存器的功能和使用方法、存储器的分段与分页机制和访问方法,以及I/O端口的读、写方法,对汇编语言程序设计至关重要。
③由于微处理器的活动(操作)都是靠软件来驱动的,用户编写什么样的程序就可以使微处理器产生什么样的活动(操作)。所以,用户对微机的应用,实际上就是用过自己的程序来实现。
④,从兼容性来看,强调功能上、逻辑上兼容,而不强调物理上的兼容即内部电路细节上的兼容,采用软件模型也是合适的。
二、实模式下微处理器的寄存器模型
先来看看下面图片:
图中不打阴影的部分表示在实模式下可以编程使用的寄存器,包括:
4个通用寄存器:AX、BX、CX、DX
6个段寄存器:CS、DS、SS、ES、FS、GS
2个指针寄存器:BP、SP
2个变址寄存器:SI、DI
1个指令指针:IP
1个标致寄存器:ELAGS
1个控制寄存器:CR0
下面来介绍个寄存器的作用和格式
①通用寄存器
实模式下的4个通用寄存器是:累加器(A)、基址寄存器(B)、计数寄存器(C)、数据寄存器(D)
作为16位使用时在寄存器名后面加X,如AX、BX、CX、DX等
作为32位使用是,则在16位的基础上加E,如:EAX、EBX、ECX、EDX。
4个寄存器各自具有不同的功能:
A寄存器猪腰用于存放程序执行过程中的一些中间结果,以及存放I/O数据
C寄存器在串、循环、循环移位、移位等操作中作计数寄存器
D寄存器也能存放地址信息,如存放I/O端口地址等
②段寄存器
段寄存器是为了存储器分段的需要而设置的,用于存放段基址,所有段寄存器都是16位的。因此段基址必须是16B的整数倍,并且段与段之间可以是连续的、相邻的、独立的或者是部分重合的。系统中可以同时有6个段被激活而处于工作状态,即:
1个代码段
1个堆栈段
4个数据段(D、E、F、G)
这些寄存器中保存的值被称为当前段寄存器值。
段寄存器内的数值可以由程序员通过软件加以改变。因此程序要访问存储器的哪个段,只需要将该段的段基址写入相关寄存器。例如:
要选用存储器中不同数据段空间的数据,只要改变数据段寄存器(DS、ES、FS和GS)中的数值即可。
同样的,当执行段间调用指令使程序发生转移时,就需要改变代码段寄存器CS的数值。
一段内存是否可以用来做代码的存储空间、数据的存储空间、还是做堆栈空间,主要是由微处理器中的段寄存器来指定。例如:
由CS与IP置顶为代码的存储空间
由DS与偏移置顶数据的存储空间
由SS与SP置顶为堆栈存储空间
③指令指针
实模式的指令指针IP为16位,它只是存储器中当前代码段内的偏移量,即代码与代码段段基址的距离。在实模式下,由微处理器把IP的偏移量和CS的当前值组合为指令代码的地址,故要访问代码的地址为CS:IP。可见,指令指针是存放程序代码的偏移地址的,而不是存放数据的。
④指针和变址寄存器
由于有些指令(算术、逻辑指令)的操作数在数据寄存器中,另一些指令(串指令)的操作数不在数据寄存器中,而在存储器内,因此,需要一些能够确定操作数在寄存器中的位置的寄存器。指针寄存器和变址寄存器就是用于存放偏移量地址,而不是存放数据的寄存器。他们分别以指针方式或变址方式选中存储器的64KB段内的具体存储单元。
指针寄存器(SP、BP)用于选取堆栈段内的具体存储单元,即指针寄存器的值指向堆栈段的栈顶或者栈内的具体存储单元;
变址寄存器(SI、DI)用于选取数据段内的具体存储单元,即变址寄存器的值指向存储器数据段或附加段内的存储单元。
所以,如果要访问存储器堆栈存储区,只要把SP或BP内的数值与堆栈段寄存器SS中内容合并成存储器物理地址即可。其中,栈顶指针SP或BP内的数值与堆栈段寄存器SS中内容合并成为存储器物理地址即可。其中栈顶指针SP与SS组合起来(SS:BP)形成20位地址指针,指向堆栈内的存储单元。
实模式下,BP经常用于读取堆栈内一些参数,传递给子程序,因而称为子程序参数传递的一种常用方法。为此,子程序内应包括使用基址寻址的指令,该指令将从堆栈里读取参数值。
另外两个变址寄存器SI和DI用于存放数据段的偏移地址。在指令中包含变址时,SI用于保存源操作数的偏移量地址,DI用于保存目标操作数的偏移地址。
⑤标志寄存器
先来看看标志寄存器的图片:
标志寄存器(ELAGS)是一个32位的寄存器,用于指示微处理器的状态并控制他的工作。标志寄存器在实模式下只使用9位,即下图:
它包括状态标志与控制标志两类。状态标志的逻辑状态取决于指令执行的结果,是自动产生的,其他指令可以使用这些标志来决定是否使用程序发生转移。控制寄存器是在程序中使用专门指令设置的,不是自动产生的,用来控制一些操作,如中断的开和关、地址的加与减的方向等。
⑴6位状态标志的作用
●进位标志位CF(Carry Flag)
当执行算术指令时,若其结果的最高位有进位或借位,则将CF置1;否则复位
●奇偶标志位PF(Parity Flag)
当操作结果中有偶数个1时,置1;否则,置0。
●辅助进位标志位AF(Auxlliary Carry Flag)
在8位、16位、32位二进制数内,若其较低字节中有低位半字节向高位半字节进位,
或者高位半字节借位给低位半字节,则将AF置1;否则,AF复位
●零标志位ZF(Zero Flag)
如果算术或者逻辑运算结果为零,则将ZF置1;否则,ZF复位
●符号标志位SF(Sign Flag)
记录运算结果的符号,若结果为负,则SF置1;否则,置0
●溢出标志位OF(Overflow Flag)
在运算时,若带符号的结果超出机器能够表示的范围,则OF置1;否则,置0
⑵3位控制标志的作用
●陷阱标志位TF(Trap Flag)
用于设置陷阱中断,若TF置1时,则在执行指令时产生单补中断,即CPU进入单步方式:
它执行一条指令后就跳到一个专用服务器程序上去,检查指令执行情况,用于程序调试。
●中断允许标志IF(Interrupt Flag)
当IF置1时,允许中断请求;当IF置0时,禁止中断请求
●方向标志位DF(Direction Flag)
决定串操作的方向。当DF置1时,串指令自动按减地址执行,即串数据传输过程是从高地址到低地址;
当DF置0时,串指令按增加地址执行,即串数据传输过程是从低地址到高地址。即:
在串处理时控制变址寄存器SI和DI递增或递减方式。
至于每次递增或者递减多少,取决于每次传输的是字节、字、双字
若是字节,则加/减1;
若是字,则加/减2;
若是双字,则加/减4;
三、 保护模式下微处理器的寄存器模型
先来看看下面的图片:
对比前面实模式下寄存器的图片可以发现:
保护模式寄存器模型是实模式寄存器模型集的一个超集,保护模式模型除了实模式中使用过的寄存器之外,新增了4个系统地址寄存器GDTR、IDTR、LDTR、TR和4个控制寄存器CR0~CR3。另外,一些寄存器的功能也得到了扩展,例如:指令指针为EIP,长度为32位;标志寄存器EFLAGS的更多位得到了利用。
系统地址寄存器
在保护模式下,微处理器内部新增了4个寄存器 GDTR、IDTR、LDTR和TR,这些寄存器是为了提供地址信息在确定全局描述符表GDT、中断描述符表IDT、局部描述符表LDT和任务状态段TSS等4种表格在存储器中的位置,故把他们叫做系统地址寄存器。
①全局描述符表寄存器GDTR用来在存储器地址空间定位一个全局描述符表GDT。GDTR的格式如下图:
从图中可以看出,GDTR长48位,由这个48位地址作为指针,直接指定GDT表在存储空间的位置。其中GDTR的高32位基地址Base,指示GDT在存储器中的开始位置。32为基址允许把GDT定位在线性地址空间的任何地方。
GDTR的低16位指示GDT的段限长Limit,它规定了GDT按字节计算的大小(Limit的值要比实际表小1。例如,如果Limit=00FFH,则表长为256B)。16位段限长允许GDT表最大可达65536B,因而最多能容纳8192个描述符(每个描述符长8B),实际应用中根据需要来确定GDT的长度。
中断描述符表寄存器
中断描述符表寄存器IDTR用来在存储器中定位一个中断描述符表IDT。IDTR也是48位长,由这个48位地址指针,直接指定IDT在存储器空间的位置。其中IDTR的高4个字节基地址Base,用于表示IDT在存储器中的起始地址,32位基地址允许IDT定位在线性地址空间的任何地方。
IDTR的低2个字节表示IDT的段限长Limit,以定义表的大小(表实际的大小等于Limit+1个字节)。可定义IDT的最大长度为65536字节长,但系统只支持256个中断和异常,所以,实际上IDT最大长度是2KB,以字节为单位的段界限为7FFH。
局部描述符表寄存器
局部描述符表寄存器LDTR并不直接指示局部描述符表LDT在寄存器中的位置,因此,他的格式与GDTR和IDTR都不同,LDTR的格式如下:
LDTR是16位长。这个16位的值是一个选择子,他指向存放GDT中的LDT的描述符。选择子不能直接定位LDT,只有描述符才能定位LDT。因此,当向LDTR中装入一个选择子是,相应的LDT的描述符就自动从GDT中读出来并装入LDTR的高速缓冲寄存器中(如上图中虚线框部分)。真正的LDT描述符就在这个高速缓冲寄存器中。它是64位的,其中32位的Base值只是LDT在存储器的起始地址,16位的Limit值指示LDT的大小,还有12位的Attribute值说明LDT的属性。
可见,LDT需要2次定位。首先利用LDTR中的选择子,在GDT中找到LDT的描述符,然后利用LDT的描述符,来定位LDT在存储器中的位置。
任务状态段寄存器
任务状态寄存器TR与LDTR类似,也不能直接指定任务状态段TSS在存储器空间的位置。
TR是16位长。这个16位的值也是一个选择子,不过这个选择子用来指示TSS段的描述符在GDT表中的位置的。找到了TSS段描述符,通过描述符就能够指定TSS段在存储器空间的位置了。因此,当选择子装入TR时,相应的TSS段的描述符就自动从全局描述符表GDT中读取并装入TR的高速缓冲寄存器中(如上图右侧虚线框部分)。这个高速缓冲寄存器为64位,它提供了TSS段的32位起始地址Base和TSS段的16位Limit以及TSS段的12位属性Attributte。
可见,TSS段也需要2次定位。首先,利用TR中的选择子,在GDT中找到TSS段的描述符,然后,利用TSS段的描述符,来定位TSS段在存储器中的位置。
控制寄存器
保护模式新增的4个32位控制寄存器CR0、CR1、CR2、CR3 ,是为了控制微处理器的工作方式和分段管理机制以及分页管理机制,如下图:
①控制寄存器CR0
CR0的主要功能是选择微处理器的工作方式和存储器的管理模式。各位的含义如下:
⑴保护模式允许置PE位
PE位控制微处理器是进入是模式还是进入保护模式,因此由叫做微处理器工作模式控制位。
PE置0,为实模式
PE置1,为保护模式
系统开机或者重启时PE清零,微处理器处于实模式。如果要进入保护模式,必须通过程序将PE置1
⑵分页管理启用位PG
PG控制禁止还是启用分页管理机制。
PG置0,禁止使用分页机制,此时由分段机制形成的线性地址作为物理地址;
PG置1,启用分页机制,此时线性地址还不是物理地址,线性地址必须经过分页转换后
才能形成物理地址。
如下图:
由于PG=1且PE=0是非法组合,即实模式下不能使用分页管理,只有保护模式下才能分页,因此,当用PG为1和PE为0的值装入CR0寄存器将引起通用保护异常。
⑶协处理器操作控制位(MP、EM、TS、ET)
CR0中的位1~位4分别标记为MP(算术存在位)、EM(模拟位)、TS(任务切换位)和ET(扩展类型位),他们控制浮点协处理器的操作。
②控制寄存器CR2
CR2 由分页管理机制使用,用于报告发生页故障时的出错信息。如果某页不在存储器中,则在页转换时会发生缺页故障,此时,微处理器把引起页故障的线性地址保存在CR2 中。操作系统中的页故障处理程序通过检查CR2 的内容,就可以查出是线性地址空间中的哪一页引起的故障。
③控制寄存器CR3
CR3 也是由业管理机制使用的,用于保存页表目录的起始物理地址。在确定页表目录在存储器空间的位置时,需要使用页表目录的基地址,CR3的高20位就是提供页表目录的基地址的,故称页表目录的基地址寄存器PDBR。由于基地址仅高2位有效,低12位不用,所以,向CR3中装入一个页表目录的其实物理地址(基地址)时,低12位必须为0;而从CR3中取值时,低12位被忽略。
改变功能的寄存器
一些在实模式和保护模式下都可以使用的寄存器,在切换到保护模式时,其功能会发生变化。
①段寄存器
段寄存器在保护模式下称为段选择子寄存器,仍然是16位,其值不在是段基址而是选择子。选择子并不直接置顶存储器地址,它选择一个定义存储器段的段基址、大小和属性的描述符。其具体格式以及作用到以后再研究。
值得指出的是,在保护模式下,每个段寄存器都是一个相应的高速缓冲寄存器,他对一般编程人员是不可见的。
②标志寄存器
在保护模式下标志寄存器EFLAGS长度扩充到32位,新增加了5位。如图:
这些新增的5位标志位只有在保护模式下使用。例如:输入/输出特权级码IOPL、嵌套任务标志NT、恢复标志RF,以及V86模式标志VM。
●IOPL(2位) 用来指定最大输入/输出特权级。
如果IOPL值为00,则只有在特权级0级才能访问I/O操作。
如果IOPL值为11,则I/O允许较低特权级访问。
●NT 指明当前任务是否嵌套,即是否被别的任务调用。该位在发生任务嵌套时自动设置,并且只能用软件复位。
●VM 指明VM位为1时,微处理器就处于V86模式。此时,其当前特权级由微处理器自动设置为3。
由于微处理器没有提供直接改变VM标志位的指令,并且只有当前特权级CPL=0时,对VM的改变才有效,
所以V86模式与保护模式的切换不能简单地通过改变VM位而进行。
●RF 恢复标志,与调试寄存器断点或单步操作一起使用。
●AC 对准检查标志,当AC=1时,且程序运行特权级为3时,对存储器访问边界进行对准检查。
●VIF 虚拟中断标志,在虚拟方式下中断标志只对Pentium机有效。
●VIP 虚拟中断暂挂标志,为Pentium微处理器提供有关虚拟模式中断的信息。它用于多任务环境下,
给操作系统提供虚拟中断标志和中断暂挂信息。
●ID 标识标志,指示Pentium微处理器支持CPUID指令。CPUID指令为系统提供有关Pentium微处理器的信息,
如:版本、制造商等。
程序不可见寄存器
32位微处理器中包含了一些不直接被应用程序访问的“程序不可见的寄存器”,又叫程序不可见高速缓冲寄存器(并不是微处理器中的一级或者二级高速缓冲存储器Cache),是用来保存描述符的。一个描述符包含段基址、段限长和段属性共8个字节64位长,因此,程序不可见高速缓冲寄存器也是8个字节。
6个段寄存器和任务寄存器TR,以及局部描述符表寄存器LDTR都分配了一个程序不可见高速缓冲寄存器,如下图虚线部分所示:
原来,每当用户在程序中向段寄存器(或TR、LDTR寄存器)装入一个新的选择子时,微处理器就会自动访问描述符表,从表中读取一个描述符,并把描述符装入该寄存器对应的程序不可见高速缓冲寄存器中。这个描述符一直保存在这里,并在访问存储器段时使用,知道段的选择子再次变化为止。这就使得微处理器在重复访问一个内存段时,不必每次都花时间到存储器中查找描述符表,而是直接快速地从程序不可以见寄存器中读取和使用描述符,因此称之为高速缓冲寄存器。
可见,程序不可见寄存器是用来提供描述符,以便指定存储段(代码段、数据段和堆栈段)、TSS段以及LDT段在存储器空间的具体位置的重要资源。虽然他们在程序中不出现,而由微处理器在内部直接操作,但是它们对定位与访问保护模式存储器的作用是不可忽视的。例如:
为了定位与访问任务状态段,在程序中只需要将TSS的选择子装入任务寄存器TR,如同选择子装入段寄存器一样。这个选择子会自动访问全局描述符表,从中读取TSS的描述符,并且将任务状态段TSS的基地址、段界限和访问权限装入LDTR高速缓冲寄存器。
至于为什么要把描述符以隐藏的方式存放在程序不可见告诉缓冲寄存器中,而不是放在显示的段寄存器中,其原因也许是为了使32位微处理器在保护模式下指令书写与在实模式下指令书写格式保持一致,都是向段寄存器写16位数据。虽然在16位数据的含义不同,在保护模式下入选择子时,也就同事向高速缓冲寄存器写入描述符,有了描述符也就等于有了段基址。
告诉缓冲寄存器是64位长,分3个字段(域),包括32位段基址,20位段限长和12位段属性。高速缓冲寄存器各字段的定义域格式如下图:
四、实模式存储器模型
存储器软件模型是从软件编程的角度去看存储器是什么样子的,也就是用户在编程时只考虑如何使用存储器,而不考虑它的硬件细节。存储器软件模型的内容包括:存储器空间、存储器的分段与分页、存储器的寻址和存储器物理地址的形成等。
实模式下存储器地址空间和数据组织
①实模式下存储地址空间
32位微处理器在实模式下,支持1MB存储器,从软件观点看这1MB的存储器是由00000H~FFFFFH地址编码(编号)的空间。数据以字节为单位存储在连续的地址码所组织的空间内,但可以连续两个字节(字长)和连续4个字节(双字长)来访问存储空间。
实模式的1MB存储空间都可以被用户访问,不过根据安排有些地址空间有专门用途,专用存储空间不能存储程序中的数据或者指令,如:00000H~003FFH区域专门用于存放中断向量表。通用区域可以存储程序的指令或者数据,通用区域的范围是400H~FFFFFH。
②实模式下存储器的数据组织
存储单元可以存放数字、字符和指令等信息。一个存储单元中存放的信息称为该存储单元的内容。如下图:
如果数据是以字节为单位存入存储器的,如上图中 0004H中存放的信息为34H,则表示为(0004)=34H。
如果数据是以字为单位存入存储器的,如上图中表示为(0004)=1234H。
所以,同一个地址即可看作是字节单元的地址,又可看作是字单元的地址,这要根据使用情况而定。
实模式存储器地址的分段
①实模式存储器地址的分段
实模式采用分段的办法来管理和使用存储器,每个段为64KB。因此,程序员在编写程序时要把存储器分成段,并在程序的开头设置各段寄存器的值,以定义所需要用到的几个段。一般情况下,各段的地址在存储器中的分配是由操作系统负责的。
值得注意的是: 实模式下的段不能起始于任意地址,而必须从字节地址的16的整数倍的任意一小段开始。
微处理器规定:从0开始,每16个字节为一小段,下面列出了存储器最低地址区的三个小段
的地址区间,每行为一小段。
其中,第一列就是每个小段的首地址。可以看出这个首地址是字节地址的16整数倍,若以十六进制表示,则最低位为0(即20位地址的低4位为0)。在1MB的地址空间里,共有64KB个小段首地址。
每个段可以独立占用64KB存储区,如下图:
同时,各个段也可以重叠,如下图:
下面说明段重叠的含义:
假设有一个存储区,包括一个代码段、数据段和堆栈段。代码段的首地址是2000H,代码长度为8KB,数据段的数长度只有256B。此时段的分配如上图所示。从上图可以看出来,代码段的最大区域可以是02000H~11FFFH,但由于代码长度只用了8KB,所以代码段结束后的第一个小段的首地址4000H就可以作为数据段的起始地址。也就是说,在这里,代码段和数据段可以重叠一起。同理,数据段的最大区域可以是04000H~13FFFH,但由于数据段只需要2KB,所以数据段结束后的第一个小段的首地址4800H就作为堆栈段起始地址。在这里,数据段和堆栈段又重叠在一起了。当然,每个存储单元的内容是不允许发生冲突的。在这里所谓的段重叠只是指每个段实际占用的大小可以根据实际需要来分配,而不一定占有64KB的最大段空间。
实际上,段区的分配工作是由操作系统完成的。但是系统也允许程序员在必要时指定需占用的内存区,例如:可由程序员指定代码段的起始位置(从100H地址开始)。
②实模式存储器逻辑地址
存储器逻辑地址也就是编程时所使用的地址,实模式的逻辑地址由段基址和偏移地址两部分组成,在程序中,段基址值用16位的段寄存器(CS、DS、SS、ES、FS、GS)表示,偏移量用16位的指令指针IP、基址寄存器BX、指针寄存器BP或变址寄存器SI/DI表示。例如:代码段逻辑地址表示为 CS:IP,数据段逻辑地址表示为 DS:BX,也可用其中几个寄存器的内容组合成一个偏移量。
段基址与偏移量的关系如下图:
其中,数据段寄存器DS中的段基址表示存储器中64KB的段的起始位置,即段中的最低位地址。BX寄存器中的偏移量是要访问的存储单元的位置与起始地址的距离。因此,段的最低地址的偏移量是0000H,最高地址的偏移量是FFFFH。
实模式下存储器寻址
实模式下只允许微处理器寻址第一个1MB存储器空间,因此第一个1MB存储器称为实模式存储器或者常规内存。
①段+偏移的寻址方案
这个不写了,太熟悉不过了,看下图:
②段+偏移的寻址组合的潜在规则
段+偏移的寻址组合,实际上就是段寄存器和偏移寄存器组合。微处理器对此有一套规则,用于访问不同的存储器段。这套规则既适用于实模式也适用于保护模式,该规则定义了各种寻址方式中,段地址寄存器和偏移地址存储器的组合方式。例如:
代码段寄存器总是和指令指针组合成 CS:IP用于寻址程序的下一条指令。
另外一种默认的组合用于堆栈。通过栈指针(SP)或基址针(BP)寻址寄存器堆栈段中的数据。这些组合用SS:SP或SS:BP表示。例如:
如果SS=2000h,BP=3000h,则微处理器寻址堆栈段寄存器的23000h单元。
实模式下,微处理器默认的段寄存器与偏移寄存器的组合如下图:
另外,微处理器内有一个叫“段超越前缀”的装置,可以改变上述寄存器和偏移寄存器的默认组合,
例如:
数据访问时可让ES寄存器作为数据段寄存器。
③段+偏移寻址方案允许重定位
可重定位的程序是一个可以放入存储器的任何区域且不加修改仍然能执行的程序,可重定位的数据是可以放在存储器的任何区域,且不需要修改就可以被程序引用的数据。
各种PC微型计算机系统的存储器结构可能不同,如果没有这个特性,若想要在不同的机子上运行程序,可能要大范围的重写或者更改,这将会是可怕的噩梦。
存储器用偏移地址在段内寻址,如果我们将整个存储器段移到存储器系统内的任何地方,只要将段寄存器内容改变为程序所移到的新存储器的地址,而不许改变其偏移地址。
例如:
一条指令位于距段首地址8个字节的位置,则它的偏移地址是8;整个程序一到新的存储器后,这个偏移地址8仍然指向距离段首地址8个字节的位置。
实模式下存储器物理地址的形成
①存储器物理地址的计算
不想多说,看下图:
②不同的逻辑地址可以映射成同一个物理地址
不解释。
五、保护模式存储器模型
①保护模式下虚拟存储器的地址空间
保护模式下,程序中使用的地址都是虚拟地址,因此虚拟地址也就是逻辑地址。32为微处理器支持虚拟地址空间为64TB。
在32位微处理器的存储器分段模型中,将存储器空间分成了全局和局部地址,各占32TB,并且各包含8192个段,每个段4GB,如图:
图中表示的是虚拟存储空间的最大值,但由于在实际应用中不是所有的描述符都在使用,所以实际使用的虚拟地址并没有这么大。
把虚拟地址空间分成全局和局部地址的目的是:
32位微处理器的多任务环境中,防止任务之间的相互干扰及破坏。当微处理器启动一个任务时,它可以访问全局存储器段也可以访问局部存储器段。全局地址空间,通常包含能被所有任务共享的资源和数据。局部地址空间的数据和代码只能被相应的任务访问,而不能被其他的任务访问,这就为防止任务之间的相互干扰及破坏提供了条件。
②保护模式下虚拟地址空间的分段
在保护模式下虚拟地址空间也采用分段方式,并使用48位存储器指针来表示虚拟地址空间,即在程序中用48位的存储器指针来访问存储器的地址单元。48位存储器指针包含16位选择子和32位偏移量,如图:
其中,选择子用来选择虚拟地址空间中的一个段,选择子为16位,只有14位用于选择存储器段,最多可达214=16K个段。偏移量是32位长,段最大可达232B=4GB。因此,正好可以表达整个虚拟地址空间16K x 4GB =64TB。
在实际应用中,一个程序所包含的段的个数是有限的,每个段的大小也不会大到4GB。因此大多数程序所占用的地址空间要比64TB小得多。
保护模式下的段可以从任意地址开始,而不像实模式下的段必须从字节地址16整数倍的地址开始。
保护模式下存储器寻址
①保护模式下存储器寻址方案
保护模式下存储器寻址既可以访问1MB的存储区(常规内存),又可以访问1MB以上的存储区(扩展内存)的数据和程序。但是寻址这个扩展段,需要修改用于实模式存储器寻址方案。
在寻址扩展内存里的数据和程序时,仍然使用段+偏移地址的寻址方案,并且偏移地址仍然用于访问存储器段内的存储单元。区别是,保护模式下的段基址不再像实模式那样由段寄存器直接提供,而是一种间接的方式,即在原来放段基址的段寄存器里放一个选择子,由选择子选择描述符表内的一个描述符,然后从描述符中获得段基址。因为描述符中包含了存储器段的基地址、长度和属性。
由于段+偏移地址仍然用于访问1MB存储器内的数据和程序,所以保护模式指令和实模式指令是完全相同的。事实上,很多在实模式下编写的程序,不用更改即可在保护模式下运行。
现在来对比一下保护模式下“段+偏移”寻址组合 和 实模式下 “段+偏移”寻址组合:
保护模式下“段+偏移”寻址组合:
实模式下 “段+偏移”寻址组合:
②段+偏移地址寻址组合的潜在规则
和实模式差不多,只是32位微处理器可以使用32位寄存器,显然保护模式下的选择范围更大。
保护模式下段式地址的转换
保护模式下虚拟地址使用48位地址指针表示。而保护模式下的物理地址是32位共4GB的地址空间。因此,在保护模式下,将虚拟地址转变成为物理地址,实际上就是将48位的虚拟地址转变为32位物理地址。
保护模式下也采用与实模式相同的“段+偏移地址”的寻址方案,转变过程如下:
选择子--->描述符表中的段描述符--->从段描述符中读取32位段基地址--->再加上偏移量--->得到32位线性地址
保护模式下存储器地址空间的分页
①分页方式
保护模式下分页方式中,物理地址被划分成1048496页,每页4096B长,如下图:
分页管理器的页的大小固定为4KB,与分段管理器的段的大小不固定不同。分页大大简化了存储管理的实现。需要提到的是CR0中的PE位和PG位及CR3中的页表目录基址寄存器(PDBR)是实现分页管理的关键,这些将在存储器管理中讨论。
②保护模式下页式地址转换
页式地址转换是把32位线性地址转换为32位物理地址。这里的线性地址和物理地址都是以页为单位的,每页4KB,4GB的线性地址和物理地址空间,都可分为1M页。线性地址空间的页称为虚页,物理地址空间的页称为实页,为此,采用页表进行映射。
六、实模式下I/O地址空间模型
32位微处理器实模式下的16位I/O地址范围是0000h~FFFFh,共64KB的地址,但在实模式下实用实际应用中只用了低10位地址,即1024个I/O端口地址。每个地址对应一个字节宽的I/O端口。
I/O地址空间的分布如图:
地址0000h~00FFh是0页空间。0页是I/O地址空间的第一个256B寻址空间。0页内的I/O地址空间指定为系统板上接口芯片的输入或输出数据传输操作。其他页内I/O地址空间指定为扩展卡的输入或输出数据传输操作。
七、保护模式下I/O地址空间模型
保护模式下I/O地址也是16位的,从0000h到FFFFh,共64KB的地址,能寻址64个8位端口,或32K个16位端口,或16K个64位端口。与实模式下I/O地址空间模型不同之处有两点:
①保护模式的I/O数据传输有字节宽度、字宽度和双字宽度,并且存储器空间可以独立编址,也可以统一编址;
②保护模式的I/O地址空间有保护措施,采用标志寄存器中的IOPL标志位和利用任务状态段TSS中的I/O允许位图两种措施来实现对I/O地址空间的保护。