计组与微机控制
5.2 8086/8088 处理器寄存器
5.2 8086/8088 处理器寄存器
8086/8088处理器:
1. 8086 是真正的 16 位微处理器,8088 是“准 16 位微处理器”
8086 的特点是:内部结构是 16 位。 外部数据总线也是 16 位。一次总线周期可以传送 16 位数据,也就是 1 个字。
所以 8086 内外都是 16 位。课本说 8088 是一个“准 16 位微处理器”。
为什么叫“准”,因为:8088 内部结构是 16 位。但是外部数据总线只有 8 位。
2.8086 和 8088 的核心区别
项目 | 8086 | 8088 内部结构 | 16 位 | 16 位 外部数据总线 | 16 位 | 8 位 一次总线周期可传 | 1 个字,16 位 | 1 个字节,8 位 软件兼容性 | 与 8088 兼容 | 与 8086 兼容 指令系统 | 相同 | 相同
所以从程序员角度看,8086 和 8088 很像。
它们的:寄存器体系 指令系统 指令编码格式 寻址方式
基本相同。但是硬件传输速度上,8086 通常比 8088 更有优势,因为 8086 外部数据总线更宽。
课本说 8086/8088 CPU 共有 14 个 16 位寄存器。
这 14 个寄存器分成三类:通用寄存器 8 个 控制寄存器 2 个 段寄存器 4 个
3.寄存器具体:

1>. AX:累加器 Accumulator
AX 常用于算术运算、逻辑运算、I/O 操作。
很多指令默认会使用 AX。
比如乘法、除法、输入输出指令,经常默认和 AX 或 AL 有关。
AX 可以拆成两个 8 位寄存器:
高 8 位:AH 低 8 位:AL
也就是:AX = AH + AL
如果 AX 是 16 位:
AX = 1234H
那么:AH = 12H AL = 34H (小端排序)
注意:H 表示十六进制。
2.> BX:基址寄存器 Base Register
BX 常用于存放地址的“基址”。
比如访问内存时,BX 可以参与形成有效地址。
可以理解成:
BX 经常用来指向一片数据的起始位置。
BX 也可以拆成:BH BL
例如:
BX = 5678H
BH = 56H
BL = 78H3>. CX:计数寄存器 Count Register
CX 常用于计数。
比如循环指令 LOOP 默认会用 CX 作为计数器。
例如:
MOV CX, 10表示循环次数准备设为 10。
然后每执行一次 LOOP,CX 通常会减 1。
CX 可以拆成:
CH CL
CL 还有一个常见用途:移位次数。
比如:
SHL AX, CL
表示把 AX 左移 CL 指定的位数。
4>. DX:数据寄存器 Data Register
DX 常用于存放数据,也常和 AX 配合。
比如乘法、除法中,DX 和 AX 经常组合成更长的数据。
例如 16 位乘法结果可能需要 32 位保存,这时候经常用:
DX:AX
表示高 16 位在 DX,低 16 位在 AX。
DX 也可以拆成:
DH DL
5>. AX、BX、CX、DX 的共同特点
这四个寄存器都是 16 位,但都能拆成两个 8 位寄存器。
16 位寄存器 | 高 8 位 | 低 8 位 AX | AH | AL BX | BH | BL CX | CH | CL DX | DH | DL
这点很常考。
比如:MOV AL, 12H
只会修改 AX 的低 8 位,不会影响 AH。
如果原来:AX = 3456H
执行:MOV AL, 12H
之后:AX = 3412H
因为 AH 仍然是 34H,AL 变成 12H。
七、SP、BP、SI、DI
这四个也是通用寄存器,但它们一般不能像 AX 那样拆成高低 8 位使用。
4. SP:堆栈指针 Stack Pointer
SP 用来指向栈顶。栈是一种特殊的内存区域,特点是:
后进先出。
在程序中,栈常用于:保存返回地址 保存临时数据 函数调用 中断处理
SP 永远和栈有关。
在 8086 中,栈的位置由:
SS:SP 共同决定。
SS 是栈段寄存器,SP 是栈内偏移地址。
BP:基址指针 Base Pointer
BP 也常和栈有关。
它经常用于访问栈中的参数或局部变量。
SP 指向栈顶,随着 PUSH、POP 会变化。
BP 通常作为一个稳定的基准,用来访问栈里的某个固定位置。比如函数调用时,经常用 BP 找参数。
所以:
SP 更像“当前栈顶在哪里”。 BP 更像“以某个固定位置为基准访问栈内容”。
SI:源变址寄存器 Source Index
SI 常用于字符串或数组操作,表示源地址。
比如从一段内存复制数据到另一段内存:
源地址可以由 SI 指向。
SI 的 S 是 Source,源。
DI:目的变址寄存器 Destination Index
DI 常用于表示目的地址。
DI 的 D 是 Destination,目的。
比如字符串传送:MOVSB
可以把 DS:SI 指向的一个字节传送到 ES:DI 指向的位置。
其中:SI 指向源 DI 指向目的
可以记:SI:从哪里来。 DI:到哪里去。
5.控制寄存器:IP 和 FLAGS
控制寄存器有:IP FLAGS
IP:指令指针 Instruction Pointer
IP 用来指出下一条要执行的指令在代码段中的偏移地址。
注意,IP 不是完整的物理地址。
8086 的真实物理地址是 20 位,但 IP 只有 16 位。
记住20根地址线,重要

