这条指令的机器码存于0100H和0101H两个单元之中)。标号LOOPl的值为0123H,即跳转的目标地址为0123H,则指令的第二个字节(相对偏移量)应为: rel = 0123H-0102H = 21H
(4).变址寻址转移指令
JMP @A+DPTR ;PC ← (A)+ DPTR 这是一条一字节转移指令。转移的目的地址由A的内容和DPTR内容之和来确定,即目的地址 =(A)+(DPTR)。本指令以DPTR内容为基址,而以A的内容作变址,因此只要把DPTR的值固定,而给A赋以不同的值,就可实现程序的多分支转移。键盘译码程序就是本指令的一个典型应用。
2、条件转移指令组
所谓条件转移就是程序转移是有条件的。执行条件转移指令时,如指令中规定的条件满足,则进行程序转移,否则程序顺序执行,相当于高级语言中的if?go to语句。条件转移有如下指令:
(1).累加器判零转移指令
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
这两条指令都是二字节指令,是有条件的相对转移指令,以rel为偏移量。
[例3-4] 将外部数据RAM的一个数据块传送到内部数据RAM中,两者的首地址分别为DATA1和TATA2,遇到传送的数据为0时停止。
解:外部RAM向内部RAM的数据传送一定要借助于累加器A,利用累加器判零转移指令正好可以判别是否要继续传送或者终止。
;外部数据块首地址 MOV # DATA1H R0 ,
;内部数据块首地址 MOV # DATA2H R1 ,
;外部数据送给A @R0 LOOP: MOVX A ,
;为0则终止 HERE HERE: JZ
;不为0传送内部RAM数据 MOV @R1 , A
;修改地址指针 INC R0
INC R1
;继续循环 SJMP LOOP
(2).数值比较转移指令
数值比较转移指令把两个操作数进行比较,比较结果作为条件来控制程序转移,共有4条指令:
;累加器内容与立即数不等则CJNE A , rel # data ,
转移
CJNE A , CJNE Rn , CJNE @Ri,
direct , # data , # data ,
rel rel rel
;累加器内容与内部RAM单元内容不等则转移 ;寄存器内容与立即数不等则转移
;内部RAM低 128单元内容与立即数不等则转移
数值比较转移指令是三字节指令,这是MCS- 51指令系统中仅有的4条3个操作数的指令。
在程序设计中非常有用。这4条指令的功能可从程序转移和数值比较两个方面来说明。
①程序转移 为简单起见,把指令中的两个比较数据分别称之为左操作数和右操作数,则指令的转移可按以下3种情况说明:
若左操作数 = 右操作数,则:
程序顺序执行 PC ← (PC) + 3 进位标志位清“0” CY ← 0
若左操作数 > 右操作数,则:
程序转移 PC ← (PC) + 3 + rel 进位标志位清“0” CY ← 0
若左操作数 < 右操作数,则:
程序转移 PC ← (PC) + 3 + rel 进位标志位置“l” CY ← 1
②数值比较
在MCS- 51中没有专门的数值比较指令,两个数的数值比较可利用这4条指令来实现,数值比较可在程序转移的基础上进行,即:
程序顺序执行, 则 左操作数 = 右操作数 程序转移且(CY)= 0,则 左操作数 > 右操作数 程序转移且(CY)= 1,则 左操作数 < 右操作数
(3).减1条件转移指令
这是一组把减1与条件转移两种功能结合在一起的指令,共2条: ①寄存器减1条件转移指令
DJNZ rel Rn , 这是一条两字节指令,其功能为:寄存器内容减1,如所得结果为0,则程序顺序执行;
如没有减到0,则程序转移。具体表示如下:
Rn ←(Rn)– 1 若 (Rn)≠ 0, 则PC ← (PC)+ 2 + rel
若 (Rn)= 0, 则PC ← (PC)+ 2
②直接寻址单元减1条件转移指令
DJNZ direct , rel 这是一条三字节指令,其功能为直接寻址单元内容减1,如所得结果为0,则程序顺序
执行;如没有减到0,则程序转移。具体表示如下:
direct ←(direct)– 1 若 (direct) ≠ 0, 则PC ← (PC) + 3 + rel
若 (direct) = 0, 则PC ← (PC) + 3
这2条指令主要用于控制程序循环。如预先把寄存器或内部RAM单元赋值循环次数,则利用减1条件转移指令,以减1后是否为0作为转移条件,即可实现按次数控制循环。
[例3-5] 把2000H开始的外部RAM单元中的数据送到3000H开始的外部RAM单元中,数据个数已在内部RAM35H单元中。
;源数据区首地址 MOV # 2000H DPTR ,
;源首址暂存堆栈 PUSH DPL
PUSH DPH
;目的数据区首址 MOV # 3000H DPTR ,
;目的首址暂存寄存器 MOV DPL R2 ,
MOV R3 DPH
;取回源地址 DPH LOOP: POP
POP DPL
;取出数据 MOVX @DPTR A ,
;源地址增量 INC DPTR
;源地址暂存堆栈 PUSH DPL
PUSH DPH
;取回目的地址 MOV R2 DPL ,
MOV R3 DPH ,
;数据送目的区 MOVX @DPTR , A
;目的地址增量 INC DPTR
;目的地址暂存寄存器 MOV DPL R2 ,
MOV DPH R3 ,
;没完,继续循环 DJNZ LOOP 35H ,
;返回主程序 RET
从上述两种转移指令的介绍中我们可以看出,无条件转移指令有直接寻址和相对寻址两种方式,而条件转移指令则只有相对寻址一种寻址方式。
3、子程序调用与返回指令组
子程序结构是一种重要的程序结构。在一个程序中经常遇到反复多次执行某程序段的情况,如果重复书写这个程序段,会使程序变得冗长而杂乱。对此,可采用子程序结构,即把重复的程序段编写为一个子程序,通过主程序调用而使用它,这样不但减少了编程工作量,而且也缩短了程序的长度。
调用和返回构成了子程序调用的完整过程。为了实现这一过程,必须有子程序调用指令和返回指令。调用指令在主程序中使用,而返回指令则应该是子程序的最后一条指令。执行完这条指令之后,程序返回主程序断点处继续执行。
(1)绝对调用指令
ACALL addr 11
这是一条二字节指令,其指令格式为:
A10 A9 A8 1 0 1 0 0 A7 A6 A5 A4 A3 A2 A1 A0
在指令中提供了子程序入口地址的低11位,这11位地址的A7~A0在指令的第二字节中,A10~A8则占据第一字节的高3位。
为了实现子程序调用,该指令共完成两项操作: ①断点保护
断点保护是通过自动方式的堆栈操作实现的,即把加2以后的PC值自动送堆栈保存起来,待子程序返回时再送回PC。
②构造目的地址
目的地址的构造是在PC加2的基础上,以指令提供的11位地址取代PC的低11位,而PC的高5位不变。例如程序中有绝对调用指令:
8100H ACALL 48H Addr11的高三位A10~A = 100,因此指令第一字节为91H,第二字节为8FH,构造的
目的地址PC加2后(PC) = 8102H,即: 1000000100000010 B (8102H)
指令提供的11位地址是10010001111B。替换PC的低11位后,PC的值即形成的目的地址是:
1000010010001111B (848FH)
即被调用子程序入口地址为848FH,或者说主程序到848FH处去调用子程序。
因为指令给出了子程序入口地址的低11位,因此本指令的子程序调用范围是2KB。例如本调用指令的地址为8100H,不变的高5位是10000B,因此本指令的子程序调用范围是8000H~87FFH。
综上所述,ACALL指令的操作内容可表示为:
PC ←(PC)+ 2 SP ←(SP)+ 1 ,(SP)←(PC)7~0 SP ←(SP)+ 1 ,(SP)←(PC)15~8 PC10~0 ← addr11 (2).长调用指令
LCALL addr 16 本指令是三字节指令,调用地址在指令中直接给出。 指令执行后,断点进栈保存,以
addr16作地址调用子程序,因此本指令的操作内容可表示为:
PC ←(PC)+ 3 SP ←(SP)+ 1 ,(SP)←(PC)7~0 SP ←(SP)+ 1 ,(SP)←(PC)15~8 PC10~0 ← addr16
长调用指令的子程序调用范围是64KB。Addr16就是被调用子程序的入口地址,使用比较方便,但三字节指令较长,占用存储空间较多。
例如(SP)= 60H,标号地址START为0100H,标号MIR为8100H,执行指令:
LCALL MIR START: 结果:(SP)= 62H,(61H)= 03H,(62H)= 01H,(PC)= 8100H
(3).返回指令
返回指令共有两条:
RET ;子程序返回指令
RETI ;中断服务子程序返回指令 子程序返回指令执行子程序返回功能,从堆栈中自动取出断点地址送给程序计数器PC,使程序在主程序断点处继续向下执行。因此本指令的操作内容可表示为:
PC15~8 ←(SP)– 1,SP ←(SP)–1 PC7~0 ←(SP)– 1,SP ←(SP)–1 例如(SP) = 62H,(62H) = 07H,(61H) = 30H, 执行指令: RET
结果(SP) = 60H,(PC) = 0730H,CPU从0730H开始执行程序。 中断服务子程序返回指令,除具有上述子程序返回指令所具有的全部功能之外,还有清除中断响应时被置位的优先级状态、开放较低级中断和恢复中断逻辑等功能。
4、空操作指令
NOP ;PC ←(PC)+ 1 空操作指令也算一条控制指令,即控制CPU不作任何操作,只消耗一个机器周期的时
间。空操作指令是单字节指令,因此执行后PC加l,时间延续一个机器周期。NOP指令常用于程序的等待或时间的延迟。 五、位操作类指令
我们在第一节讲过使用单片机可以把由模拟电路或数字电路实现的控制功能改由软件方法实现,使控制系统软化的微控制技术,在第二章又讲到位处理器的问题,这些内容都与位操作指令有关。