版权声明:本文章参考了唐朔飞的《 计算机组成原理》未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!
1 Intel CPU的发展里程碑Created with Raphaël 2.2.0 4位4004 8位8008 16位8086 32位80386 64位Pentium
字:一般说来,CPU在同一时间内处理的一组二进制数称为一个计算机的“字”,而这组二进制数的位数就是“字长”。通常称处理字长为8位数据的CPU叫8位CPU,32位CPU就是在同一时间内处理字长为32位的二进制数据。
Intel CPU 系列,最初是 4 位微处理器 4004,然后到到 8 位微处理器的 8008,再到 8 位微处理器 8080,以及稍后的 16 位微处理器 8086,由 8086 开始,Intel 进入现在所谓的x86时代 。
Intel 8086 为 16 位 CPU ,地址总线为20根,寻址能力为220*1B=1MB。因为在 8086 之前的 CPU 都是 8 位 CPU,这样也就造成了很多的外设也只支持 8 位,因此 Intel 紧接着就推出了 8 位的 8088 CPU。如果是单从汇编语言的角度上来说,8086 和 8088 是没有区别的,即8086上跑的程序可以不加修改的移植到8088,8088上跑的程序也可以不加修改的移植到8086上,当然,还是有些特殊的地方是不同的,而这些基本上在这里可以忽略掉.
在 8088 CPU 之后,Intel 又推出了 80186 ,80286 ,这两款 CPU 均是 16 位 CPU 。简单来说80186只是8086增加了一些指令, 但 80286 则不同,80286 的地址总线数目达到了 24 根,从而最大寻址能力为 2 24 2^{24} 224bit即 16MB,由于支持更多的物理内存寻址,因此 80286 便开始成为了多任务,多用户系统的核心。
在80286之后,Intel 又推出了 80386 ,80386 为 32 位微处理器,Intel 80×86 家族的 32 位微处理器始于 80386;同时 80386 也完全兼容先前的 8086/8088,80186,80286,并且 80386 全面支持 32 位数据类型和 32 位操作,80386 的数据总线根数和地址总线根数均达到了 32 根,从而可以最大物理寻址为 232bit 即 4GB 。
而之后的 80486 也是 32 位微处理器,而后又出来了 Pentium 和 Pentium Pro 等等第五代微处理器,这些处理器虽然也是32位微处理器,但是他们的数据总线和地址总线都有所扩展,比如 Pentium 的数据总线达到 64 位,而 Pentium Pro 的地址总线位数达到了 36 位 。
详细信息参考《CPU的发展历史》。
2 16位CPU标准寄存器8086的可编程寄存器包括:
通用寄存器包括数据寄存器、指针寄存器、变址寄存器。除完成规定的专门用途外,均可用于传送和暂存数据,可以保存算术逻辑运算的操作和运算结果。通用寄存器的长度取决于机器字长。
16位cpu通用寄存器共有8个:AX、BX、CX、DX、BP、SP、SI、DI。八个寄存器都可以作为普通的数据寄存器使用。但有的有特殊的用途:AX为累加器,CX为计数器,BX,BP为基址寄存器,SI,DI为变址寄存器,BP还可以是基指针,SP为堆栈指针。
由于之前的 CPU 为 8 位 CPU,所以为了兼容以前的 8 位程序,在 8086 CPU 中,每一个数据寄存器都可以当做两个单独的寄存器来使用,由此,每一个 16 位寄存器就可以当做 2 个独立的 8 位寄存器来使用了 。
16位CPU具有4个16位数据寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。
AX 寄存器也叫做累加寄存器,此外还具有的特殊用途是在使用 DIV 和 MUL 指令时使用。
BX 寄存器也叫基址寄存器,可以暂存一般的数据。
BX 主要还是用于其专属功能:寻址(寻址物理内存地址)上,BX 寄存器中存放的数据一般是用来作为偏移地址使用的。在 8086 CPU 中,CPU 是根据 <段地址:偏移地址> 来进行寻址操作的,而 BX 中存放的数据表示的是偏移地址的话,自然,便可以通过 <段地址:[BX]> 的方式来完成寻址操作了。
CX 寄存器也叫计数寄存器,可以暂存一般性的数据。
在位操作中,当移多位时,要用CL来指明移位的位数;
当在汇编指令中使用循环 LOOP 指令时,可以通过CX 来指定需要循环的次数,而 CPU 在每一次执行 LOOP 指令的时候,都会做两件事:一件就是令 CX = CX – 1,即令 CX 计数器自动减去 1;还有一件就是判断 CX 中的值,如果 CX 中的值为 0 则会跳出循环,而继续执行循环下面的指令,当然如果 CX 中的值不为 0 ,则会继续执行循环中所指定的指令 。
DX 寄存器也叫数据寄存器,可以暂存一般性的数据
当在使用 DIV 指令进行除法运算时,如果除数为 16 位时,被除数将会是 32 位,而被除数的高 16 位就是存放在 DX 中,而且执行完 DIV 指令后,本次除法运算所产生的余数将会保存在 DX 中,
在执行 MUL 指令时,如果两个相乘的数都是 16 位的话,那么相乘后产生的结果显然需要 32 位来保存,而这32 位的结果的高 16 位就是存放在 DX 寄存器中 。
寄存器BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
寄存器SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们也可作一般的指针存储器使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。
16位CPU的段寄存器是16位,是根据内存分段管理模式而设置的。
保护模式下逻辑地址由段寄存器的值(也就是段选择符)和一个偏移量组合而成的。通过段选择符可以找到段描述符,进而找到段基址,线性地址=段基址+偏移量。
ES为附加段寄存器。CS为代码段寄存器。SS为堆栈段寄存器。DS为数据段寄存器。
指令指IP(Instruction Pointer)寄存器是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。逻辑地址=CS:IP
标志寄存器在16位CPU中用于反映处理器的状态和运算结果的某些特征,其中只有9位有定义)这些标志位分为两类:
运算结果标志位
进位标志CF(Carry Flag)——进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。
奇偶标志PF(Parity Flag)——奇偶标志PF用于反映运算结果中&#8221;1&#8243;的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。
辅助进位标志AF(Auxiliary Carry Flag)——在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
零标志ZF(Zero Flag)——零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。
符号标志SF(Sign Flag)——符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。
溢出标志OF(Overflow Flag)——溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。
状态控制标志位——状态控制标志位是用来控制CPU操作的,它们要通过专门的指令才能使之发生改变。
追踪标志TF(Trap Flag)——当追踪标志TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。指令系统中没有专门的指令来改变标志位TF的值,但程序员可用其它办法来改变其值。
中断允许标志IF(Interrupt-enable Flag)——中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。CPU的指令系统中也有专门的指令来改变标志位IF的值。具体规定如下:
方向标志DF(Direction Flag)——方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。当其为0时,si、di寄存器增大;当其为1时,si、di寄存器减小
80386共提供7种类型的可编程寄存器,如下:
80386有8个32位的通用寄存器,这8个通用寄存器都是由8086相应16位通用寄存器扩展成32位而得,用法相似。名字分别是:EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP。每个寄存器可以掰成两个16位寄存器使用,也可以掰成4个8位寄存器使用。
在16位CPU中,数据寄存器不能作为指针寄存器,在32位CPU中,其数据寄存器不仅可传送数据、暂存数据、保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。
80386有6个16位段寄存器,分别是:CS(代码段寄存器),DS(数据段寄存器),SS(堆栈段寄存器),ES、FS 、GS(附加数据段寄存器)。前4个段寄存器的名称与8086相同,在实地址方式下使用方式也和8086相同。80386又增加了FS与GS,主要为了减轻对DS段和ES段的压力。除CS支持代码段,SS支持堆栈段外,程序员可以利用其它的所有段寄存器支持数据段。
段寄存器中存放的不再是某个段的基地址,而是某个段的选择符(Selector)。因为16 位的寄存器无法存放32位的段基地址,段基地址只好存放在段的描述符(Descriptor)中。
每个段寄存器对应这一个64位段描述符寄存器,这在8086中是没有的,它的作用是快速访问段描述符。当段寄存器载入段选择符时,64位的段描述符寄存器就载入GDT中的对应的段描述符。
80386的指令指针寄存器EIP是一个32位寄存器,是从8086的IP寄存器扩充而来。EIP中存放下一条将要执行指令的偏移量(offset),这个偏移量是相对于目前正在运行的代码段寄存器(CS)而言的。偏移量加上当前代码段的基地址,就形成了下一条指令的地址。
80386的标志寄存器EFLAGS也是一个32位寄存器,其中只使用了15位,从8086的FLAGS寄存器扩展而来。如下图所示:
OF、DF、IF、TF、SF、ZF、AF、PF和CF在8086中就已经存在,请参考上面2.3.2 标志寄存器。
下面的标志位是80286新增的标志位
IOPL(I/O Privilege Level)是从80286开始出现的,占2个bit表示I/O特权级,如果当前特权级小于或等于IOPL,则可以执行I/O操作,否则将出现一个保护性异常。IOPL只能由特权级为0的程序或任务来修改。
NT(Nested Task)也是从80286开始出现的,表示嵌套任务,用于控制中断返回指令IRET,当NT=0时,用堆栈中保存的值恢复EFLAGS、CS和EIP,从而实现返回;若NT=1,则通过任务切换实现中断返回。
下面的标志位是80386新增的标志位
VM(Virtual-8086 mode)表示虚拟8086模式,如果VM被置位且80386已处于于保护模式下,则CPU切换到虚拟8086模式,此时,对段的任何操作又回到了实模式,如同在8086下运行一样。
RF(Resume flag)表示恢复标志(也叫重启标志),与调试寄存器一起用于断点和单步操作,当RF=1 时,下一条指令的任何调试故障将被忽略,不产生异常中断。当RF=0时,调试故障被接受,并产生异常中断。用于调试失败后,强迫程序恢复执行,在成功执行每条指令后,RF自动复位。
下面的标志位是80486新增的标志位
下面的标志位是Pentium新增的标志位
80386有4个系统地址寄存器,用来存储操作系统需要的保护信息和地址转换表信息、定义目前正在执行任务的环境、地址空间和中断向量空间。由于只能在保护方式下使用,因此又称为保护方式寄存器。
注:GDT表里面的每一项都表明一个段的信息,或者是一个LDT表的相关信息。其实一个LDT表也是一个段。所以也可以说GDT表的每一项都描述一个段。就像一个文件夹下面可以有文件,也可以有文件夹一样,GDT表里面既可以有段描述符,也可以有LDT的表。
中断描述符表寄存器IDTR(Interrupt Descriptor Table Register),是48 位寄存器,用来保存中断描述符表(IDT)的32 位基地址和IDT 的大小(16位)。(中断描述符表最大为216B,共216B/8B=8K个中断描述符)。
局部描述符表寄存器LDTR(Local Descriptor Table Register ),是16 位寄存器,保存局部描述符表LDT 段的选择符。一旦16位的选择符(也叫选择子)放入LDTR,CPU会自动将选择符所指定的局部描述符装入64位的局部描述符寄存器中。
任务状态寄存器TR(Task State Register)是16 位寄存器,用于保存任务状态段TSS段的16位选择符。与LDTR类似,一旦16位的选择符放入TR,CPU会自动将该选择符所指定的任务描述符装入64位的任务描述符寄存器中。
LDT和TSS都是一个段,所以在GDT中有对应的表项描述。LDTR和TR是由16位选择字段和64位描述符寄存器组成。用来指定局部描述符表和任务状态段TSS在物理存储器中的位置和大小。64位描述符寄存器是自动装入的,程序员不可见。LDTR与TR只能在保护方式下使用,程序只能访问16位选择符寄存器。(注意区分描述符表寄存器与描述符寄存器)。
IDTR是48位的(大于32位),与GDTR位数一样,大于32位的结构自然就有4G内任意寻址的能力。所以可以直接访问中断向量表,不需要通过选择子(16位结构)来间接寻找。所以IDT表可以与GDT表完全独立,不需要像LDT一样还要在GDT表建立相关表项。但是TSS段和LDT表两个结构就不行,他们的寄存器只有16位,不可能在4G内存中任意寻址,所以只能将其插入到GDT表中,然后借用GDT和自身的选择子的组合来间接寻址。
80386的控制寄存器有4个:CR0(机器状态字)、CR1(Intel 预留)、CR2(页故障地址)、CR3(页目录地址)。其中CR1保留以后使用,从Pentium开始,又增加了一个CR4。
CR0的低16位包含了与80286的MSW一致的位定义,保持了和80286的兼容,同时也兼容了从80286开始的两条指令LMSW/SMSW
下面四个定义从80286开始存在。
下面的2个定义从80386开始存在
下面的4个定义从80386开始存在
CR1保留未用。
CR2存放引起页故障的线性地址,只有在PG=1时,CR2才有效,当页故障处理程序被激活时,压入页故障处理程序堆栈中的错误码提供页故障的状态信息。
CR3的高20位存放页目录的基地址,因为也目录总是页对齐的(一页为4K),所以页目录基地址从bit12开始就可以了。只有当CR0中的PG=1时,CR3的页目录基地址才有效。
CR4是从Pentium CPU开始出现的。
一共有8个调试寄存器DR0-DR7,DR0-DR3可以分别设置4个断点的线性地址,DR4-DR5保留未用,DR6是断点状态寄存器,DR7是断点控制寄存器(包括断点类型、断点长度,断点开放/禁止)
一共有8个测试寄存器TR0-TR7,TR0-TR2保留,TR3-TR5用作CACHE测试,TR6为命令测试寄存器,TR7为测试数据寄存器。
4 64位CPU标准寄存器版权声明:本文章参考了唐朔飞的《 计算机组成原理》未经作者允许,严禁用于商业出版,否则追究法律责任。网络转载请注明出处,这是对原创者的起码的尊重!!!