您的位置: 网站首页 > 电子与嵌入式 > 单片机原理与应用 > 第3章 MCS-51单片机指令系统 > 【3.3.5 程序转移类指令】

3.3.5 程序转移类指令

 

计算机程序运行过程中,以PC累加l实现程序顺序执行,但在处理一些较复杂的控制系统时,需要发生程序转移,即改变PC的值将程序跳转到某个指定的地址再顺序执行,控制转移类指令可以改变PC的值,实现程序转移的目的。

MCS-51单片机的程序转移指令共14条,可进一步细分为无条件转移指令、条件转移指令、子程序调用指令等。另有位条件转移类指令,已在位操作指令中进行了介绍。所有程序转移类指令执行时间都是两个机器周期。

1.无条件转移指令

无条件转移指令的功能是当程序碰到该指令时,无条件转移到该指令提供的地址去。MCS-514条无条件转移指令,分别提供了不同的转移范围和转移方式。

1)绝对转移指令。

AJMP addr11         ;PC100addr11

说明:1)本指令为2KB地址范围内的转移指令。转移的目的地址要求与AJMP指令后面一条指令在同一个2KB范围。MCS-51单片机的64KB程序存储器划分为32个连续的2KB空间。每一个2KB空间称为1页,如下所示。

2)本指令为双字节指令。设addr11的各位是a10a9a8a2a1a0,则指令

AJMP addr11的二进制机器码为a10a9a800001a7a6a5a4a3a2a1a0

64KB程序存储器中页的具体划分如下。

0000H07FFH0800H0FFFH1000H17FFH1800H1FFFH2000H27FFH

2800H2FFFH3000H37FFH3800H3FFFH4000H47FFH4800H4FFFH

5000H57FFH5800H5FFFH6000H67FFH6800H6FFFH7000I77FFH

7800H7FFFH8000H87FFH8800H8FFFH9000H97FFH9800H9FFFH

A000HA7FFHA800HAFFFHB000HB7FFHB800HBFFFHC000HC7FFH

C800HCFFFHD000HD7FFHD800HDFFFHE000HE7FFHE800HEFFFH

F000HF7FFHF800HFFFFH

【例3-14若在ROM中的07FDH07FEH两地址单元处有一条AJMP指令,试问它向高地址方向跳转有无余地?

解:AJMP指令执行过程中,要求PC值的高5位不能发生变化。但是在执行本例的AJMP指令时PC内容已经等于是07FFH,若向高地址跳转就到0800H以后了,这样高5位地址就要发生变化,这是不允许的。换言之,07FFH是第02KB页面中的最后一个字节,因此从这里往高地址方向再无AJMP跳转的余地了。

上述表明,笼统地谈AJMP的跳转范围为2KB是不确切的,而应当说AJMP跳转的目的地址必须与AJMP后面一条指令位于同一个2KB页面范围之内。

2)长转移指令。

LJMP addrl6          ;PCaddrl6

说明:本指令为64KB程序存储器空间的全范围转移指令,转移地址可为64KB地址值中的任一值。本指令为3字节指令。

3)短(相对)转移指令。

SJMP rel             ;PCPC+2+rel

说明:本指令为相对转移指令。因为rel1字节补码(偏移量,且SJMP rel指令为双字节指令,所以转移范围为-126D+129D,共计256个单元。

例如,LOOPlSJMP LOOP2

LOOPl标号处地址为0100HLOOP2标号处地址为0130H,则目标地址为0130H,偏移量rel=0130H-0100H-2H=2EH

LOOPl标号处地址为0100HLOOP2标号处地址为00E4H,则目标地址为00E4H,偏移量rel=00E4H-0100H-2H=-1EH,用补码表示rel=0E2H

4)间接转移指令。

JMP @A+DPTR          ;PC(A)+(DPTR)

该指令转移的目的地址是累加器ADPTR的内容之和。该指令常用在分支程序中,又称为分支指令。通常将DPTR作为目标转移地址的基地址,根据A中不同的值实现程序的多分支转移。

例如,A=10HDPTR=2000H,指令JMP@A+DPTR执行后,PC=2010H。也就是说,程序转移到2012H地址单元去执行。如A=20H,则转移到2022H地址单元执行。

【例3-15要求当A=00H时,程序散转到KEY0;当A=01H时,散转到KEYI等。

解:据题意程序如下。

         CLR C                ;清进位位

       RLC A                ;累加器内容乘2

         MOV DPTR,#TABLE

JMP @A+DPTR

……

TABLEAJMP KEY0

         AJMP KEYl

         AJMP KEY2

    ……

2.条件转移指令

条件转移是指程序发生转移是有条件的,若指令中所规定的条件满足,则程序发生转移,若不满足指令所规定的条件,则程序顺序执行。

条件转移指令发生转移时,都是以相对寻址方式得到目标地址,指令的执行过程是先进行条件判断,后决定程序的走向。指令的转移范围非常有限,仅为-128+127256

1)累加器为零非零转移指令。

JZ   rel                 ;A=0则转移(PCPC+2+rel),若A≠0程序顺序执行

JNZ  rel                ;A≠0则转移(PCPC+2+rel),若A=0程序顺序执行

2)减1非零转移指令。

DJNZ Rn,rel             ;RnRn-1,若Rn≠0,则转移(PCPC+2+rel)

                         ;Rn=0,则程序顺序执行

DJNZ dir,rel            ;dir(dir)-1,若(dir)≠0,则转移(PCPC+3+rel)

                         ;(dir)=0,则程序顺序执行

说明:DJNZ Rnrel是双字节指令,DJNZ dirrel3字节指令,所以在满足转移的条件后,前者的结果是PCPC+2+rel,后者的结果是PCPC+3+rel

