6.2 算术指令与标志位
数据传送指令保留原有位模式;算术指令会计算新的位模式,并更新状态标志(status flags)。这些单独的位概括了处理器稍后需要的结果性质。第 4 章介绍过 FLAGS 寄存器,本节把每个标志与具体算术联系起来。
ADD、SUB、INC、DEC 与 NEG
ADD 目的,源 用两者之和替换目的;SUB 目的,源 用“目的减源”的结果替换目的。源操作数保持不变。
INC 操作数 加 1,DEC 操作数 减 1。它们更新 OF、SF、ZF、AF 和 PF,却有意保留 CF。NEG 操作数 计算零减该操作数:对零取负会清除 CF,对任何非零值取负都会设置 CF。
对于 8 位目的,只保存结果低 8 位。例如 FFH+01H=100H,但 8 位寄存器只能保存 00H。被丢弃的第九位会记录在 CF 中。
六个算术状态标志分别是:
- CF,进位标志:无符号加法产生超出目的宽度的位,或无符号减法需要借位。
- PF,奇偶标志:结果低字节中 1 的数量为偶数。
- AF,辅助进位标志:位 3 与位 4 之间发生进位或借位;十进制调整指令会使用它。
- ZF,零标志:保存下来的所有结果位都是零。
- SF,符号标志:保存结果的最高位为 1。
- OF,溢出标志:有符号结果超出目的二进制补码的表示范围。
CF 与 OF 回答不同问题
同一个 8 位模式既可以解释为 0 到 255 的无符号数,也可以解释为 −128 到 +127 的有符号数。算术逻辑单元不会选择其中一种解释;它只计算一次,然后同时给出 CF 和 OF。
观察 7FH+01H=80H:
- 无符号解释:127+1=128 可以表示,因此 CF=0。
- 有符号解释:+127+1 无法表示,保存的
80H表示 −128,因此 OF=1。
再观察 FFH+01H=00H:
- 无符号解释:255+1 需要第九位,因此 CF=1。
- 有符号解释:−1+1=0 合法,因此 OF=0。
不能只用 CF 判断有符号溢出,也不能只用 OF 判断无符号进位。
ADC 与 SBB 把算术扩展到多个字
8086 的算术逻辑单元宽度为 16 位,但程序可以用高字和低字表示一个 32 位整数。先处理低字:
ADD lowA,lowB
ADC highA,highBADC 表示带进位加法(add with carry):highA 变为 highA+highB+CF。减法中,SBB 表示带借位减法(subtract with borrow):highA 变为 highA−highB−CF。
例如 0000FFFFH+00000001H。低字计算 FFFFH+0001H 保存 0000H 并设置 CF;ADC 0000H,0000H 会加入这个进位,得到高字 0001H,拼接结果为 00010000H。若把 ADC 换成 ADD,就会错误地丢掉跨越字边界的位。
算术可以产生掩码、计数器和比较结果,但程序有时需要在不做普通加法的情况下修改单独的位。第 6.3 节将介绍逻辑、移位与循环移位。