← 返回 计组与微机控制

计组与微机控制

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 可以提前去内存取后面的指令。这样就减少等待时间。

5.3 8086/8088 的体系结构 图 1

图 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, BX

EU 会使用 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/O

1.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 通信。