在执行单元EU和总线接口单元BIU中一共有14个寄存器,其中通用寄存器8个、标志寄存器FLAGS一个、控制寄存器5个,其中指令队列虽然不是寄存器但也需要重点说明一下:
1. 指令队列的工作原理:
指令队列的存储空间为6byte,8086为16位CPU意味着一条指令需要2个字节存储(16bit=2byte),指令队列一旦有2个空字节BIU就会到内存中去取指令存入指令队列中。当EU执行一条需要到存储器或I/O端口读取操作数的指令时,BIU将在执行完现行取指令的存储器周期后的下一个存储周期,对指令所指定的存储单元或I/O端口进行访问,读取的操作数经BIU送EU进行处理。当EU执行跳转、子程序调用或返回指令时,BIU就使指令队列复位,并从指令给出的新地址开始取指令,新取的第1条指令直接经指令队列送EU执行,随后取来的指令将填入指令队列缓冲器。
2. 指令队列出现的意义以及缺陷:
指令队列的出现可以降低CPU访问内存或者接口的速度,从而使得对存储器和接口要求降低并且其造价更加的低廉,指令预取队列的出现开创了指令执行流水线的先河,使得一条有一条的指令在执行时更快速的无缝衔接。但是其自身的缺陷在于:预取队列预取的只是指令并没有预取指令执行所需的参数,因此当指令涉及参数的执行时指令执行流水线不可避免的断流,断流的情况如下所示:
1) 指令预取队列中有转移类指令
2) 执行指令需要参数
当指令的执行需要参数时(比如:加法),EU得去获得了参数才可以顺利执行指令,因此此时的并行流水线依旧存在着断流的情况。
3)执行单元执行速度较慢
EU还未执行完一条指令,BIU中的预取队列已经填充完毕。
8个通用寄存器再进行细分,又可划分为数据寄存器(AX~DX)、栈顶指针寄存器(SP)、基址寄存器(BP)、DI(目标变址寄存器)、SI(源变址寄存器)。
1. 数据寄存器(AX、BX、CX、DX)
16位的数据寄存器可以拆成2个8位寄存器(例如:AX->AH+AL等)来使用,但是一定要注意“8086为16位寄存器,8位寄存器中存放的一定是数据不可能是地址,因为16位寄存器的地址一定是16位的,哪怕地址为0那也是16位的0”。除此之外,16位的数据寄存器可以依据专用功能再进行细分:
① AX:累加寄存器,该寄存器存取速度为CPU通用寄存器中之最,因此AX常用作累加结果的存放处,也被称为累加器;
② BX:基址寄存器,当间接寻址时16位的BX寄存器作为基地址的专用存放处;
③ CX:计数寄存器,循环操作时CX中存放的是循环次数记录值;
④ DX:数据寄存器,在I/O端口间接寻址当中,16位的DX寄存器存放I/O的间接地址,此外,DX还存储32位运算(两个16位相乘)中结果的高16位。
具体来讲AX和DX寄存器在运算中的作用:
DIV 在 8086 CPU 中是除法指令,而在使用除法的时候有两种情况,即除数可以是 8 位或者是 16 位的。除数可以存放在寄存器中或者是内存单元中,被除数放在AX中。当除数是 8 位时,被除数一定会是 16 位的,并且默认是放在 AX 寄存器中;而当除数是 16 位时,被除数一定是 32 位的,其中高16位放到DX中,低16位放在AX中。当除法指令执行完成以后,如果除数是 8 位的,则在 AL 中会保存此次除法操作的商,而在 AH 中则会保存此次除法操作的余数;如果除数是 16 位的话,则 AX 中会保存本次除法操作的商,而 DX 则保存本次除法操作的余数。
MUL 在8086CPU中是乘法指令,在做乘法运算时,两个相乘的数要么都是 8 位,要么都是 16 位。如果两个相乘的数都是 8 位的话,则一个默认是放在 AL 中,而另一个 8 位的乘数则位于其他的寄存器或者说是内存字节单元中;而如果两个相乘的数都是 16 位的话,则一个默认存放在 AX 中,另一个则是某个寄存器中或者是某个内存字单元中。当 MUL 指令执行完毕后,如果是 8 位的乘法运算,则默认乘法运算的结果是保存在 AX 中;如果是 16 位的乘法运算的话,则默认乘法运算的结果有 32 位,其中高位默认保存在 DX 中,而低位则默认保存在 AX 中。
综上所述:
数据寄存器符号 |
数据寄存器专用名称 |
专用情形 |
专用作用 |
AX |
累加寄存器 |
累加 |
累加结果存放处 |
BX |
基址寄存器 |
间接寻址 |
存放基地址 |
CX |
计数寄存器 |
循环操作 |
存放计数值 |
DX |
数据寄存器 |
IO端口的间接寻址 |
IO端口地址 |
32位数据运算 |
运算结果高16位 |
2. 基址寄存器(BP)
基址寄存器顾名思义是专用(间接寻址)时用于存放段基地址(逻辑段段首地址)所用,在通用时BP中存放的是数据,不可以拆分为两个8位寄存器。
3. 栈顶指针寄存器(SP)
当程序中使用堆栈区时,SP中存放的16位二进制数据为指向堆栈段栈顶的地址,在通用时SP中存放的是数据,不可以拆分为两个8位寄存器。BX和BP的区别如下所示:
寄存器符号 |
寄存器专用名称 |
地址指向数据的所在段类型 |
SP |
栈顶指针寄存器 |
堆栈段 |
BP |
基址寄存器 |
数据段 |
4. 变址寄存器(SI、DI)
变址寄存器中存放的地址可以指向代码段、数据段、附加段中的任意位置,不存放专用地址,因此也被称为变址寄存器。在通用时SI和DI中存放的是数据,不可以拆分为两个8位寄存器。
16位标志寄存器中有9位有效位,分别为6位状态标志位和3位控制标志位。
6位状态标志位记录了算术和逻辑运算的一些特征(例如:结果是否为0,是否有进位,借位,结果是否溢出等):
其中,要注意CF有效表明无符号数计算溢出(无符号位计算判断溢出的依据:最高位进位),OF有效表明有符号数计算溢出(有符号位计算判断溢出的依据:次高位和最高位进位/借位状态不同)。
控制标志位表征着CPU的运行状态:
陷阱标志位:表征CPU正处于单步运行状态,即每运行一条语句就会进入一次中断,也就是我们软件中常用的单步调试;
中断允许标志位:也成为中断屏蔽标志位,用于确定某个中断是否被允许(允许则为1);
方向标志位:表明了操作串的操作方向,操作串顾名思义就是一系列在内存上连续分布数据进行连续操作(数据串是存储器中一块字节或字的存储区域,其长度可以是1字节一64K字节;串操作就是对数据串中每个元素所进行的操作,这种操作通常是组合操作,能完成几条指令的功能)。
段寄存器一共有四个(代码段寄存器CS、数据段寄存器DS、附加段寄存器ES、堆栈段寄存器SS),其存储的地址分别指向代码段段首、数据段段首、附加段段首、堆栈段段首。
通用寄存器:
AX:accumulate register——累加器
BX:based register——基地址寄存器
CX:count register——计数器
DX:data registered——数据寄存器
段寄存器:
CS:code segment——代码段
DS:data segment——数据段
SS:stack segment——栈段寄存器
ES:extra segment——附加段寄存器
特殊功能寄存器:
IP:instructor point——指令指针寄存器
SP:stack point——堆栈指针寄存器
BP:base point——基础指针
SI:source index——源变址寄存器
DI:destination index——目的变址寄存器
PSW:program state word——程序状态字
FLAGS寄存器的9个有效标志位:
OF(11位-overflow flag-溢出标志位):OV(overflow-溢出)/NV(not overflow-没溢出)
DF(10位-direction flag-方向标志位):DN(down-下方)/UP(up-上方)
IF(9位-interrupt flag-中断标志位):EI(enable interrupt-允许中断)/DI(disabled interrupt-不允许中断)
TF(8位-trap flag-陷阱标志位)
SF(7位-sign flag-负号标志位):NG(negative-负)/PL(plus-正)
ZF(6位-zero flag-零值标志位):ZR(zero-为零)/NZ(not zero-不为0)
AF(4位-auxiliary carray flag-辅助进位标志位):AC(auxiliary carry-有辅助进位)/NA(not auxiliary carry-没有辅助进位)
PF(2位-parity flag-奇偶标志位):PE(parity even-偶)/PO(parity odd-奇)
CF(0位-carry flag-进位标志位):CY(carried-有进位)/NC(not carried-没进位)