← 返回 计组与微机控制

计组与微机控制

5.6 段寄存器、指令寄存器和标志寄存器

5.6 段寄存器、指令寄存器和标志寄存器

5.6 段寄存器、指令寄存器和标志寄存器 图 1

CPU 要访问某个内存单元,必须知道:

它在哪个段?它在这个段内偏移多少?

也就是:段地址 + 偏移地址

段地址由段寄存器提供。
偏移地址由 IP、SP、BP、SI、DI、BX 或指令中的位移量等提供。

所以一个内存地址通常写成:段寄存器:偏移地址

例如:CS:IP DS:BX SS:SP ES:DI

一个程序可以有很多段,但当前最多有 4 个段

课本说,一个程序可以分成很多个存储段。

但是 CPU 运行的任意时刻,最多只能有 4 个“当前段”。

这 4 个当前段由 4 个段寄存器指出:

CS:当前代码段
DS:当前数据段
ES:当前附加段
SS:当前堆栈段

可以这样理解:

内存里可能有很多个房间。 但 CPU 手里当前只有 4 张“门牌号卡片”。 这 4 张卡片分别指向当前代码、当前数据、当前附加数据、当前堆栈。

CS、DS、ES、SS 的角色不能随便混

课本强调,这 4 个当前段的作用不能随便调换。

意思是:

CS 通常必须指向代码段,因为 CPU 取指令靠 CS:IP。
SS 通常必须指向堆栈段,因为 PUSH、POP、CALL、RET 等栈操作靠 SS:SP。
DS 和 ES 通常指向数据段或附加数据段。

尤其是 CS 很特殊。

你不能像普通寄存器一样直接:

MOV CS, AX

这在 8086 里是不允许的。

CS 通常通过跳转、调用、返回、中断等方式改变。

图 2.6:用段寄存器寻找存储段

图 2.6 左边画了 CS、DS、SS、ES 四个段寄存器。

右边是一条从:00000H 到 FFFFFH的内存空间。

因为 8086 有 20 位地址线,所以内存物理地址范围是:

00000H ~ FFFFFH

也就是 1MB。图中每个段寄存器都指向内存中的某个段基址。

然后通过偏移量找到段内具体单元。

段基址和偏移量

如果:DS = 2000H
偏移量 = 1234H那么物理地址是:

2000H × 10H + 1234H = 20000H + 1234H = 21234H

所以:DS:1234H → 物理地址 21234H

注意,这里的 2000H 不是直接作为物理地址用,而是要左移 4 位。

IP:指令指针寄存器

IP 是 Instruction Pointer,指令指针。

它的作用是:保存下一条将要执行的指令在当前代码段中的偏移地址。

所以取指令时用的是:CS:IP

CS 给出代码段的段基址。
IP 给出下一条指令在代码段内的偏移量。

IP 会自动变化

程序运行时,CPU 会自动修改 IP。

比如当前执行的指令长度是 3 个字节。

假设执行前:IP = 0100H

CPU 取完这条 3 字节指令后,IP 会自动变成:

IP = 0103H

这样下一次就能取下一条指令。

所以 IP 的变化通常不需要程序员手动完成。

普通程序不能直接访问 IP

课本强调:

一般编制的程序不能直接访问 IP。

也就是说,不能这样写:

MOV AX, IP
MOV IP, AX

这是不允许的。但是程序可以通过控制转移指令间接改变 IP。

比如:

JMP label
CALL subroutine
RET
INT 21H

这些指令会改变程序执行位置,所以会影响 IP。

图 2.7:IP 的功能

图 2.7 表达的是:

CS 指向代码段基址。
IP 指向代码段内某个偏移位置。
CS:IP 合起来找到正在执行或将要执行的指令。

执行完当前指令后,IP 自动指向下一条指令。

所以可以把 IP 想成:CPU 读代码时的书签。

CPU 执行程序就像读书,IP 指向下一句要读的位置。

----FLAGS:标志寄存器----

FLAGS 是 16 位标志寄存器,也叫程序状态字 PSW。

它的作用是:反映 CPU 执行运算后的状态,并控制某些 CPU 行为。

8086/8088 中常用的标志有 9 个。

5.6 段寄存器、指令寄存器和标志寄存器 图 2

其中 6 个是状态标志:

CF、PF、AF、ZF、SF、OF

其中 3 个是控制标志:

TF、IF、DF

这页开始讲 CF 和 PF。

状态标志和控制标志有什么区别?

状态标志是 CPU 运算后自动产生的结果状态。

比如:有没有进位?结果是不是 0? 结果符号是正还是负? 有没有溢出?

控制标志则是用来控制 CPU 行为的。

比如:

是否允许中断? 字符串操作方向是递增还是递减? 是否单步执行?

所以:

状态标志:反映结果 控制标志:控制行为

CF:进位标志 Carry Flag

CF 是 Carry Flag,进位标志。

它主要用于无符号运算。

课本说:当进行算术运算时,如果最高位产生进位或借位,则 CF = 1,否则 CF = 0。

