计组与微机控制
5.3 8086/8088 的体系结构
5.3 8086/8088 的体系结构
8086/8088 采用全新的体系结构——指令流水线结构。
可以先把“流水线”理解成工厂流水线。
工厂生产一个产品,不是一个人从头做到尾,而是:
A 工人装外壳B 工人装电池C 工人检测D 工人包装
当 B 在处理第一个产品时,A 可以开始处理第二个产品。
这样整体速度就提高了。CPU 也是类似。
1. 传统方式的问题
传统 CPU 是:取第 1 条指令,执行第 1 条指令 取第 2 条指令,执行第 2 条指令 取指和执行不能重叠。
2. 8086/8088 的改进
8086/8088 把 CPU 分成两个相对独立的部分:
EU:执行单元 Execution Unit BIU:总线接口单元 Bus Interface Unit
这两个部分可以并行工作。也就是说:EU 正在执行当前指令时,BIU 可以提前去内存取后面的指令。这样就减少等待时间。

图 2.4:8086/8088 CPU 功能结构框图
图 2.4 中间有一条虚线。
虚线左边是 EU。 虚线右边是 BIU。
我们分别看。EU:执行单元
EU 的英文是 Execution Unit,执行单元。
它主要负责:
从指令队列中取出指令 译码指令 执行指令 进行算术逻辑运算 修改标志寄存器 使用通用寄存器
图中 EU 里面有:通用寄存器 操作数暂存器 ALU 标志寄存器 EU 控制器
1. EU 中的通用寄存器
图里写:
AX、BX、CX、DX、SP、BP、SI、DI
这些就是前面讲过的 8 个通用寄存器。
它们主要为执行指令服务。
比如:
ADD AX, BXEU 会使用 AX、BX 和 ALU 完成加法。
2>. 操作数暂存器
操作数暂存器可以理解成临时寄存器。
ALU 运算前,可能需要把参与运算的数据暂时放一放。
比如:ADD AX, BX
ALU 可能需要把 AX、BX 的内容送入内部暂存器,再进行加法。
这个过程程序员一般看不见,但硬件内部需要。
3>. ALU
ALU 是 EU 的核心。它负责:加减运算 逻辑运算 移位运算 比较运算
比如:
SUB AX, 1
AND AL, 0FH
CMP AX, BX这些都和 ALU 有关。
4>. 标志寄存器 FLAGS
ALU 运算后,经常会影响 FLAGS。
比如:ADD AL, 1
如果结果为 0,ZF 可能被置 1。 如果产生进位,CF 可能被置 1。 如果溢出,OF 可能被置 1。
所以 FLAGS 是 EU 执行结果的重要记录。
5>. EU 控制器
EU 控制器负责控制 EU 内部执行。
它会根据指令含义安排:
用哪个寄存器
让 ALU 做什么运算
结果写回哪里
是否修改 FLAGS
是否向 BIU 请求访问内存或 I/O1.BIU:总线接口单元
BIU 的英文是 Bus Interface Unit,总线接口单元。
它负责 CPU 和外部世界打交道。
外部世界主要包括:
内存 I/O 端口 外部总线
BIU 主要功能:
形成物理地址 从内存取指令 把指令放入指令队列 执行内存读写总线周期 执行 I/O 读写总线周期
图中 BIU 里面有:
段寄存器 CS、DS、ES、SS
指令指针 IP
地址形成与总线控制
指令队列
外部总线接口1>. 段寄存器和 IP 为什么在 BIU 里?
因为 BIU 负责访问内存,而访问内存必须形成物理地址。
取指令时要用:CS:IP
访问数据时可能用:
DS:偏移地址
访问栈时用:
SS:SP 或 SS:BP
字符串目的地址可能用:ES:DI
所以段寄存器和地址形成逻辑放在 BIU 这边。
2>. 地址形成与总线控制
BIU 要把段地址和偏移地址合成 20 位物理地址。
公式还是:
物理地址 = 段地址 × 16 + 偏移地址
形成地址后,BIU 通过外部地址总线把地址送出去。
同时通过控制总线发出读/写信号。
如果是读内存:
BIU 发地址 BIU 发读控制信号 内存把数据放到数据总线 BIU 接收数据
如果是写内存:
BIU 发地址 BIU 发写控制信号 BIU 把数据放到数据总线 内存写入数据
3>. 指令队列是什么?
图中右下角有一个“指令队列”。
8086 的指令队列是 6 字节。 8088 的指令队列是 4 字节。
它的作用是:提前存放从内存取来的指令字节。
BIU 会趁总线空闲时提前取指令,把取来的指令放入队列。
EU 执行指令时,就从这个队列里取指令,而不是每次都等内存现取。
这就是一种简单的预取机制。
4. 为什么 8086 队列是 6 字节,8088 是 4 字节?
8086 外部数据总线是 16 位,一次能取 2 个字节,取指效率较高,所以设置 6 字节队列。
8088 外部数据总线是 8 位,一次只能取 1 个字节,外部总线较窄,队列是 4 字节。
只需要记住:8086:6 字节指令队列。 8088:4 字节指令队列。
这是常考点。
EU 和 BIU 怎样配合?
这是最核心的内容。
课本的意思是:
EU 和 BIU 是既分工又合作的两个独立部件。
1. BIU 做什么?
BIU 主要负责“取货”和“送货”:
从内存取指令 把指令放进指令队列 根据 EU 的请求访问内存或 I/O 形成物理地址 控制外部总线
2. EU 做什么?
EU 主要负责“干活”:
从指令队列取指令 译码 执行 运算 修改标志 产生有效地址 需要访问内存时向 BIU 提请求
3. 一个典型过程
假设程序中有几条指令:
MOV AX, BX
ADD AX, 1
MOV [2000H], AX第一条:MOV AX, BX
这是寄存器之间传送,不需要访问内存数据。
EU 可以直接执行。
这时候 BIU 可以趁机继续取后面的指令。
第二条:ADD AX, 1
也是 CPU 内部完成。
EU 执行时,BIU 仍然可以预取指令。
第三条:
MOV [2000H], AX这条要把 AX 写入内存。
EU 发现需要访问内存,于是告诉 BIU:
我要写内存,偏移地址是 2000H,数据是 AX。
BIU 负责形成物理地址,并完成总线写周期。
4. 并行工作的本质
注意,8086/8088 这里的“并行”不是说它能同时执行两条指令。
它的意思是:执行当前指令和预取后续指令可以重叠。
也就是:EU 执行当前指令。 BIU 提前取后面的指令。
这样可以提高整体速度。
为什么这种结构叫指令流水线?
因为取指令和执行指令分开了。
传统方式:取指令 1 执行指令 1 取指令 2 执行指令 2
流水线方式:
取指令 1 执行指令 1 的同时,取指令 2 执行指令 2 的同时,取指令 3 执行指令 3 的同时,取指令 4
所以 CPU 不必每执行完一条指令才去取下一条。
BIU 可以提前把指令准备好。
为什么指令队列能提高速度?
因为很多指令执行时不需要访问外部总线。
比如:
ADD AX, BX
INC CX
MOV DX, AX这些主要在 CPU 内部完成。
这时候外部总线如果不用就浪费了。
BIU 就可以利用这些空闲时间去预取指令。
等 EU 执行完当前指令,要下一条指令时,指令队列里已经有了,不用等内存慢慢送来。
所以速度提高。
什么时候指令队列会失效?
虽然还没深入讲,但可以提前理解一个重要点:
如果程序顺序执行,BIU 预取的后续指令大概率会用上。
但如果遇到跳转指令,比如:
JMP 3000H原来队列里预取的是顺序后面的指令。
可是现在程序跳到别的地方了。
那么原来队列里的指令就没用了,需要清空队列,重新从新地址取指令。
所以流水线遇到跳转时,效率会下降。
这也是后来 CPU 分支预测等技术的背景。
总结: 微型计算机包括:
CPU 存储器 I/O 设备 总线
CPU 通过总线和内存、I/O 通信。
