第二十四课:算术运算类指令分析
算术运算指令共有24条,算术运算主要是执行加、减、乘、除法四则运算。另外MCS-51指令系统中有相当一部分是进行加、减1操作,BCD码的运算和调整,我们都归类为运算指令。虽然MCS-51单片机的算术逻辑单元ALU仅能对8位无符号整数进行运算,但利用进位标志C,则可进行多字节无符号整数的运算。同时利用溢出标志,还可以对带符号数进行补码运算。需要指出的是,除加、减1指令外,这类指令大多数都会对PSW(程序状态字)有影响。这在使用中应特别注意。
[1]. 加法指令(4条)
这4条指令的作用是把立即数,直接地址、工作寄存器及间接地址内容与累加器A的内容相加,运算结果存在A中。
ADDA,#data ;(A)+#data→(A) 累加器A中的内容与立即数#data相加,结果存在A中
ADDA,data;(A)+(data)→(A) 累加器A中的内容与直接地址单元中的内容相加,结果存在A中
ADDA,Rn ;(A)+(Rn)→(A) 累加器A中的内容与工作寄存器Rn中的内容相加,结果存在A中
ADDA,@Ri;(A)+((Ri))→(A) 累加器A中的内容与工作寄存器Ri所指向地址单元中的内容相加,结果存在A中
这些指令所用到的源操作数都是累加器ACC,目的操作数则根据自已的需要来选择。
上述这四条指令的用途是:将A中的值与后面的值相加,最终结果存回到累加器A中。
例:MOVA,#30H
ADDA,#10H
则执行完本条指令后,A中的值就是40H
下面的题目请大家自行练习
MOV34H,#10H
MOVR0,#13H
MOVA,34H
ADDA,R0
MOVR1,#34H
ADDA,@R1
练习题说明:
MOV 34H,#10H
这条指令的目的是将立即数10H送入34H这个存储单元
MOV R0,#13H
这条指令的目的是将立即数13H送入R0这个寄存器
MOV A,34H
这条指令大家要特别注意了,这条指令的源操作数在哪里呢?它的源操作数是在34H这个存储单元里,也就是34H是个存储单元,而不是一个数
这条指令用的是直接寻址,大前看前面的指令,第一条指令将10H这个立即数送入了34H这个存储单元。那么,也就是34H中存储着10H这么一个常数。
执行MOVA,34H单元后,累加器A中的值是多少呢?前面说了34H存储单元中的值是10H,所以这时累加器的值就是10H。
ADD A,R0
这条指令其实就是把前面三条指令的数据求个总和。第二条指令MOVR0,#13H执行完后。R0寄存器里的值是13H。第三条指令MOV A,34H执行完后,累加器的值是10H。
这条指令的意思就是把R0寄存器中的值(13H)与累加器A中的值(10H)相加,其结果是(23H)送入累加器A。
MOV R1,#34H
这条指令是将常数34H送入寄存器R1,执行完这条指令后,R1寄存器中的值是34H
ADD A,@R1
这个时候求和,大家请注意了。这条指令是寄存器间接寻址方式。前面我们已知道,累加器中的值是23H,MOVR1,#34H执行完后,R1寄存器的值是34H。大家注意,在间接寻址方式MOVA,@Ri(Ri为R0或R1,在这条指令中用的是R1)中。R1内的值指的就不是一个常数了,而是一个直接地址。这条指令的意思就是把寄存器R1中存储的34H存储单元的内容(10H)与累加器中的内容(23H)相加,其结果为33H。
根据前面我们用的MedWin仿真软件大家进行模拟仿真,同时打开DATA窗口及寄存器窗口观察程序执行时内部寄存器及数据区的变化情况。软件使用如有不凝问,请到我们论坛提出。我们会尽力为大家解答。
[2]. 带进位加法指令(4条)
这4条指令除与[1]功能相同外,在进行加法运算时还需考虑进位问题。
ADDCA,data;(A)+(data)+(C)→(A) 累加器A中的内容与直接地址单元的内容连同进位位相加,结果存在A中
ADDCA,#data ;(A)+#data +(C)→(A) 累加器A中的内容与立即数连同进位位相加,结果存在A中
ADDCA,Rn;(A)+Rn+(C)→(A) 累加器A中的内容与工作寄存器Rn中的内容、连同进位位相加,结果存在A中
ADDCA,@Ri ;(A)+((Ri))+(C)→(A) 累加器A中的内容与工作寄存器Ri指向地址单元中的内容、连同进位位相加,结果存在A中
用途:将A中的值和其后面的值相加,并且加上进位位C中的值。
说明:由于51单片机是一种8位机,所以只能做8位的数学运算,但8位的运算范围只有0-255,这在实际工作中是不够的,因此就要进行扩展,一般是将2个8位的数学运算合起来,成为一个16位的运算,这样,可以表达的数的范围就可以到达0-65535。如何合并呢?其实很简单,让我们看一个十进制数的例子吧:
66+78
这两个数相加,我们根本不在意这个过程,但事实上我们是这样做的:先做6+8(低位),然后再做6+7,这是高位。做了两次加法,只是我们做的时候并没有刻意分成两次加法来做罢了,或者说我们并没有意识到我们做了两次加法。之所以要分成两次来做,是因为这两个数超过了一位数所能表达的范围(0-9)。
在做低位时产生了进位,我们做的时候是在适当的位置点一下,然后在做高位加法时将这一点加进去。那么计算机中做16位加法时同样如此,先做低8位的,如果两数相加后产生了进位,也要“点一下”做个标记,这个标记就职进位位C,在程序状态字PSW中。在进行高位加法是将这个C加进去。
例如:1067H+10A0H,先做67H+A0H=107H,而107H显然超过了0FFH,因此,最终保存在A中的数是7,而1则到了PSW中的CY位了,换言之,CY就相当于100H。然后再做10H+10H+CY,结果是21H,所以最终的结果是2107H。
[3]. 带借位减法指令(4条)
这组指令包含立即数、直接地址、间接地址及工作寄存器与累加器A连同借位位C内容相减,结果送回累加器A中。
这里我们对借位位C的状态作出说明,在进行减法运算中,CY=1表示有借位,CY=0则无借位。OV=1声明带符号数相减时,从一个正数减去一个负数结果为负数,或者从一个负数中减去一个正数结果为正数的错误情况。在进行减法运算前,如果不知道借位标志位C的状态,则应先对CY进行清零操作。
SUBBA,data;(A)-(data) - (C)→(A) 累加器A中的内容与直接地址单元中的内容、连同借位位相减,结果存在A中
SUBBA,#data ;(A)-#data -(C)→(A) 累加器A中的内容与立即数、连同借位位相减,结果存在A中
SUBBA,Rn ;(A)-(Rn) -(C)→(A) 累加器A中的内容与工作寄存器中的内容、连同借位位相减,结果存在A中
SUBBA,@Ri;(A)-((Ri)) -(C)→(A) 累加器A中的内容与工作寄存器Ri指向的地址单元中的内容、连同借位位相减,结果存在A中
[4]. 乘法指令(1条)
这个指令的作用是把累加器A和寄存器B中的8位无符号数相乘,所得到的是16位乘积,这个结果低8位存在累加器A,而高8位存在寄存器B中。如果OV=1,说明乘积大于0FFFFH(65536),否则OV=0,但进位标志位CY总是等于0。
MULAB ;(A)×(B)→(A)和(B) 累加器A中的内容与寄存器B中的内容相乘,结果存在A、B中
例:(A)=4EH,(B)=5DH,执行指令
MULAB后,乘积是1C56H,所以在B中放的是1CH,而A中放的则是56H。
[5].除法指令(1条)
这个指令的作用是把累加器A的8位无符号整数除以寄存器B中的8位无符号整数,所得到的商存在累加器A,而余数存在寄存器B中。除法运算总是使OV和进位标志位CY等于0。如果OV=1,表明寄存器B中的内容为00H,那么执行结果为不确定值,表示除法有溢出。
DIVAB ;(A)÷(B)→(A)和(B) 累加器A中的内容除以寄存器B中的内容,所得到的商存在累加器A,而余数存在寄存器B中。
例如:13/5,其商是2,余数是3。除了以后,商会放在A中,余数放在B中,CU和OV都是0。如果在做除法前B中的值是00H,也就是除数为0,那么OV=1。
[6]. 加1指令(5条)
这5条指令的的功能均为原寄存器的内容加1,结果送回原寄存器。上述提到,加1指令不会对任何标志有影响,如果原寄存器的内容为FFH,执行加1后,结果就会是00H。这组指令共有直接、寄存器、寄存器减间址等寻址方式:
INCA;(A)+1→(A) 累加器A中的内容加1,结果存在A中
INCdata ;(data)+1→(data) 直接地址单元中的内容加1,结果送回原地址单元中
INC@Ri ;((Ri))+1→((Ri)) 寄存器的内容指向的地址单元中的内容加1,结果送回原地址单元中
INCRn ;(Rn)+1→(Rn)寄存器Rn的内容加1,结果送回原地址单元中
INCDPTR;(DPTR)+1→(DPTR)数据指针的内容加1,结果送回数据指针中
用途很简单,就是将后面目标中的值加1。
例:(A)=12H,(R0)=33H,(21H)=32H,(34H)=22H,DPTR=1234H。执行下面的指令;
INCA ;(A)=13H
INCR0;(R0)=34H
INC21H ;(21H)=33H
INC@R0 ;(34H)=23H
INCDPTR;(DPTR)=1235H
这些指令执行后的结果都附在了指令的后面。
说明:从结果上看,INCA和ADD A,#1差不多,但INCA是单字节,单周期指令,而ADDA,#1则是双字节双周期指令,而且INCA不会影响PSW位,如(A)=0FFH,INCA后(A)=00H,而CY依然保持不变。如果是ADD A,#1,则(A)=00H,而CY一定是1。因此加1指令并不适合做加法运算,事实上它主要是用来做计数、地址增加等用途。另外,加法类指令都是以A为核心的,其中一个数必须放在A中,而运算结果也必须放在A中,而加1类指令的对象则广泛得多,可以是寄存器、内存地址、间址寻址的地址等等。
在INCdata这条指令中,如果直接地址是I/O,其功能是先读入I/O锁存器的内容,然后在CPU进行加1操作,再输出到I/O上,这就是“读—修改—写”操作。
[7].减1指令(4条)
这组指令的作用是把所指的寄存器内容减1,结果送回原寄存器,若原寄存器的内容为00H,减1后即为FFH,运算结果不影响任何标志位,这组指令共有直接、寄存器、寄存器间址等寻址方式,当直接地址是I/O口锁存器时,“读—修改—写”操作与加1指令类似。
DECA ;(A)-1→(A)累加器A中的内容减1,结果送回累加器A中
DECdata;(data)-1→(data)直接地址单元中的内容减1,结果送回直接地址单元中
DEC@Ri;((Ri))-1→((Ri))寄存器Ri指向的地址单元中的内容减1,结果送回原地址单元中
DECRn;(Rn)-1→(Rn)寄存器Rn中的内容减1,结果送回寄存器Rn中
[8]. 十进制调整指令(1条)
在进行BCD码运算时,这条指令总是跟在ADD或ADDC指令之后,其功能是将执行加法运算后存于累加器A中的结果进行调整和修正。
DAA
综合练习:
MOV A,#12H
MOV R0,#24H
MOV 21H,#56H
ADD A,#12H
MOV DPTR,#1234H
ADD A,DPH
ADD A,R0
CLR C
SUBBA,DPL
SUBBA,#25H
INC A
SETBC
ADDCA,21H
INC R0
SUBBA,R0
MOV 24H,#16H
CLR C
ADD A,@R0
先写出每步运行结果,然后将以上题目键入,并在软件仿真中运行,观察寄存器及有关单元的内容的变化。看结果是否与预想的结果相同?
关于软件仿真的具体使用方法,我们会专门安排一节课给大家学习。敬请期待!
导读:目前正在解读《51单片机指令系统(6)》的相关信息,《51单片机指令系统(6)》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《51单片机指令系统(6)》的详细说明。
提醒:《51单片机指令系统(6)》最后刷新时间 2024-03-14 01:23:15,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《51单片机指令系统(6)》该内容的真实性请自行鉴别。