3)两数不等转移指令。

    CJNE A,dir,rel      ;A≠(dir),则转移(PCPC+3+-rel)否则程序顺序执行

    CJNE A,#data,rel    ;A≠#data,则转移(PCPC+3+rel)否则程序顺序执行

    CJNE@Ri,#data,rel   ;((Ri))≠#data,则转移(PCPC+3+rel)否则程序顺序执行

说明:CJNE指令对标志C有影响。若第一操作数大于或等于第二操作数,则C=0,如指令CJNE AdirrelA(dir);若第一操作数小于第二操作数,则C=1,如指令CJNE AdirrelA(dir)。利用对C的判断,可使这几条指令实现两操作数相等与否的判断,还可完成两数大小的比较。

例如,R2=23H,执行CJNE R2#34H$+08H指令后,程序转移到本条CJNE指令的首地址($08H后的地址单元去执行。

4)相对偏移量rel的求法。

在短转移和条件转移中,用偏移量rel和转移指令所处的地址值来计算转移的目的地址,rel1字节补码值,如果rel是正数的补码,程序往前转移;如果rel是负数的补码,程序往回转移。

设本条转移指令的首地址为As,指令长Bn23字节,要转移到的地址为目的地址An,这三者之间的关系为:

                     rel=An-(As+Bn)

在已知源地址、目的地址和指令长度时,可由上述公式计算rel的大小。

【例3-16一条短转移指令“SJMP rel”的首地址为2010H单元。求:转移到目的地址为2020H单元的rel转移到目的地址为2000H单元的rel

解:SJMP rel”是双字节指令,故Bn=2,则由题意知,As=2010H。所以

① rel=(2020H-2010H-2)=(0EH)=0EH   

② rel=(2000H-2010H-2)=(-12H)=0EEH

中,rel是正数的补码,所以实现了向前地址增大)方向的转移;在中,rel是负数的补码,所以实现了向回地址减小方向的转移。

【例3-17已知内部RAMM1M2单元中各有一个无符号8位二进制数,试编程比较它们的大小,并把大数送到MAX单元。

解:相应程序如下。

    MOV A,M1

    CJNE A,M2,LOOP

    LOOP :   JNC LOOPl

    MOV A,M2

    LOOP1:   MOV MAX,A

             RET

3.调用子程序及返回指令

子程序的调用和返回指令共有4条。

1)调用子程序指令。

LCALL addrl6    ;PCPC+3  SPSP+1(SP)PC70

;SPSP+1,(SP)PC158PCaddrl6

ACALL addr11    ;PCPC+2  SPSP+1(SP)PC70

;SPSP+1(SP)PC158PC100addr11

在程序设计时,通常把一些重复的操作或运算编成子程序独立出来以供调用。原来的程序称为主程序,主程序可以调用子程序。实现这种调用功能的指令称为调用指令。子程序通过子程序返回指令来实现程序返回。

LCALL指令可调用在64KB范围内所指定的子程序,为长调用指令,addrl6是子程序入口地址。执行时,先将断口地址(调用指令下面一条指令的地址压入堆栈,然后将子程序入口地址装入PCCPU转而执行子程序。

上述第二条指令ACALL为短调用指令(双字节指令,其执行过程类似LCALL指令。但是,由于指令只提供了11位子程序入口地址,因此被调用的子程序入口地址必须与调用指令ACALL的下一条指令的第一个字节位于相同的2KB存储区内。设addr11a10a9a8a2a1a0,则指令ACALL addr11的机器码为a10a9a810001a7a6a5a4a3a2a1a0

2)返回指令。

RET          ;PC15~8(SP),SPSP-1

            ;PC7~0(SP),SPSP-1

RETI        ;PC15~8(SP),SPSP-1

            ;PC7~0(SP),SPSP-1

第一条指令是子程序返回指令。指令的功能是:将堆栈内的断口地址弹出送入PC,使CPU返回到原断口地址处继续执行原程序。

第二条指令是中断返回指令。这条指令将堆栈内的断口地址弹出送入PC,使CPU返回到原断口地址处执行原程序,并清除内部相应的中断状态寄存器(该寄存器由CPU响应中断时置位的内容。它只能用于中断服务程序。

返回指令置于子程序或中断服务程序的末尾,表示子程序或中断服务程序的结束。

4.空操作指令

NOP          ;PCPC+1

这是一条单字节指令。该指令执行时,不作任何操作(即空操作,仅将程序计数器PC的内容加1,使CPU指向下一条指令继续执行程序。这条指令常用来产生一个机器周期的时间延迟。

5.程序转移类指令汇总

程序转移类指令汇总表如表3-6所示。

3-6  程序转移类指令汇总表

   

功能说明

   

振荡器周期

LJMP addrl6

长转移

3

24

AJMP addr11

绝对转移

2

24

SJMP rel

短转移相对偏移

2

24

JMP @A+DPTR

相对DPTR的间接转移

1

24

JZ rel

累加器为零则转移

2

24

JNZ rel

累加器为非零则转移

2

24

CJNE Adirectrel

比较直接寻址字节和A不相等则转移

3

24

CJNE A#datarel

比较立即数和A不相等则转移

3

24

CJNE Rn#datarel

比较立即数和寄存器不相等则转移

3

24

CJNE @Ri#datarel

比较立即数和间接寻址RAM不相等则转移

3

24

DJNZ Rnrel

寄存器减“1”不为零则转移

3

24

续上表

   

功能说明

   

振荡器周期

DJNZ directrel

直接寻址字节减“1”不为零则转移

3

24

ACALL addr11

绝对调用子程序

2

24

LCALL addr16

长调用子程序

3

24

RET

从子程序返回

1

24

RETI

从中断返回

1

24

NOP

空操作

1

12