资源描述
MCS-51单片机的指令
一. 数据传送类指令(29条)
.1 通用传送指令(16条)
格式:MOV 目的操作数,源操作数
功能:把第二操作数指定的字节内容传送到第一操作数指定的单元中。不影响源操作数内容,不影响别的寄存器和标志。
根据目的操作数的不同,通用传送指令又分为以下几种类型:
1.1 以累加器A为目的操作数的传送类指令(4条)
指令助记符及功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOV
A,
direct
;(A)←(direct)
直接寻址
MOV
A,
@Ri
;(A)←((Ri))
寄存器间接寻址
MOV
A,
Rn
;(A)←(Rn)
寄存器寻址
MOV
A,
#data
;(A)←data
立即寻址
这类指令的功能是将源操作数送到目的操作数A中。指令执行后的结果:除了奇偶标志P始终跟踪A中数据的奇偶性外,不影响PSW中的其他标志位。
1.2 以Rn为目的操作数的传送类指令(3条)
指令助记符及功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOV
Rn,
A
;(Rn)←(A)
寄存器寻址
MOV
Rn,
direct
;(Rn)←(direct)
直接寻址
MOV
Rn,
#data
;(Rn)←data
立即寻址
其中,Rn是R0,…,R7中的任意一个。
例1 若(A)=20H,则执行指令MOV R3, A后,(R3)=20H。
注意: Rn寄存器之间不能直接传送数据。如指令“MOV R1, R7”是错误的。
该类指令执行后,不影响PSW中的标志位。
1.3. 以直接地址directX为目的操作数的传送类指令(5条)
指令助记符及功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOV
directX,
A
;(directX)←(A)
寄存器寻址
MOV
directX,
Rn
;(directX)←(Rn)
寄存器寻址
MOV
directX,
directY
;(directX)←(directY)
直接寻址
MOV
directX,
@Ri
;(directX)←((Ri))
寄存器间接寻址
MOV
directX,
#data
;(directX)←data
立即寻址
这类指令的功能是把源操作数的内容送到直接地址directX中去。
在上述指令中的直接地址单元(directX与directY)是指内部RAM的00H~7FH区域,以及特殊功能寄存器。
例1 若(30H)=20H,(R0)=30H,则执行指令MOV 90H, @R0的结果为(90H)=20H。
1.4. 以寄存器间接地址@Ri为目的操作数的传送类指令(3条)
指令助记符及功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOV
@Ri,
A
;((Ri))←(A)
寄存器寻址
MOV
@Ri,
direct
;((Ri))←(direct)
直接寻址
MOV
@Ri,
#data
;((Ri))←data
立即寻址
这类指令的功能是将源操作数的内容送到由Ri(R0或R1)的内容所指定的地址中去。
例1 若(R0)=50H,(50H)=20H,(A)=10H,则执行指令“MOV @R0, A”后,50H单元的内容由原来的20H变为10H。
该类指令执行后,不影响PSW中的标志位。
1.5 16位目标地址传送指令(1条)
指令助记符及功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOV
DPTR,
#data16
;(DPTR)←data16
立即寻址
这条指令的功能是:把16位立即数送入DPTR中。而16位的数据指针DPTR由DPH与DPL组成,该指令执行后,16位立即数的高8位送入DPH中,低8位送入DPL中。
2 外部数据存储器(或I/O口)与累加器A传送指令(4条)
为了区别于以MOV为指令助记符的内部数据传送指令,外部数据存储器传送指令的指令助记符为MOVX。
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOVX
A,
@DPTR
;(A)←((DPTR))
寄存器间接寻址
MOVX
A,
@Ri
;(A)←((Ri))
寄存器间接寻址
MOVX
@DPTR,
A
;((DPTR))←(A)
寄存器寻址
MOVX
@Ri,
A
;((Ri))←(A)
寄存器寻址
例1 设(P2)=20H,现将A中数据存储到20FFH单元中去。
可用以下程序实现:
MOV R1, #0FFH ;(R1)←0FFH
MOVX @R1, A ;(20FFH)←(A)
也可采用下述程序实现:
MOV DPTR, #20FFH ;(DPTR)←20FFH
MOVX @DPTR, A ;((DPTR))←(A),即(20FFH)←(A)
执行结果是一样的,A中数据都是被存储到外部存储器的20FFH单元中去。
.3 程序存储器向累加器A传送数据指令(2条)
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
MOVC
A,
@A+PC
;(A)←((A)+(PC)+1)
变址寻址
MOVC
A,
@A+DPTR
;(A)←((A)+(DPTR))
变址寻址
4 数据交换指令(5条)
数据交换指令有两类,分别是:字节交换指令和半字节交换指令。
4.1. 字节交换指令
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
XCH
A,
direct
;(A)(direct)
直接寻址
XCH
A,
@Ri
;(A)((Ri))
间接寻址
XCH
A,
Rn
;(A)(Rn)
寄存器寻址
上述指令的功能是将累加器A中的内容与源操作数所指定的直接寻址、间接寻址、寄存器寻址的某一单元内容互相交换。
例1 设(R1)=30H,(30H)=45H,(A)=7FH,则执行指令:
XCH A, @R1
结果:(A)=45H,而(30H)=7FH,从而实现了累加器A与内部数据存储器RAM中30H单元的数据交换。
4.2. 半字节交换指令
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
XCHD
A,
@Ri
;(A)((Ri))
间接寻址
该指令是把累加器A的低4位与寄存器Ri间接寻址的内部RAM单元的低4位互换,高4位内容不变。
例1 设(30H)=6FH,(R0)=30H,(A)=0F6H,则执行指令:
XCHD A, @Ri
结果:(A)=0FFH,(30H)=66H
数据交换指令除了影响始终跟踪A中数据奇偶性的P标志外,对PSW中其他标志位均无影响。
4.3. 累加器A中高四位与低四位交换指令
SWAP A
该指令所执行的操作是累加器A中的高4位与低4位的内容互换,其结果仍存放在累加器A中。
例1 设(A)=0A5H(10100101B),则执行指令:
SWAP A
结果:(A)=5AH(01011010B)
.5 堆栈操作指令(2条)
堆栈操作指令只有2条,即:压入(PUSH)和弹出(POP)。
压入指令:PUSH direct ;SP←SP+1,((SP))←(direct)
弹出指令:POP direct ;((SP))←(direct),SP←SP-1
在MCS-51单片机中,堆栈中的数据是以“先进后出”的结构方式处理的。入栈操作过程为:先将堆栈指针SP←SP+1,指向栈顶的上一个空单元,然后再将直接寻址单元direct中的数据传送到SP所指示的地址单元中去。而出栈操作过程则为:将堆栈指针SP所指示的栈顶中的数据弹出,传送到直接寻址单元direct中,然后SP←SP-1,形成新的栈顶指针。
它们常被应用在保护现场(即把寄存器的内容暂存在某内存区)和恢复现场的程序中。
例1 PUSH A ;保护A中数据
PUSH PSW ;保护标志寄存器中数据
… ;执行服务程序
POP PSW ;恢复标志寄存器中数据
POP A ;恢复A中数据
执行上述程序后,A和PSW寄存器中的内容可得到正确恢复。
二. 算术运算类指令(24条)
.1 加减运算指令(12条)
1.1 加法指令(4条)
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
ADD
A,
#data
;(A)←(A)+data
立即寻址
ADD
A,
direct
;(A)←(A)+(direct)
直接寻址
ADD
A,
@Ri
;(A)←(A)+((Ri))
寄存器间接寻址
ADD
A,
Rn
;(A)←(A)+(Rn)
寄存器寻址
这类指令所完成的操作是把源操作数(立即数、直接地址单元内容、间接地址单元内容、工作寄存器内容)与累加器A的内容相加,将结果保存在累加器A中。影响程序状态寄存器的AC、CY、OV、P标志位。
例1 执行指令:
MOV A, #0A9H
运算结果:(A)=61H
1.2. 带进位加法指令
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
ADDC
A,
#data
;(A)←(A)+data+(C)
立即寻址
ADDC
A,
direct
;(A)←(A)+(direct)+(C)
直接寻址
ADDC
A,
@Ri
;(A)←(A)+((Ri))+(C)
寄存器间接寻址
ADDC
A,
Rn
;(A)←(A)+(Rn)+(C)
寄存器寻址
带进位加法指令与前述加法指令的区别仅为考虑进位位,其他与加法指令相同。
例1 设(A)=0AAH,(R0)=55H,C=1,则执行指令:
ADDC A, R0
运算结果:(A)=00000000B,CY=1
3. 带借位减指令
指令助记符与功能说明如下:
目的操作数
源操作数
功能说明
源操作数寻址方式
SUBB
A,
#data
;(A)←(A)-data-(C)
立即寻址
SUBB
A,
direct
;(A)←(A)-(direct)-(C)
直接寻址
SUBB
A,
@Ri
;(A)←(A)-((Ri))-(C)
寄存器间接寻址
SUBB
A,
Rn
;(A)←(A)-(Rn)-(C)
寄存器寻址
在单字节相减时,为了避免相减后结果出错,必须先清0借位位C。
例1 设(40H)=0BAH,(41H)=98H,试编写40H内容减去41H内容后,结果再存入40H单元的程序。
MOV A, 40H ;(A)←(40H)
CLR C ;进位位C清0
SUBB A, 41H ;(A)←(A)-(41H) -(C)
MOV 40H, A ;(40H)←(A)
执行以上程序后,(40H)=22H,CY=0,OV=0。
.2 乘除运算指令(2条)
1. 乘法指令
MUL AB ;(A)←乘积低8位,(B)←乘积高8位
该指令把累加器A与寄存器B中的8位无符号整数相乘,所得到的16位乘积的低8位存放在累加器A中,高8位存放在寄存器B中。
如果二者的乘积大于255(0FFH),则溢出标志位置1,否则清0;运算结果总使进位标志位CY清0。
例1 设(A)=67H(103),(B)=0ADH(173),执行指令:
MUL AB
运算结果:乘积为459BH(17819),(A)=9BH,(B)=45H。另外:OV=1,CY=0
2. 除法指令
DIV AB ;(A)←商,(B)←余数
该指令是将累加器A中的8位无符号整数除以寄存器B中的8位无符号整数,所得商存放在累加器A中,余数存放在寄存器B中。进位位CY与溢出位OV均清0。
若寄存器B中除数为0,则执行除法指令后,结果为不定值,并使溢出标志位OV置1,但在任何情况下,进位标志CY总清0。
例1 设(A)=9AH,(B)=23H,执行指令:
DIV AB
则(A)=04H,(B)=0EH
.3 增1减1指令(9条)
1. 增1指令
INC A ;(A)←(A)+1
INC direct ;(direct)←(direct)+1
INC @Ri ;((Ri))←((Ri))+1
INC Rn ;(Rn)←(Rn)+1
INC DPTR ;(DPTR)←(DPTR)+1
INC指令把所指出的变量加1,计算结果仍然送回原地址单元。原来的内容若为0FFH,则加1后将变为00H,运算结果中,只有INC A指令影响P标志位,对其余标志位无任何影响。
该指令使用3种寻址方式:寄存器寻址,直接寻址、寄存器间接寻址。
例1 设(A)=40H,(41H)=29H,则执行下列指令:
INC A ;(A)←40H+1H
INC 41H ;(41H)←29H+1H
结果:(A)=41H,(41H)=2AH
2. 减1指令
DEC A ;(A)←(A)-1
DEC direct ;(direct)←(direct)-1
DEC @Ri ;((Ri))←((Ri))-1
DEC Rn ;(Rn)←(Rn)-1
DEC指令把所指出的变量减1,计算结果仍然送回原地址单元。原来的内容若为00H,则减1后将变为0FFH,运算结果中,只有DEC A指令影响P标志位,对其余标志位无任何影响。
该指令使用3种寻址方式:寄存器寻址,直接寻址、寄存器间接寻址。
例1 设(R0)=4FH,片内RAM单元(4FH)=40H,(4EH)=00H,执行指令:
DEC @R0 ;(4FH)←3FH
DEC R0 ;(R0)←4EH
DEC @R0 ;(4EH)←0FFH
结果:(R0)=4EH,(4EH)=0FFH,(4FH)=3FH
.4 二/十进制调整指令(1条)
DA A
该指令的功能是对累加器A中的“二/十”进制(BCD码)加法结果进行调整。
要保证参加运算的两数为BCD码,在对BCD码进行二进制加法运算(ADD与ADDC指令)后,紧跟着一条“DA A”指令即可。
例1 执行下面的指令:
MOV A, #86H
ADD A, #47H
结果:(A)=0CDH,CY=0,AC=0
所得结果并不是BCD码,若接着执行以下指令:
DA A
则结果:(A)=33H,CY=1,AC=1
三. 逻辑运算指令(24条)
.1 单操作数指令(6条)
1. 累加器A清0
指令格式:
CLR A
功能:将00H送入累加器A中。
2. 累加器A取反
指令格式:
CPL A
功能:将累加器A中内容取反(将A中内容按位取反,即逻辑非运算)后再送回累加器A中。
例1 设(A)=98H,执行指令
CLR A ;(A)←0
CPL A ;(A)←0FFH
结果:(A)=0FFH
3. 累加器A内容循环左移一位
指令格式:
RL A
功能:将累加器A中的内容循环左移一位。即
例1 设(A)=10001000,则执行指令“RL A”后,结果:(A)=00010001
4. 累加器A内容带进位位CY循环左移一位
指令格式:
RLC A
功能:将累加器A中的内容与进位标志位CY一起循环左移一位。即:
例1 设(A)=01010101,(CY)=1。则执行指令“RLC A”后,结果:(A)=10101011,(CY)=0。
5. 累加器A内容循环右移一位
指令格式:
RR A
功能:将累加器A中的内容循环右移一位。即:
例1 设(A)=00010001,则执行指令“RR A”后,结果:(A)=10001000
6. 累加器A内容带进位位CY循环右移一位
指令格式:
RRC A
功能:将累加器A中的内容与进位标志位CY一起循环右移一位。即:
例1 设(A)=10101011,(CY)=0。则执行指令“RRC A”后,结果:(A)=01010101,(CY)=1。
.2 双操作数指令(18条)
1. 逻辑与指令
逻辑与的规则定义为:有0出0,全1出1
这类指令格式如下:
目的操作数 源操作数
ANL A, Rn ;n=0, …, 7
ANL A, direct
ANL A, @Ri ;i=0, 1
ANL A, #data
ANL direct, A
ANL direct, #data
这组指令的功能是将目的操作数单元中的内容与源操作数单元中的内容按位相“与”后,结果再送回目的操作数单元中。
例1 设(A)=0C3H,(R3)=0ADH,执行指令“ANL A, R3”。
结果:(A)=81H(10000001B)。
指令执行过程如下:
2. 逻辑或指令
逻辑或的规则定义为:有1出1,全0出0
这类指令格式如下:
目的操作数 源操作数
ORL A, Rn ;n=0, …, 7
ORL A, direct
ORL A, @Ri ;i=0, 1
ORL A, #data
ORL direct, A
ORL direct, #data
这组指令的功能是将目的操作数单元中的内容与源操作数单元中的内容按位相“或”后,结果再送回目的操作数单元中。
例1 设(A)=0C3H,(R3)=0ADH,执行指令“ORL A, R3”。
结果:(A)=0EFH(11101111B)。
指令执行过程如下:
3. 逻辑异或指令
逻辑异或的规则定义为:同出0,异出1
这类指令格式如下:
目的操作数 源操作数
XRL A, Rn ;n=0, …, 7
XRL A, direct
XRL A, @Ri ;i=0, 1
XRL A, #data
XRL direct, A
XRL direct, #data
这组指令的功能是将目的操作数单元中的内容与源操作数单元中的内容按位相“异或”后,结果再送回目的操作数单元中。
例1 设(A)=0C3H,(R3)=0ADH,执行指令“XRL A, R3”。
结果:(A)=6EH(01101110B)。
指令执行过程如下:
四 位操作类指令(12条)
指令中可被单片机汇编程序识别的位地址有多种方式:
(1) 直接位地址方式:如D5H。
(2) 字节地址位数方式:如B8.0。
(3) 位寄存器的定义名称,如C等。
(4) 对于位寻址寄存器,可以用字节寄存器名加位数来表示,二者之间用“.”隔开。如PSW.3等。
(5) 用户定义方式:如用伪指令:AA bit PSW.4;定义后允许用AA代表PSW.4。
.1 位数据传送指令
指令助记符与功能说明如下:
目的操作数 源操作数 功能说明
MOV C, bit ;(C)←(bit)
MOV bit, C ;(C)←(bit)
指令完成的功能是把第二操作数所指出的布尔变量送到由第一操作数指定的位单元。其中的一个操作数必为位累加器(进位标志C),另一个可以是任何直接寻址位(bit)。指令执行的结果不影响其他寄存器或标志。
例1 要将20H位的内容传送给23H位,不能直接用“MOV 20H, 23H”,因为该指令执行的实际是字节传送,若要将20H位的内容传送给23H位,可用下述程序实现:
MOV C, 20H ;(C)←(20H)
MOV 23H, C ;(23H)←(C)
2 位状态控制指令
1. 位清0指令
指令格式如下:
CLR C ;(C)←(0)
CLR bit ;( bit)←(0)
以上指令可使直接寻址位(bit)或位累加器C清0,不影响其他标志。
例1 片内RAM单元26H的内容为0FFH,执行指令:
CLR 32H
结果:(26H)=0FBH(11111011B),其中,32H为26H单元第二位的位地址。
2. 位求反指令
指令格式如下:
CPL C ;(C)←(/C)
CPL bit ;(bit)←(/bit)
以上指令把位累加器C或者直接寻址位(bit)内容取反,不影响其他标志位。
例1 执行下面的指令序列:
MOV P1,#2FH ;(P1)←(2FH即00101111B)
CPL P1.0 ;P1.0位求反
CPL P1.2 ;P1.2位求反
结果:(P1)=2AH(00101010B)。
3. 位置1指令
指令格式如下:
SETB C ;(C)←1
SETB bit ;(bit)←1
以上指令把进位标志C或者任何可直接寻址位(bit)置1,不影响其他标志位。
例1 假设进位标志C内容为0,输出口P1原来的内容为0FH(00001111B),则执行下面指令:
SETB C
SETB P1.7
结果:(C)=1,(P1)=8FH(10001111B)。
3 位逻辑操作指令
位逻辑操作指令只有两条:位与,位或。
1. 位与指令
指令助记符与功能说明如下:
目的操作数 源操作数 功能说明
ANL C, bit ;(C)←(C)∧(bit)
ANL C, /bit ;(C)←(C)∧(/bit)
位与指令的功能是将直接寻址位的内容或直接寻址位内容取反后(不改变原来位的内容)和位累加器C的内容相与,结果保存在C中。
例1 当位地址(2AH)=1,(32H)=1,同时累加器中(ACC.7)=0时,进位位C=1,否则C清0,可编程序如下:
MOV C, 2AH ;(C)←(2AH)
ANL C, 32H ;(C)←(C)∧(32H)
ANL C, /ACC.7 ;(C)←(C)∧(/ACC.7)
2. 位或指令
指令助记符与功能说明如下:
目的操作数 源操作数 功能说明
ORL C, bit ;(C)←(C)∨(bit)
ORL C, /bit ;(C)←(C)∨(/bit)
位或指令的功能是将直接寻址位的内容或直接寻址位内容取反后(不改变原来位的内容)和位累加器C的内容相或,结果保存在C中。
例1 写出位地址(2AH)=1和(32H)=1、累加器(ACC.7)=0相或的程序:
MOV C, 2AH ;(C)←(2AH)
ORL C, 32H ;(C)←(C)∨(32H)
ORL C, ACC.7 ;(C)←(C)∨(ACC.7)
结果:(C)=1。
.4 位条件转移指令
这类指令可分为判C或判直接寻址位状态转移两种。
1. 判C转移指令
JC rel ;若(C)=1,则(PC)←(PC)+2+rel;若(C)=0,则(PC)←(PC)+2
JNC rel ;若(C)=0,则(PC)←(PC)+rel;若(C)=1,则(PC)←(PC)+2
上述两条指令通过判进位位C的状态来决定程序的走向,前一条若进位标志为1,后一条若进位标志为0,就可使程序转向目标地址,否则顺序执行下一条指令。目标地址为第二字节所给的带符号的偏移量与PC当前值((PC)←(PC)+2)之和。指令的执行不影响任何标志。
图为判C转移指令的执行过程。
(a) JC rel (b) JNC rel
JB bit, rel ;若(bit)=1,则(PC)←(PC)+3+rel
;若(bit)=0,则(PC)←(PC)+3
JNB bit, rel ;若(bit)=0,则(PC)←(PC)+3+rel
;若(bit)=1,则(PC)←(PC)+3
JBC bit, rel ;若(bit)=1,则(PC)←(PC)+3+rel,而且(bit)清0
;若(bit)=0,则(PC)←(PC)+3
上述指令检测直接寻址位,若位变量为1(JB、JBC)或位变量为0(JNB),则程序转向目标地址执行,否则顺序执行下条指令。目标地址为(PC)←(PC)+3+rel。在检测位变量时,不影响任何标志,JB、JNB指令不影响原变量值,但JBC指令不管原变量为何值,检测后即行清0。
判直接寻址位转移指令的执行过程如图所示。
(a) JB bit, rel (b) JNB bit, rel (c) JBC bit, rel
五 控制转移类指令(22条)
。
.1 无条件转移指令
1. 长转移指令
指令格式:
LJMP addr16 ;(PC)←addr0~15
该指令又称为无条件转移指令,指令提供16位转移地址,因此,执行这条指令可以使程序从当前地址转移到64K程序存储器地址空间的任何单元,即0000H~FFFFH。指令的执行结果是将16位目的地址送入程序计数器PC。该指令为三字节指令:操作码、16位地址的高8位、16位地址的低8位。
2. 绝对转移指令
指令格式:
绝对转移指令也称为11位地址的无条件转移指令。与长转移指令的区别在于指令的操作数给出的是11位转移地址。该指令为一双字节指令,指令执行时,首先是PC的内容加2,然后由当前PC的高5位和指令中的11位偏移地址构成16位转移地址。该指令要求转移的目的地址的高5位和该指令执行时当前的PC值高5位相同,因此寻址范围为2KB(00000000000B~11111111111B),即可转移的范围为2KB区域。转移可以向前也可以向后。
其中:00001为操作码,~为目的地址的低11位。
该跳转指令要求目的地址和当前的PC值在同一2KB区域内。若把64KB程序存储器每2KB分为一页,则64KB空间共有32页,每一页地址范围如下:
第0页0000H~07FFH
第1页0800H~0FFFH
第2页1000H~17FFH
第30页F000H~F7FFH
第31页F800H~FFFFH
因此,AJMP要求在同一页内跳转。
3. 相对短转移指令
指令格式:
指令控制程序无条件转向指定地址。该地址由指令第二字节的相对地址和程序计数器PC的当前值(执行SJMP前的PC值加2)相加形成。因而转向地址可以在这条指令首地址的前128字节到后127字节之间,即+127~-128。负数表示反向转移,正数表示正向转移。
如果程序中使用:
SJMP $
将会造成单指令的无限循环。
4. 间接转移指令
JMP @A+DPTR ;(PC)←(A)+(DPTR)
该指令把累加器A中的8位无符号数与作为基址寄存器DPTR中的16位数据相加,所得的16位地址值装入程序计数器PC作为转移的目标地址。由于执行16位加法,从低8位产生的进位将传送到高位去。指令执行后不影响累加器A和数据指针DPTR中的内容,不影响任何标志位。
这是一条多分支选择转移指令,其转移地址不是汇编或编程时确定的,而是在程序运行时动态决定的,这是与前面三条指令的区别。这样可在DPTR中装入多分支转移程序的首地址,而由累加器A中的内容来动态选择其中的某一个分支程序予以转移,这就可用一条指令代替众多转移指令,实现以DPTR内容为起始的256个字节范围的选择转移。
.2 条件转移指令
条件转移指令必须是在满足指令中规定的条件情况下,程序才转移,否则程序顺序执行。其目标地址在以下一条指令的起始地址为中心的256字节范围中(-128~+127)。
1. 累加器A判零转移指令
JZ rel ;累加器为0转移,否则继续执行
JNZ rel ;累加器不为0转移,否则继续执行
JZ表示累加器A内容全为0,则转向指定地址,否则程序顺序执行;JNZ指令刚好相反:只须累加器A不为0,就转向指定地址,否则程序顺序执行。
上述两条指令均为双字节指令,且指令的执行不改变原累加器A的内容,不影响标志位。指令的执行过程如图所示。
例1 将内部RAM单元中起始地址为20H的数据传送到P1口,当RAM单元中内容为0时,不传送,接着传送下一单元内容。
(a) JZ rel (b) JNZ rel
程序设计如下:
MOV R0, #20H ;设置数据指针
LOOP: MOV A, @R0 ;内部RAM单元内容送入累加器A
INC R0 ;指向下一单元
JZ LOOP ;(A)=0则传送下一单元
MOV P1, A ;(P1)←(A)
SJMP LOOP ;继续执行
2. 比较转移指令
指令格式:
CJNE <目的操作数>, <源操作数>, rel
CJNE类指令比较前面两个操作数的大小,如果它们的值不相等则转移,相等则继续执行。这些指令都是三字节指令,PC当前值((PC)←(PC)+3与指令第三字节带符号的偏移量相加即得到转移地址。如果目的字节的无符号整数值小于源字节的无符号整数值,则进位标志位置1;否则进位标志位清0,指令不影响任何一个操作数。
具体的比较转移类指令有四条:
l CJNE A, #data, rel
l CJNE A, data, rel
l CJNE @Ri, #data, rel
l CJNE Rn, #data, rel
指令的操作过程如图所示。
由图1可以看出,CJNE指令先将源操作数与目的操作数进行比较,然后根据比较的结果来决定程序的走向。程序的转移范围是以PC当前值((PC)←(PC)+3为起始地址的+127~-128字节单元地址。
在MCS-51中没有专门的数值比较指令,两个数值大小的比较可利用这四条指令来实现,即按指令执行后CY的状态来判断数值的大小:
若源操作数<目的操作数,则(CY)=0;
若源操作数>目的操作数,则(CY)=1。
例1 设内部数据存储器的30H单元和31H单元之中各存放有一个8位无符号数,找出其中较大者送入40H单元。
这可通过CJNE指令和JC指令的配合使用,来实现两个数值大小的比较。具体程序如下:
MOV A, 30H ;(A)←(30H)
CJNE A, 31H, K1 ;(30H)≠(31H)则转移
MOV 40H, A
SJMP K3
K1: JC K2 ;(30H)<(31H)转移
MOV 40H, A ;(30H)>(31H)则存结果
SJMP K3
K2: MOV 40H, 31H ;存结果
K3: …
3. 循环减1转移指令
指令格式:
DJNZ <字节>, rel
这是一条减1并与0比较指令,程序每执行一次该指令,就把第一操作数字节变量减1,结果送回到第一操作数中,并根据字节变量是否为0,决定程序走向:不为0则转移;为0则顺序执行。如果字节变量原为00,则执行该指令后,内容变为0FFH,不影响标志位。这类指令共有两条:
l DJNZ data, rel
l DJNZ Rn, rel
循环减1转移指令的操作过程如图所示。
这两条指令主要用于控制程序循环。如预先把寄存器或内部RAM单元赋值循环次数,则利用减1后是否为0作为转移条件,即可实现按次数控制循环。是一条三字节指令。
例1 将内部RAM区中从30H开始的16个单元内容清0。
利用DJNZ指令编写程序如下:
MOV R0, #30H ;设置地址指针
MOV R7, #10H ;设置数据指针
CLR A
LOOP: MOV @R0, A ;内部RAM单元清零
INC R0 :修改地址指针
DJNZ R7, LOOP ;(R7)≠0则继续
SJMP $
3 子程序调用和返回指令
MCS-51单片机有两条调用指令LCALL(长调用)、ACALL(绝对调用)和一条与之配对的子程序返回指令RET。
1. 长调用指令
指令格式:
长调用指令提供16位地址,可调用64K范围内所指定的子程序,由于是三字节指令,执行时首先(PC)+3→(PC),从而获得下一条指令地址,并把此时PC内容压入堆栈(作为返回地址,先压入低字节后压入高字节),堆栈指针SP加2指向栈顶,然后把目标地址addr16装入PC,转入子程序。该指令的执行不影响标志位。
2. 绝对调用指令
指令格式:
该指令提供11位目标地址,限在2K地址内调用,由于是双字节指令,所以执行时(PC)←(PC)+2,从而获得下一条指令的地址,然后把该地址压入堆栈作为返回地址。
3. 返回指令
指令格式:
RET表示子程序结束需要返回主程序,所以执行该指令时,分别从堆栈中弹出调用子程序时压入的返回地址,使程序从调用指令(LCALL或ACALL)的下相邻指令开始继续执行主程序。
4. 中断返回指令
指令格式:
RETI
该指令用于中断返回。执行过程类似于RET。
RET与RETI指令应分别放在子程序和中断服务程序的最后。
5. 空操作指令
指令格式:
NOP ;(PC)←(PC)+1
执行该指令出了
展开阅读全文