对于字节操作,最高位是第 7 位。 对于字操作,最高位是第 15 位。

加法中的 CF

例如 8 位加法:AL = FFH AL + 01H

FFH 是二进制:1111 1111

加 1 后:1 0000 0000

低 8 位结果是:0000 0000

但是从第 7 位向外产生了进位。

所以:AL = 00H CF = 1

这表示无符号数加法超过了 8 位能表示的范围。

没有进位时 CF = 0

例如:AL = 12H AL + 34H = 46H

没有超过 8 位范围,没有向最高位外进位。

所以:CF = 0

减法中的 CF 表示借位

例如:AL = 00H AL - 01H

0 减 1 不够减,需要借位。

结果低 8 位会变成:FFH

并且:CF = 1

所以在减法中,CF = 1 表示发生借位。

CF 和无符号数有关

这个一定要注意。CF 主要用来看无符号数运算是否超范围。

比如 8 位无符号数范围是:0 ~ 255

如果:255 + 1 = 256

8 位装不下,CF = 1。

但如果你把数看成有符号数,就要更多关注 OF,而不是 CF。

这个后面讲 OF 时会更清楚。

移位指令中 CF 的作用

课本还说,CF 也可以在移位类指令中使用。

例如左移:1000 0001 左移 1 位

最高位的 1 被移出去。

这个被移出去的位会进入 CF。

所以 CF 还可以保存:

左移时从最高位移出的位,或右移时从最低位移出的位。

PF:奇偶标志 Parity Flag

PF 是 Parity Flag,奇偶标志。

课本说:当操作结果低 8 位中 1 的个数为偶数时,PF = 1;否则 PF = 0。

这里有两个关键词:

低 8 位 1 的个数为偶数

PF 只看低 8 位

这点很容易考。不管你做的是 8 位运算还是 16 位运算,PF 都只检查结果的低 8 位。

比如结果是:AX = 1234H

低 8 位是:34H

所以 PF 只看 34H 对应的二进制,不看 12H。

偶数个 1,则 PF = 1

例如结果低 8 位是:0000 0011

里面有两个 1。 2 是偶数,所以:

PF = 1,再比如:

1010 0001 里面有 3 个 1。

3 是奇数,所以:PF = 0

PF 的名字为什么叫“奇偶”?

它检测的是结果中 1 的个数是奇数还是偶数。但要注意:

8086 中是 偶校验逻辑:

偶数个 1 → PF = 1
奇数个 1 → PF = 0

很多人会误以为“奇偶标志”里“奇”对应 1,这是错的。

要记:偶数个 1,PF 置 1。

这几页新增重点其实可以压缩成下面几条。

第一,通用寄存器按常见用途分成三类:

AX、BX、CX、DX:数据寄存器
SP、BP:指针寄存器
SI、DI:变址寄存器

第二,AX、BX、CX、DX 可以拆成高低 8 位:

AH/AL,BH/BL,CH/CL,DH/DL

第三,某些指令会隐含使用固定寄存器:

LOOP 默认使用 CX
移位次数默认用 CL
乘除法常用 AX、DX
PUSH/POP 默认用 SP
串操作源地址用 SI,目的地址用 DI

第四,SP 和 BP 都常用于栈:

SS:SP 指向栈顶
BP 常用于访问栈中数据

第五,SI 和 DI 常用于串操作:

DS:SI → ES:DI

第六,段寄存器指出当前段:

CS:代码段
DS:数据段
ES:附加段
SS:堆栈段

第七,IP 指向下一条指令的偏移地址:

CS:IP

第八,FLAGS 记录状态和控制 CPU 行为,目前讲了:

CF:进位/借位标志
PF:低 8 位中 1 的个数为偶数则置 1

题型 1:哪些寄存器可以拆成 8 位?

答案:AX、BX、CX、DX

对应:AH/AL,BH/BL,CH/CL,DH/DL

SP、BP、SI、DI 不能这样拆。

题型 2:LOOP 指令默认使用哪个寄存器?

答案:CX

执行一次 LOOP,CX 减 1。
如果 CX 不为 0,就跳转。
如果 CX 为 0,就继续向下执行。

题型 3:移位次数大于 1 时,次数放在哪里?

答案:CL

例如:SHL AX, CL SAR AX, CL

题型 4:PUSH、POP 隐含使用哪个寄存器?

答案:SP

并且栈地址由:SS:SP决定。

题型 5:串操作中源地址和目的地址分别由谁给出?

答案:源地址:DS:SI 目的地址:ES:DI

题型 6:下一条指令地址由什么决定?

答案:CS:IP

CS 给代码段基址。
IP 给段内偏移量。

题型 7:CF 什么时候置 1?

答案:加法最高位产生进位时,CF = 1。
减法最高位产生借位时,CF = 1。
移位时,移出的那一位也可能进入 CF。

题型 8:PF 看什么?

答案:PF 只看结果低 8 位中 1 的个数。

偶数个 1 → PF = 1
奇数个 1 → PF = 0