← 返回 计组与微机控制

计组与微机控制

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.寄存器具体:

5.2 8086/8088 处理器寄存器 图 1

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 = 78H

3>. 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根地址线,重要

5.2 8086/8088 处理器寄存器 图 2

所以必须配合 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:DI

SS:堆栈段寄存器 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