ADD A ,R5 DA A
结果为:A=23H,CY=1。 三、逻辑运算与移位类指令
逻辑运算包括与、或和异或 3类指令,每类有6条指令,此外,还有累加器A清零、求反的指令和4条移位指令。本节我们将学习这24条指令。
1、逻辑与运算指令组
逻辑运算都是按位进行的,逻辑与运算用符号“∧”表示。6条逻辑与运算指令如下 :
ANL Rn A , ;A ← (A) ∧ (Rn) ANL direct A , ;A ← (A) ∧ (direct) ANL @Ri A , ;A ← (A) ∧ ((Ri)) ANL # data A , ;A ← (A) ∧ data ANL direct , A ;direct ← (direct)∧(A) ANL direct , # data ;direct ← (direct) ∧ data
其中前4条指令运算结果存放在 A中,而后2条指令的运算结果则存放在直接寻址的地址单元中。
2、逻辑或运算指令组
逻辑或运算指令用符号“∨”表示,6条逻辑或运算指令如下:
ORL Rn A , ;A ← (A) ∨ (Rn) ORL direct A , ;A ← (A) ∨ (direct) ORL @Ri A , ;A ← (A) ∨ ((Ri)) ORL # data A , ;A ← (A) ∨ data ORL direct , A ;direct ← (direct)∨(A) ORL direct , # data ;direct ← (direct) ∨ data
其中前 4条指令的操作结果存放在累加器A中,后2条指令的操作结果存放在直接寻址的地址单元中。
3、逻辑异或运算指令组
XRL Rn A , ;A ← (A) ? (Rn) ORL direct A , ;A ← (A) ? (direct) ORL @Ri A , ;A ← (A) ? ((Ri)) ORL # data A , ;A ← (A) ? data ORL direct , A ;direct ← (direct)?(A) ORL direct , # data ;direct ← (direct) ? data
前4条指令操作结果存放在累加器A中,后2条指令的操作结果存放在直接寻址的 地址单元中。
4、累加器清“0”和取反指令组 累加器清“0”指令一条:
CLR A ;A ← 0 累加器按位取反指令一条:
CPL A ;A ← (?) 注意,累加器按位取反实际上就是逻辑非运算。
[例3-1] 当需要只改变字节数据的某几位,而其余位不变时,不能使用直接传送方法,而只能通过逻辑运算完成,以下举例说明。例如将累加器A的低4位传送到P1口的低4位,但P1口的高4位需保持不变,对此可由以下程序段实现:
MOV ANL ANL ORL MOV
R0 , A , P1 , P , A , A # 0FH # F0H A R0
;内容暂存R0
;屏蔽A的高4位(低4位不变) ;屏蔽P1口的低4位(高4位不变) ;实现低4位传送 ;恢复A的内容
[例3-2] 利用逻辑运算指令,可以模拟各种
硬件逻辑电路,如对图3-1所示的组合逻辑电路,试编写一程序模拟其功能。设输入信号放在X、Y、Z单元中,输出信号放在F单元。
图3-1 组合逻辑原理
;A ← (X) MOV X A ,
;A ← (A)∧(Y) ANL Y A ,
;A内容暂存 MOV A R1 ,
;A ← (Y) MOV Y A ,
XRL Z A , ;A ← (Y)?(Z) CPL A ;A ← (?)?(?);得到输出 ORL R1 A ,
;存输出 MOV A F ,
5、移位指令组
MCS- 51的移位指令只能对累加器A进行移位,共有不带进位的循环左、右移和带进位的循环左、右移指令4条。
(1)循环左移
RL A ;A n+1 ← A n ,A0 ← A7
累加器A (2)循环右移 RR
A ;A n ← A n+1 , A7← A0
累加器A (3).带进位循环左移
RLC A
;A n+1 ←A n ,CY ← A7 ,A0 ← CY
累加器A
(4).带进位循环右移
RRC A
;A n ← A n+1,A7 ← CY ,CY ← A0
累加器A 四、 控制转移类指令
程序的顺序执行是由PC自动加1实现的。要改变程序的执行顺序,实现分支转向,应通过强迫改变PC值的方法来实现,这就是控制转移类指令的基本功能。共有两类转移:无条件转移和有条件转移。本节还要介绍子程序调用及返回指令。
1、无条件转移指令组
不规定条件的程序转移称之为无条件转移。MCS-51共有4条无条件转移指令。 (1).长转移指令
LJMP addr 16 ;PC ← addr16 指令执行后把16位地址(addrl6)送PC,从而实现程序转移。因转移范围大,可达64KB,称之为“长转移”。长转移指令是三字节指令,依次是操作码、高8位地址、低8位地址。
(2).绝对转移指令
AJMP addr 11
这是一条二字节指令,其指令格式为 A10 A9 A8 0 0 1 0 0 A7 A6 A5 A4 A3 A2 A1 A0
指令提供的11位地址中,A7~A0在第二字节。A10~A8则占据第一字节的高3位,而指令操作码只占第一字节的低5位。AJMP指令的功能是构造程序转移的目的地址,实现程序转移,其构造方法是:以指令提供的11位地址去替换PC的低11位内容,形成新的PC值,此即转移的目的地址。但要注意,被替换的PC值是本条指令地址加2以后的PC值,即指向下一条指令的PC值。因此AJMP指令的操作过程可表示为:
PC ← (PC) + 2 PC10~0 ← addr 11
例如程序中2070H地址单元有绝对转移指令: 2070H AJMP 16AH
11位绝对转移地址为:00101101010B(16AH)。因此,指令代码为: 0 0 1 0 0 1 0 0 0 1 1 0 1 0 1 0
程序计数器PC加2后的内容为:0010000001110010B(2072H),以11位绝对转移地址替换PC的低11位内容,最后形成的目的地址为0010000101101010B(2l6AH)。其中B表
示二进制数,H表示十六进制数。addr11是地址,因此是无符号数,其最小值为000H,最大值为7FFH,因此绝对转移指令所能转移的最大范围是2KB。对于“2070H AJMP l6AH”指令,其转移范围是2000H~27FFH。
例如指令:
AJMP addr 11` LOOP:
假设addr11 = 00100000000B,标号LOOP的地址为1030H,则执行指令后,程序将转移到1100H。该指令的机器码为21H,00H(A10A9A8 = 001),即指令的第一字节为21H。
(3).短转移指令
SJMP Rel
SJMP相对寻址方式转移指令,其中rel为相对偏移量,其功能是计算目的地址,并按计算得到的目的地址实现程序的相对转移。计算公式为: 目的地址 = (PC) + 2 + rel
偏移量rel是一个带符号的8位二进制补码数,因此所能实现程序转移是双向的。如rel为正数则向前转移;如rel为负数则向后转移。转移的范围笼统地说是256,因此称为短转移。对于短转移指令的使用可从如下两个方面进行讨论。
①根据偏移量rel计算转移的目的地址
这种情况经常在读目标程序时遇到,是解决往哪儿转移的问题。例如在853AH地址上
有SJMP指令: 835AH SJMP 35H 源地址为835AH,rel = 35H是正数,因此程序向前转移。
目的地址 = 835AH +35H = 8931H。即执行完本指令后,程序转到8931H地址去执行。 又例如在835AH地址上SJMP指令是:
835AH SJMP 0E7H rel = 0E7H,是负数19H的补码,因此,程序向后转移,目的地址 = 835AH + 02H –19H
= 8343H。即执行完本指令后,程序向后转到8343H地址去执行。
②根据目的地址计算偏移量
这是编程时必须解决的问题,也是一项比较麻烦的事情。对于二字节的SJMP指令,rel的计算公式如下:
向前转移时:
rel = 目的地址 - 源地址 – 2 = (地址差) - 2
向后转移时,目的地址小于源地址,rel应为负数的补码:
rel = (目的地址 - (源地址 + 2 ))补
= FFH - (源地址 + 2 –目的地址) + 1 = FEH - (地址差)
为方便起见,在汇编程序中都有计算偏移量的功能。用户编写汇编源程序时,只需在相对转移指令中直接写上要转向的地址标号就可以了。程序汇编时由汇编程序自动计算和填入偏移量。但手工汇编时,偏移量的值则需程序设计人员自己计算。
此外,在汇编语言程序中,为等待中断或程序结束,常有使程序“原地踏步”的需要,对此可使用SJMP指令完成:
SJMP HERE HERE:
或 HERE: SJMP $
指令机器码为80FE。在汇编语言中,以“$”代表PC的当前值。
[例3-3] 执行指令:LOOP:SJMP LOOPl。如果LOOP的标号值为0100H(即SJMP