串传送指令
MOVSB
功能
以字节为单位传送串
实现
- ( ( E S ) ∗ 16 + ( D I ) ) = ( ( D S ) ∗ 16 + ( S I ) ) ((ES) * 16 + (DI)) = ((DS) * 16 + (SI)) ((ES)∗16+(DI))=((DS)∗16+(SI))
- 如果 DF = 0 ,则 ( S I ) = ( S I ) + 1 (SI) = (SI) + 1 (SI)=(SI)+1 , ( D I ) = ( D I ) + 1 (DI) = (DI) + 1 (DI)=(DI)+1 。如果 DF = 1 ,则 ( S I ) = ( S I ) − 1 (SI) = (SI) - 1 (SI)=(SI)−1 , ( D I ) = ( D I ) − 1 (DI) = (DI) - 1 (DI)=(DI)−1
MOVSW
功能
以字为单位传送串
实现
- ( ( E S ) ∗ 16 + ( D I ) ) = ( ( D S ) ∗ 16 + ( S I ) ) ((ES) * 16 + (DI)) = ((DS) * 16 + (SI)) ((ES)∗16+(DI))=((DS)∗16+(SI))
- 如果 DF = 0 ,则 ( S I ) = ( S I ) + 2 (SI) = (SI) + 2 (SI)=(SI)+2 , ( D I ) = ( D I ) + 2 (DI) = (DI) + 2 (DI)=(DI)+2 。如果 DF = 1 ,则 ( S I ) = ( S I ) − 2 (SI) = (SI) - 2 (SI)=(SI)−2 , ( D I ) = ( D I ) − 2 (DI) = (DI) - 2 (DI)=(DI)−2
REP 指令
REP 指令常和串传送指令搭配使用
功能
根据 CX 的值,重复执行后面的指令
标志寄存器
结构
- FLAG 寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息
- 8086 CPU 中没有使用 FLAG 的 1、3、5、12、13、14、15 位,这些位不具有任何意义
作用
- 用来存储相关指令的某些执行结果
- 用来为 CPU 执行相关指令提供行为依据
- 用来控制 CPU 的相关工作方式
查看寄存器的值
在 DEBUG 环境下使用 R 指令查看
含义
标志 | 值为 1 | 值为 0 | 意义 | 备注 | |
---|---|---|---|---|---|
Overflow | OF | OV | NV | 溢出 | |
Direction | DF | DN | UP | 方向 | |
Sign | SF | NG | PL | 符号 | positive / negative |
Zero | ZF | ZR | NZ | 零值 | |
Parity | PF | PE | PO | 奇偶 | odd / even |
Carry | CF | CY | NC | 进位 |
直接访问标志寄存器的方法
- PUSHF 将标志寄存器的值压栈
- POPF 从栈中弹出数据,送入标志寄存器
ZF 零标志(Zero Flag)
ZF 标记相关指令的计算结果是否为 0
- ZF = 1 表示“结果是0”,1 表示“逻辑真”
- ZF = 0 表示“结果不是0”,1 表示“逻辑假”
在 8086 CPU 的指令集中的应用
- 有的指令的执行是影响标志寄存器的,比如 : ADD , SUB , MUL , DIV , INC , OR , AND 等,大都是运算指令,进行逻辑或算数运算
- 有的指令对标志寄存器没有影响,比如 :MOV, PUSH, POP等,它们大都是传送指令
- 使用一条指令的时候,要注意这条指令的全部功能,其中包括执行结果对标记寄存器的哪些标志位造成影响。
PF 奇偶标志(Parity Flag)
- PF 记录指令执行后,结果的所有二进制位中 1 的个数
- 1 的个数为偶数 ,PF = 1
- 1 的个数为奇数 ,PF = 0
SF 符号标志(Sign Flag)
- SF 记录指令执行后,将结果视为有符号数
- 结果为负,SF = 1
- 结果为非负数,SF = 0
有符号数与补码
- 计算机中有符号数一律用补码来表示和存储
- 正整数的补码是其二进制表示,与原码相同
- 负整数的补码,是将其对应二进制的所有位取反(包括符号位)后加 1
- 例如 正数5 (00000101) 所有位取反后 (11111010) 后加 1 得到 -5 的补码 (11111011)
SF 标志是 CPU 对有符号数操作结果的一种记录
将数据当作有符号数来运算的时候,通过 SF 可知结果的正负;将数据当作无符号数来运算,SF 的值则没有意义,虽然相关的指令影响了它的值。
CF 进位标志(Carry Flag)
- 在进行无符号数运算 时,CF 记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值
- CF记录执行后,有进位或借位时 CF = 1,无进位或借位时 CF = 0
- 对于位数为 N 的无符号数来说,其对应的二进制的最高位即第 N − 1 N-1 N−1 位,是最高有效位
- 假想存在的第 N 位,就是相对最高有效位的更高位
SUB 寄存器 , 寄存器
不能用MOV 寄存器 , 0
替代,SUB 寄存器 , 寄存器
可以使 CF 为 0- ADD 指令不能替代 多个 INC 指令,INC 指令不会造成进位,不会影响 CF 标志位,而 ADD 指令会影响。
OF 溢出标志(Overflow Flag)
- 在进行有符号数运算的时候,如果结果超过了机器所能表示的范围称为溢出
- OF 记录有符号数操作指令执行后,有溢出时 OF = 1,无溢出时 OF = 0
机器所能表达的范围
- 以 8 位运算为例,如果用 8 位寄存器或内存单元来存放,机器所能表示的范围就是 [ − 128 , 127 ] [-128,127] [−128,127]
- 同理,对于 16 位有符号数,机器所能表示的范围是 [ − 32768 , 32767 ] [-32768,32767] [−32768,32767]
CF 和 OF 的区别
- CF 是对无符号数运算有意义的进/借位标志位
- OF 是对有符号数运算有意义的溢出标志位
DF 方向标志位(Direction Flag)
功能
- 在串处理指令中,控制每次操作后 SI 和 DI 的增减
- DF = 0 时,每次操作后 SI 和 DI 都递增
- DF = 1 时,每次操作后 SI 和 DI 都递减
对 DF 位进行设置的指令
- CLD 指令 : 将标志寄存器的 DF 位设置为 0 (clear)
- STD 指令 : 将标志寄存器的 DF 位设置为 1 (setup)
带进(借)位的加减法
ADC 带进位加法指令
ADC 是带进位加法指令,它利用了 CF 位上记录的进位值
格式
ADC 操作对象1 , 操作对象2
功能
操作对象 1 = 操作对象 1 + 操作对象 2 + C F 操作对象1 = 操作对象1 + 操作对象2 + CF 操作对象1=操作对象1+操作对象2+CF
SBB 带借位减法指令
格式
SBB 操作对象1 , 操作对象2
功能
操作对象 1 = 操作对象 1 − 操作对象 2 − C F 操作对象1 = 操作对象1 - 操作对象2 - CF 操作对象1=操作对象1−操作对象2−CF
与 SUB 的区别
SBB 利用了 CF 位上记录的借位值
CMP 和 条件转移指令
CMP 指令
- CMP 是比较指令,功能相当于减法指令,只是不保存结果
- CMP 指令执行后,将对标志寄存器产生影响
格式
CMP 操作对象1 , 操作对象2
功能
计算 操作对象 1 − 操作对象 2 操作对象1 - 操作对象2 操作对象1−操作对象2
例
指令 | CMP AX , AX |
---|---|
功能 | 做 (AX) - (AX) 的运算,结果为 0 ,但并不在 AX 中保存,仅影响 FLAG 的相关各位 |
标志寄存器 | ZF = 1 , PF = 1 , SF = 0 , CF = 0 , CF = 0 |
应用方法
用标志寄存器值,确定比较结果
无符号数比较与标志位取值
比较关系 | (AX) ? (BX) | (AX) - (BX) 特点 | 标志寄存器 |
---|---|---|---|
等于 | ( A X ) = ( B X ) (AX) = (BX) (AX)=(BX) | ( A X ) − ( B X ) = 0 (AX) - (BX) = 0 (AX)−(BX)=0 | ZF = 1 |
不等于 | ( A X ) ≠ ( B X ) (AX) \not = (BX) (AX)=(BX) | ( A X ) − ( B X ) ≠ 0 (AX) - (BX) \not = 0 (AX)−(BX)=0 | ZF = 0 |
小于 | ( A X ) > ( B X ) (AX) > (BX) (AX)>(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 将产生借位 | CF = 1 |
小于等于 | ( A X ) ≤ ( B X ) (AX) \leq (BX) (AX)≤(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 或者借位,或者结果为 0 | CF = 1 或 ZF = 1 |
大于 | KaTeX parse error: Undefined control sequence: \textgreater at position 6: (AX) \̲t̲e̲x̲t̲g̲r̲e̲a̲t̲e̲r̲ ̲(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 既不借位,结果也不为 0 | CF = 0 且 ZF = 0 |
大于等于 | ( A X ) ≥ ( B X ) (AX) \geq (BX) (AX)≥(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 不必借位 | CF = 0 |
比较指令的设计思路
通过做减法运算影响标志寄存器,标志寄存器的相关位的取值,体现比较的结果
有符号数比较与标志位取值(不完善)
仅凭结果正负(SF)无法得出结论,需要配合是否溢出(OF)得到结论
比较关系 | (AX) ? (BX) | (AX) - (BX) 特点 | 标志寄存器 |
---|---|---|---|
等于 | ( A X ) = ( B X ) (AX) = (BX) (AX)=(BX) | ( A X ) − ( B X ) = 0 (AX) - (BX) = 0 (AX)−(BX)=0 | ZF = 1 |
不等于 | ( A X ) ≠ ( B X ) (AX) \not = (BX) (AX)=(BX) | ( A X ) − ( B X ) ≠ 0 (AX) - (BX) \not = 0 (AX)−(BX)=0 | ZF = 0 |
小于 | ( A X ) > ( B X ) (AX) > (BX) (AX)>(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 将产生借位 | SF = 1 且 OF = 0 |
小于等于 | ( A X ) ≤ ( B X ) (AX) \leq (BX) (AX)≤(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 或者借位,或者结果为 0 | SF = 0 或 OF = 1 |
大于 | KaTeX parse error: Undefined control sequence: \textgreater at position 6: (AX) \̲t̲e̲x̲t̲g̲r̲e̲a̲t̲e̲r̲ ̲(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 既不借位,结果也不为 0 | SF = 1 且 OF = 1 |
大于等于 | ( A X ) ≥ ( B X ) (AX) \geq (BX) (AX)≥(BX) | ( A X ) − ( B X ) (AX) - (BX) (AX)−(BX) 不必借位 | SF = 0 且 OF = 0 |
条件转移指令
套路
所有影响标志寄存器的指令 + 条件转移指令
字符 | 含义 |
---|---|
J | Jump |
E | Equal |
N | Not |
B | Below |
A | Above |
L | Less |
G | Greater |
S | Sign |
C | Carry |
P | Parity |
O | Overflow |
Z | Zero |
根据单个标志位转移的指令
指令 | 含义 | 转移条件 |
---|---|---|
JE / JZ | 相等 / 结果为 0 | ZF = 1 |
JNE / JNZ | 不等 / 结果不为 0 | ZF = 0 |
JS | 结果为负 | SF = 1 |
JNS | 结果非负 | SF = 0 |
JO | 结果溢出 | OF = 1 |
JNO | 结果溢出 | OF = 0 |
JP | 奇偶位为 1 | PF = 1 |
JNP | 奇偶位不为 1 | PF = 0 |
JB / JNAE / JC | 低于 / 不高于等于 / 有借位 | CF = 1 |
JNB / JAE / JNC | 不低于 / 高于等于 / 无解位 | CF = 0 |
根据无符号数比较结果进行转移的指令
指令 | 含义 | 转移条件 |
---|---|---|
JB / JNAE / JC | 不高于则转移 | CF = 1 |
JNB / JAE / JNC | 低于则转移 | CF = 0 |
JNA / JBE | 不高于则转移 | CF = 1 或 ZF =1 |
JA / JNBE | 高于则转移 | CF = 0 且 ZF = 0 |
根据有符号数比较结果进行转移的指令
指令 | 含义 | 转移条件 |
---|---|---|
JL / JNGE | 小于则转移 | SF = 1 且 OF = 0 |
JNL / JGE | 不小于则转移 | SF = 0 且 OF = 0 |
JLE / JNG | 小于等于则转移 | SF = 0 且 OF = 1 |
JNLE / JG | 不小于等于则转移 | SF = 1 且 OF = 1 |
条件转移指令的使用
- JXXX 系列指令和 CMP 指令配合使用,构造条件转移指令
- 不必再考虑 CMP 指令对相关标志位的影响和 JXXX 指令对相关标志位的检测
- 可以直接考虑 CMP 和 JXXX 指令配合使用时表现出来的逻辑含义
- JXXX 系列指令和 CMP 指令配合实现高级语言中的 IF 语句的功能
条件转移指令的应用
- 条件转移指令可以根据某种”条件“,决定是否”转移“程序执行流程
- ”转移“ = 修改 IP
如果检测条件
- 通过检测标志位,由标志位体现条件
- 条件转移指令通常都和 CMP 相配合使用,CMP 指令改变标志位