CJNE A,direct,rel ;比较不相等转移
这几条基本指令可派生出很多条不同控制计数器的循环转移指令,大大扩充了应用范围 和多重循环层次。
循环嵌套就是在循环内套用循环的结构形式,也称“多重循环”。
循环的执行过程是从内向外逐层展开的。内层执行完全部循环后,外层则完成一次循环, 逐次类推。层次必须分明,层次之间不能有交叉,否则将产生错误。
编程时要注意循环的正确退出,要防止出现“死循环”。
【4-10】什么是子程序?它的结构特点是什么?什么是子程序嵌套?
【答】在编制应用程序时,往往将需要多次应用但完成的运算或操作相同的程序段,编制 成一个子程序,并尽量使其标准化,存放于某存储区域。调用子程序的程序称为“主程序”或 “调用程序”。
子程序是由专门的子程序调用指令CALL调用,而以子程序返回指令RET结束的程序 段。子程序的第一条指令地址,通常称为“子程序首地址”或“人口地址”,往往采用标号(可用助记符)加以表示,调用(转子)指令的下一条指令地址,通常称为“返回地址”或“断
很难找到
点”。
在子程序中调用子程序的现象通常称为子程序嵌套。
【4-11】手工汇编下列程序:
KEY EQU 2 0H
ORG 2000H
MOV RO,#30H ;数据区首址
MOV Rl,#1 6 ;数据区长度
MOV 20H,#KEY ;关键字送20H单元
CLR F0 ;清用户标志位
MOV 21H,#0l ;序号置l
LP: MOV A,@R0 ;取数
CJNE A,20H,LP1.
SJMP HERE ;找到关键字,结束.
LPI: INC 21H ;序号加1
INC R0 ;数据区地址指针加1
DJNZ R1,LP ;继续
SETB F0 ;未搜索到关键字,则置位用户标志
HERE:SJMP HERE
【答】根据指令查指令表得到机器码,手工汇编结果如下:
KEY EQU 20H
ORG 2000H
2000 7830 MOV R0,#30H ;数据区首址
2002 7910 MOV R1,#1 6 ;数据区长度
2004 752020 MOV 20H,#KEY ;关键字送20H单元
2007 C2D5 CLR F0 ;清用户标志位
2009 752101 MOV 21H,#01 ;序号置1
200C E6 LP: MOV A,@R0 ;取数
200D B52002 CJNE A,20H,LPI
2010 8007 SJMP HERE ;找到关键字,结束
2012 0521 LPI:INC 21H ;序号加1
2014 08 INC R0 ;数据区地址指针加1
2015 D9F5 DJNZ R1,LP ;继续
2017 D2D5 SETB F0 ;未搜索到关键字,则置位用户标志
2019 80FE HERE:SJMP HERE
【4-12]把长度为10 H的字符串从内部RAM的输入缓冲区INBUF向设在外部RAM的输出缓冲区OUTBUF进行传送,一直进行到遇见字符“CR"时停止。若字符串中无字符“CR”,则整个字符串全部传送。加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN: MOV R7,#10H ;数据长度
MOV R0,#INBUF ;源数据首地址
MOV DPTR,#OUTBUF ;目的数据首地址
很难找到
LOOP: MOV A,@R0 ;把源数据的值赋给A
CJNE A,#0DH,LOOPl ;判断是否为“CR”(ASCII码值为0DH)
SJMP ENDl ;是“CR",则结束传送
LOOPl: MOVX @DPTR,A ;把A的值赋给目的数据
INC R0 ;源数据下一个地址值
INC DPTR ;目的数据下一个地址值
DJNZ R7,L00P ;判断数据传送是否完毕
ENDI: SJMP ENDI
END
【4-13】内部RAM从2OH单元开始存放一个正数表,表中之数为无序排列,并以“-1”作为结束标志。编程实现在表中找出最小正数,存入10H。加上必要的伪指令,并对源程序加以注释。
【答】程序如下:
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN: MOV R0,#20H ;正数表首址
MOV 1 0H,#7FH ;初始值设为正数最大值
LOOP: MOV A,@R0
CJNE A,“-1’’,CHK ;比较结束标志“-1”
SJMP END1 ;是“-l",结束比较
CHK: CJNE A,10H,CHKI ;比较两个数大小
SJMP LOOP1 ;两个数相等,不交换
CHKI: JNC LOOP1 ;A较大,不交换
MOV 10H,A ;A较小,交换
LOOP1 INC R0
SJMP LOOP ‘
END1: SJMP END1
END
例如:已知(20H)=22 H,(21H)=23H,(22H)=0CH,(23H)=20H,(24H)=16H, (25H)=-1。 执行结果:(10H)=0CH
【4-14】比较两个ASCII码字符串是否相等。字符串的长度在内部RAM的2 H单元,第一个字符串的首地址在30H中,第二个字符串的首地址在50H中。如果两个字符串相等,则置用户标志FO为0;否则,置用户标志FO为1。加上必要的伪指令,并对源程序加以注释(每个ASCII码字符为一个字节,如ASCII码“A”表示为41H)。
LOOPl: MOVX @DPTR,A ;把A的值赋给目的数据
INC R0 ;源数据下一个地址值
INC DPTR ;目的数据下一个地址值
DJNZ R7,L00P ;判断数据传送是否完毕
ENDI: SJMP ENDI
END
【答】字符串中每一个字符都可以用一个ASCII码表示。只要有一个字符不相同,就可以判断字符串不相等。
ORG 0000H ’
很难找到
AJMP MAIN ·
ORG 0030H
MAIN: MOV R0,#30H 第一个字符串的首地址
MOV R1.,#5 0H 第二个字符串的首地址
LOOP: MOV A,@R0 第一个字符串的字符值赋给A
MOV B,@R1 ;第二个字符串的字符值赋给B
CJNE A,B,NEXT ;两个字符值比较
INC R0 字符值相等,则继续比较
INC R1.
DJNZ 20H,LOOP ;判断字符串是否比较完
CLR F0 字符串相等,则F0位清0
SJMP $
NEXT: SETB F0 字符串不等,则F0位置1