所以必须配合 CS 使用。
也就是:
CS:IP 指向下一条要取的指令。
CS 是代码段寄存器。
IP 是代码段内的偏移量。FLAGS:标志寄存器
FLAGS 用来记录 CPU 执行结果的一些状态,以及控制 CPU 的某些行为。
比如:
结果是不是 0 有没有进位 有没有溢出 结果正负如何 是否允许中断 方向标志是什么
举例:
CMP AX, BX这个指令本质上比较 AX 和 BX。
比较完之后,CPU 不一定马上跳转,而是先修改 FLAGS 里的标志位。
然后下一条条件跳转指令根据 FLAGS 判断跳不跳。
例如:
JE label
意思是如果相等就跳转。
它怎么知道相等?
就是看 FLAGS 里的零标志位 ZF。
6.段寄存器:
图里段寄存器有:
CS DS ES SS
这是 8086/8088 非常重要的特点。
8086 有 20 根地址线,所以可以访问:
2^20 = 1MB也就是 1 MB 内存空间。
但是 8086 的寄存器是 16 位的。
16 位最多能表示:2^16 = 64KB
问题来了:16 位寄存器最多只能表示 64KB 地址,怎么访问 1MB 内存?
8086 的办法是:分段寻址。
用一个段寄存器表示“段的起点”,再用一个偏移地址表示“段内位置”。
最终形成 20 位物理地址。
物理地址怎么形成?
公式是:
物理地址 = 段地址 × 16 + 偏移地址
因为乘以 16 等价于十六进制左移一位。
也可以写成:
物理地址 = 段寄存器内容左移 4 位 + 偏移量
比如:
CS = 1234H
IP = 5678H那么下一条指令的物理地址是:
1234H × 10H + 5678H = 12340H + 5678H = 179B8H
所以 CS:IP = 1234:5678 对应的物理地址是 179B8H。
CS:代码段寄存器 Code Segment
CS 保存代码段的段地址。
CPU 取指令时,默认使用:
CS:IP
所以 CS 决定程序代码在哪个段,IP 决定下一条指令在这个段内的位置。
DS:数据段寄存器 Data Segment
DS 保存数据段的段地址。
一般访问普通数据时,默认使用 DS。
比如:
MOV AX, [1000H]通常表示从:
DS:1000H
这个地址取数据到 AX。
ES:附加段寄存器 Extra Segment
ES 是附加数据段。
它常用于字符串操作中的目的段。
比如字符串传送时,经常是:
源地址:DS:SI
目的地址:ES:DISS:堆栈段寄存器 Stack Segment
SS 保存栈段的段地址。
栈顶地址通常由:
SS:SP决定。
所以:
CS 管代码
DS 管数据
ES 管附加数据
SS 管堆栈CS 取指令,DS 取数据,SS 管堆栈,ES 作附加。
I/O 端口为什么是 64KB?
课本还说:
I/O 端口可扩展到 64KB,也就是 0 到 65535 个地址端口。
这是因为 8086/8088 的 I/O 端口地址空间是 16 位。
16 位可以表示:2^16 = 65536
也就是 64K 个端口地址。
所以:
内存地址空间:20 位,1MB I/O 端口空间:16 位,64K
