控制转移类指令用于控制程序的走向。其中包括:无条件转移指令、条件转移指令以及子程序调用和返回指令,其作用区间是程序存储器空间,这类指令一般不影响标志位。控制转移类指令用到的助记符有:LJMP、AJMP、SJMP、JMP、JZ、JNZ、CJNE、DJNZ等多种。由于这些指令的助记符多为英文单词的缩写,需要我们多加记忆。
1.无条件转移指令(4条)
无条件转移指令的功能是当程序执行完此类转移指令后,程序就无条件地转到指令所提供的目的地址去。
LJMP addr16 ;PC←addr16
AJMP addr11 ;PC←(PC)+2,PC10~0←addr11,PC15~11不变
SJMP rel ;PC←(PC)+2+rel
JMP @A+DPTR ;PC←(A)+(DPTR)
第一条指令称为长转移指令。该指令为3字节指令,指令中提供16位目标地址,将指令中第二字节和第三字节地址码分别装入PC的高8位和低8位中,以实现程序的转移。所以该指令转移的目标地址范围是在整个64K字节的存储空间内。
第二条指令称为绝对转移指令。该指令为2字节指令,指令中提供11位目标地址,所以该指令转移的目标地址范围是从下条指令开始的2K字节的存储空间内,如图3.2所示。
图3.2 AJMP指令执行示意图
由图3.2可见,该指令的转移地址由指令操作码的高3位和第二字节组成,可以在2K字节的存储空间内实现转移。
第三条指令称为相对转移指令又称为短转移指令。该指令为2字节指令,指令中的rel是一个带符号的相对偏移量,范围为-128~+127。负数表示向后转移,正数表示向前转移,该指令执行后程序转移到当前PC值与rel之和所指示的单元地址处。
第四条指令称为间接转移指令又称散转移指令。转移地址由数据地址指针DPTR与该累加器A中的8位无符号数之和形成。该指令执行后不影响DPTR和A中的原内容,也不影响任何标志位,只是把相加的结果直接送PC,以实现程序的转移。
【例3.20】根据data的数值设计散转表程序,当data=0时,转处理程序G0,当data=1时,转处理程序G1,…,当data=n时,转处理程序Gn。编程如下:
MOV A,#data
RL A ;将A修正为偶数
MOV DPRT,#TABLE ;表首址送DPTR
JMP @A+DPTR ;以A中内容为偏移量跳转
TABLE:AJMP G0
AJMP G1
AJMP G2
AJMP Gn
(注意:data可以是任意数,但由于AJMP是双字节指令,所以A中的数值必须修正为偶数)。
2.条件转移指令(13条)
条件转移指令是依据某种特定条件实现转移的指令。条件满足时实现转移,其目标地址在下一条指令的起始地址为中心的256个字节范围内(-128~+127);条件不满足时则顺序执行下面一条指令。
条件转移指令非常丰富,包括判累加器零转移、判位状态转移、比较转移和循环转移共4组。
JZ rel ;若(A)=0,则转移,PC←(PC)+2+rel
若(A)≠0,则顺序执行,PC←(PC)+2
JNZ rel ;若(A)≠0,则转移,PC←(PC)+2+rel
若(A)=0,则顺序执行,PC←(PC)+2
CJNE A,direct,rel ;若(A)=(direct),则顺序执行,PC←(PC)+3,C←0
若(A)>(direct),则转移,PC←(PC)+3+rel,C←0
若(A)<(direct),则转移,PC←(PC)+3+rel,C←1
CJNE A,#data,rel ;若(A)=data,则顺序执行,PC←(PC)+3,C←0
若(A)>data,则转移,PC←(PC)+3+rel,C←0
若(A)<data,则转移,PC←(PC)+3+rel,C←1
CJNE Rn,#data,rel ;若(Rn)=data,则顺序执行,PC←(PC)+3,C←0
若(Rn)>data,则转移,PC←(PC)+3+rel,C←0
若(Rn)<data,则转移,PC←(PC)+3+rel,C←1
CJNE @Ri,#data,rel ;若(Ri)=data,则顺序执行,PC←(PC)+3,C←0
若(Ri)>data,则转移,PC←(PC)+3+rel,C←0
若(Ri)<data,则转移,PC←(PC)+3+rel,C←1
DJNZ Rn,rel ;Rn←(Rn)-1,若(Rn)≠0,则转移,PC←(PC)+2+rel
若(Rn)=0,则顺序执行,PC←(PC)+2
DJNZ direct,rel ;direct←(direct)-1,
若(direct)≠0,则转移,PC←(PC)+3+rel
若(direct)=0,则顺序执行,PC←(PC)+3
JC rel ;若C=1,则转移,PC←(PC)+2+rel(www.xing528.com)
若C=0,顺序执行,PC←(PC)+2
JNC rel ;若C=0,则转移,PC←(PC)+2+rel
若C=1,顺序执行,PC←(PC)+2
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
JZ和JNZ指令是判别累加器A的内容是否为0来确定是顺序执行还是转移。
CJNE是比较转移指令,该指令通过比较前面两个操作数的大小,如果它们的值不相等则转移,相等则顺序执行。指令执行后要影响进位位CY,若操作数1小于操作数2,则CY=1;若操作数1大于操作数2,则CY=0。
JC、JNC、JB和JNB指令的功能分别是判别进位位CY和直接位地址的内容是“1”还是“0”,以此来决定程序的走向。JBC指令的功能是:若直接位地址的内容为“1”则转移,并且同时将该位清0,否则顺序执行。这条指令若是对I/O口某一位进行操作,也具有“读-改-写”功能。
【例3.21】MOV P1,#87H ;P1←87H
MOV A,#55H ;A←55H
JB P1.3,L1 ;若P1.3=1,转L1;若P1.3=0,不转
JNB ACC.3,L2 ;若ACC.3=0,转L2处执行
L1:
L2:
3.调用子程序及返回指令(4条)
在程序设计中,经常需要对某段程序反复执行,为了减少程序的编写以及节省存储空间,于是引入了主程序和子程序的概念,通常把某一段需反复调用的程序称为子程序,子程序的最后一条指令为返回主程序指令(RET),而对具有调用子程序功能的指令称为调用指令。
LCALL addr 16 ;PC←(PC)+3,SP←(SP)+1,((SP))←(PC7~0),SP←(SP)+1,((SP))←(PC15~8),PC←addr 16
ACALL addr 11 ;PC←(PC)+2,SP←(SP)+1,((SP))←(PC7~0),SP←(SP)+1,((SP))←(PC15~8),(PC10~0)←addr 10~0,PC15~11保持不变
RET ;PC15~8←((SP)),SP←(SP)-1,PC7~0←((SP)),SP←SP-1
RETI ;中断返回,除具有RET的功能外还可以恢复中断逻辑。
LCALL指令称为长调用指令,其与LJMP一样提供16位地址,可调用64K字节范围内的子程序。由于其为三字节指令,所以执行时首先PC←(PC)+3,以获得下一条指令地址,并把此时的PC内容压入堆栈,作为返回地址,然后把目标地址addr16装入PC,转去执行子程序。
ACALL指令称为绝对调用指令,该指令提供11位目标地址,限制在2K字节范围内调用,由于是双字节指令,所以执行时PC←(PC)+2以获得下一条指令的地址,然后把该地址压入堆栈作为返回地址。其操作码的形成与AJMP指令相同。
RET指令称为子程序返回指令,表示子程序结束时需返主程序,所以执行该指令时,分别从堆栈中弹出调用子程序时压入的返回地址。
RETI指令称为中断返回指令,该指令的执行过程类似指令RET,但其还能恢复中断逻辑。需要注意的是RET和RETI决不能互换使用,RETI仅用于中断服务子程序的返回。
4.空操作指令(1条)
NOP ;PC←(PC)+1
空操作指令除了使PC加1外,CPU不作任何操作,而转去执行下一条指令。这条指令常用于产生一个机器周期的延时。
【例3.22】软件延时子程序,设晶振频率12MHz(即每个机器周期为1μs)。
DELAY:MOV R7,#0FAH(#250)
L1: NOP
NOP
DJNZ R7,L1
RET
此软件延时子程序产生的延时时间为:(1+(1+1+2)×250+1)×1μs=1002μs≈1ms
【例3.23】利用NOP指令产生方波从P1.0输出。
HERE:CLR P1.0 ;P1.0清0(P1.0输出低电平)
NOP ;空操作,延时
NOP
NOP
SETB P1.0 ;P1.0置1(P1.0输出高电平)
NOP ;空操作,延时
NOP
NOP
SJMP HERE ;无条件返回,继续循环
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。