ADD,ADDC,INC,DA,SUBB,DEC,MUL,DIV
3.3.1 加法指令ADD

ADD指令是一个字节加法指令,用于实现两个操作数相加的运算。其基本格式为:
其中:
- A为累加器,作为第一个操作数和存放结果的寄存器
- src为第二个操作数,可以是:
- 寄存器R0-R7
- 直接寻址的内部RAM单元
- 间接寻址的内部RAM单元
- 立即数据(#data)
执行过程:
- 将src中的数据与累加器A中的内容相加
- 运算结果存回累加器A中
- 根据运算结果设置相关标志位:
- 进位标志位C
- 溢出标志位OV
- 辅助进位标志位AC
在ADD指令执行后,标志位的设置规则如下:
- 进位标志位C:当运算结果超过8位(即产生进位)时,C=1;否则C=0
- 溢出标志位OV:当两个操作数都是有符号数时,如果运算结果超出有符号数的表示范围(-128~+127),则OV=1;否则OV=0
- 辅助进位标志位AC:当运算过程中第3位向第4位有进位时,AC=1;否则AC=0。主要用于BCD码的运算
举例说明:
值得说明的是,如果我们进行的是无符号数的运算,虽然一定条件下OV位也会被置1,但是此时OV位是没有意义的,编程者只需要关注CY位即可
3.3.2 带进位加法指令ADDC

ADDC(Add with Carry)指令是一个带进位的字节加法指令,其基本格式为:
其中:
- A为累加器,作为第一个操作数和存放结果的寄存器
- src为第二个操作数,可选择的操作数类型与ADD指令相同
ADDC指令的特点是在执行加法运算时,会将进位标志位C的值也参与运算。具体执行过程为:
- 将src中的数据、累加器A中的内容以及进位标志位C的值三者相加
- 运算结果存回累加器A中
- 根据运算结果设置相关标志位(C、OV、AC),设置规则与ADD指令相同
这个指令主要用于多字节加法运算。举例说明:
在这个例子中,当计算完低字节后,如果产生了进位(C=1),那么在计算高字节时,ADDC指令会自动将这个进位加入计算过程中,从而实现了正确的16位加法运算。
3.3.3 加1指令INC

INC(Increment)指令是一个加1指令,用于将操作数加1。其基本格式为:
其中operand可以是:
- 累加器A
- 寄存器R0-R7
- 直接寻址的内部RAM单元
- 端口P0-P3可直接寻址,此时INC操作会修改输出口的内容
- 间接寻址的内部RAM单元
- 外部RAM单元(DPTR)
INC指令的特点:
- 执行加1操作,结果存回原操作数
- 不影响任何标志位
- 当操作数为0FFH时,加1后变为00H
举例说明:
INC指令常用于计数器的实现、地址的自动增加等场合。
3.3.4 二-十进制调整指令DA
DA(Decimal Adjust)指令用于将二进制加法运算的结果调整为BCD码格式。其基本格式为:
DA指令的工作原理:
- 仅对累加器A进行操作
- 必须在ADD或ADDC指令之后使用
- 根据AC和C标志位的状态对A的内容进行调整:
- 如果低4位>9或AC=1,则A的低4位加6
- 如果高4位>9或C=1,则A的高4位加6
举例说明:
在这些例子中,DA指令将二进制加法的结果自动调整为正确的BCD码格式,便于在数码显示等场合使用。需要注意的是,只有当操作数本身就是BCD码时,使用DA指令才有意义。
- 对于BCD码的减法运算,需要使用以下步骤:
- 先将减数按位取反(99-原BCD码)
- 然后执行加法运算(被减数+取反后的减数)
- 最后使用DA指令进行调整
3.3.5 带借位减法指令SUBB

需要注意的是,在80C51指令系统中没有不带借位的减法。如果需要的话,可以在“SUBB”指令前,用“CLR C”指令将CY先清零。
SUBB(Subtract with Borrow)指令是一个带借位的字节减法指令,其基本格式为:
其中:
- A为累加器,作为被减数和存放结果的寄存器
- src为减数,可以是:
- 寄存器R0-R7
- 直接寻址的内部RAM单元
- 间接寻址的内部RAM单元
- 立即数据(#data)
执行过程:
- 将累加器A的内容减去src中的数据和借位标志位C的值
- 运算结果存回累加器A中
- 根据运算结果设置相关标志位:
- 借位标志位C: 当运算需要借位时,C=1。例如:
- 溢出标志位OV: 当有符号数运算结果超出范围时,OV=1。例如:
- 辅助借位标志位AC: 用于BCD码运算。例如:
- 首先将减数17H通过与99H异或运算转换为它的"9的补码"82H
- 然后将被减数45H与82H相加
- 最后使用DA指令将结果调整为正确的BCD码格式28H
在SUBB指令中,有三个重要的标志位:
执行本例后:
45H(BCD码45) - 17H(BCD码17) = 2EH(非BCD码结果)
因为低4位5减去7需要借位,所以AC=1
注意:这个结果2EH并不是一个有效的BCD码。如果要进行BCD码减法,不能使用SUBB,需要使用之前提到的"99的补码方法"。
以下是使用"99的补码方法"进行BCD码减法的正确示例:
在这个例子中:
3.3.6 减1指令DEC

DEC(Decrease)指令用于实现操作数减1的运算。其基本格式为:
其中operand可以是:
- 累加器A
- 寄存器R0-R7
- 直接寻址的内部RAM单元
- 间接寻址的内部RAM单元
DEC指令的特点:
- 执行减1操作,结果存回原操作数
- 不影响任何标志位
- 当操作数为00H时,减1后变为0FFH
举例说明:
DEC指令常用于计数器的递减、循环控制等场合。
3.3.7 乘法/除法指令
1. 乘法指令 MUL AB
MUL AB指令用于实现两个无符号数的乘法运算。其基本格式为:
其中:
- A和B寄存器分别存放两个8位无符号数
- 运算结果的高8位存放在B中,低8位存放在A中
- 如果运算结果超过FFH(即B≠0),则OV=1;否则OV=0
- C标志位始终被清零
举例说明:
注意事项:
- 只能进行8位×8位的无符号数乘法
- 结果最大为FFFFH(65535,64KB)
- 不能直接进行BCD码的乘法运算
对于BCD码的乘法运算,由于MUL指令无法直接处理BCD码,我们需要先将BCD码转换为二进制数,然后进行乘法运算,最后再将结果转换回BCD码。以下是具体步骤:
这种方法比较复杂,在实际应用中,通常会使用查表法或其他算法来实现BCD码的乘法运算。
2. 除法指令 DIV
DIV AB指令用于实现两个无符号数的除法运算。其基本格式为:
其中:
- A寄存器存放被除数,B寄存器存放除数
- 运算后,商存放在A中,余数存放在B中
- 当除数B=0时,OV=1;否则OV=0
- C标志位始终被清零
举例说明:
注意事项:
- 只能进行8位÷8位的无符号数除法
- 不能除以0,否则会设置溢出标志
- 不能直接进行BCD码的除法运算
对于BCD码的除法运算,由于DIV指令无法直接处理BCD码,需要先将BCD码转换为二进制数,然后进行除法运算,最后再将结果转换回BCD码。以下是具体步骤:
同样地,这种方法比较复杂。在实际应用中,通常会使用查表法或其他简化算法来实现BCD码的除法运算。