MOV R1,#10
MOV SUM,#00H
MOV SUM+1, #00H LOOP:MOV A,@R0 INC R0 ADD A,SUM
DA A ;十进制调整 MOV SUM,A JNC NEXT
INC SUM+1
NEXT: DJNZ R1,LOOP SJMP $ END
3-25 若题3-24中改为对10个双字节十进制数(4个十进数)求和,结果仍存入以SUM开始的单元,低位先存。试编写相应的程序。
解:此题程序与上一题相似。只是多嵌套一次字节循环。若是十进制数的字节数再增加,也只需修改一下字节循环的次数(以下程序中R2的值)。程序如下:
SUM DATA 20H DATAD DATA 23H MOV R0,#DATAD CLR A
MOV SUM,A ;和单元清零
MOV SUM+1, A MOV SUM+2,A
MOV R3,#10 ;10个数 LOOP:MOV R1,#SUM
MOV R2,#2 ;2个字节 CLR C LOOP1:MOV A,@R0 ADDC A,@R1
DA A ;十进制调整 JNC R0
INC R1
DJNZ R2,LOOP1 JNC NEXT INC @R1
NEXT: DJNZ R3,LOOP SJMP $ END
3-26 编写一段程序,模拟如图3-1所示逻辑电路的逻辑功能。要求将4输入与非门的功能模拟先写成一个子程序,然后多次调用以得到整个的电路的功能模拟。设X,Y,Z和W都已定义为位地址,若程序中还需要其他位地址,也可以另行定义。
解:除了用伪指令BIT定义输入X,Y,Z,W和输出F之外,还定义F1和F2为两个中间结果。子程序中4个输入端定义为A1,A2,A3和A4。调用时,只需将相应的输入值存入这4个位地
址即可。程序如下:
X BIT 20.0H
Y BIT 20.1H Z BIT 20.2H W BIT 20.3H F BIT 20.4H A1 BIT 21.0H A2 BIT 21.1H A3 BIT 21.2H A4 BIT 21.3H F1 BIT 21.4H F2 BIT 21.5H
START: MOV C,X
MOV A1,C ;A1=Y MOV C,Y
MOV A2,C ;A2=Y MOV C,Z CPL C MOV A3,C ;A3=MOV C,W
MOV A4,C ;A4=W ACALL NAND
MOV F1,C ;F1=CPL A3 ;A3=Z SETB A4 ;A4=1 ACALL NAND MOV F2,C ;F2=CPL A2 ;A2=MOV C,W
MOV A3,C ;A3=2 ACALL NAND ;C=MOV A1,C MOV C,F1 MOV A2,C MOV C,F2 MOV A3,C ACALL NAND
MOV F,C ;F=
SJMP $ NAND:MOV C,A1 ANL C,A2 ANL C,A3 ANL C,A4 CPL C ;C= RET END
3-27 编写模拟与非门构成的
由P1.0和P1.1输入,输出Q和否则P1.4置0。
触发器的程序。设,
分别为P1.2和P1.3。若出现输出不定的情祝,则置位P1.4,
触发器的逻辑图如图3-2所示。
==0时输出不定。实际上,当
==0
=
解:根据一般书籍上的逻辑功能,都认为当时,输出Q和=0变为
都为1,并非不定,只是不符合输出应该互补的输出特征。只有当输入由
==1时,才真正出现输出状态的不确定,即不能确定是Q=1,=0还是Q=0,
=1。编程时要注意符合以上特点。假定模拟是连续的。程序如下:
LOOP: ORL P1,#03H ; P1.0,P1.1为输入状态
MOV A,P1 ;输入ANL A,#03H ;输出JZ IN00 ; MOV R2,A ;暂存 XRL A,#03H ;判断JZ IN11 ;
,
==0,转移
,是否都为1 ==1,转移
CLR P1.4 ;不定标志置0 MOV A,R2 ;恢复A值 RRC A ;取JNC IN01 ;
值到Cy =0,转移
SETB P1.2 ; =0,Q=1 CLR P1.3 ;
=0
SJMP LOOP ;转下一次读入
IN01: CLR P1.2 ;
SETB P1.3 ;
=0,Q=0 =1
SJMP LOOP ;转下一次读入
IN00: CLR P1.4 ;不定标志清0
SETB P1.2 ;
=0,=0,Q=1
SETB P1.3 ;也为1 SJMP LOOP
IN11: MOV A,P1
ANL A,#OCH ;取出Q,
=1
XRL A,#0CH ;判断是否Q=
JZ NEXT ;都为1,转移 SJMP LOOP ;不都为1,Q,
NEXT: SETB P1.4 ;置位不定标志 SJMP LOOP END
3-28 用查表法求1.0-9.9的平方值。原数存在DAT单元,高4位为整数部分,低4位为小数
不变
部分。查表结果存入RESU和RESU+1两个单元,RESU单元存整数部分,RESU + 1单元存小数部分。试编写有关程序。
解:1.0-9.9的平方数构成一张二维的表格,共有10行20列共200个元素。因为每个平方数都有整数和小数部分,分别应用两个单元(表中的两个相邻元素)来存放,整数先存。在查这种二维表时,要先经过简单计算得出查表的位置,然后再去查表,比查一维表要稍复杂一些。有关程序如下:
DAT DATA 20H RESU DATA 21H
MOV R0,#DAT ; 原数的地址存R0 CLR A
XCHD A,@R0 ; 取出小数部分 MOV R2,A ;R2存小数 MOV A,@R0 ;再取整数 SWAP A
ANL A,#0FH ;只要低4位整数 DEC A
MOV B,#20 ;每行20个元素 MUL AB MOV R3,A ;暂存 MOV A,R2 ;取出小数 RL A ;乘以2 ADD A,R3 ;求出查表位置 MOV R3,A ;暂存 MOV DPTR,#TAB ;表首地址 MOVC A,@A+DPTR ;查得整数部分 MOV RESU,A ;存入 MOV A,R3
INC A ;下一个查表位置 MOVC A,@A+DPTR MOV RESU+1,A SJMP $
TAB: DB 1,0,1,21,?,3,61 DB 4,0,4,41,?,8,41 DB 9,0,9,61,?,15,21 ?
DB 81,0,82,81,?,98,1 END
3-29 大学某班有学生NUM人,已经学过了COURSE门课程,有一个成绩单为NUM行,COURSE列。设每门课程都用一个序号来代表,如数学、物理、化学、?,其代号分别为0,1,2,?。编制一个程序可以累计任何一门课程的总成绩,被统计课程代号存放在寄存器R2中,统计结果存入寄存器R4和R5中。设学生数小于100,所以单科成绩总分小于10000。
解:这时,成绩单中的项数可以超过256,所以不能简单地设定DPTR为表格首地址,只改变A的数值,再用MOVC A,@A+DPTR指令来查表。因为A的值只能为0-255,需要根据R2中给定的科目代号以及学生的序号来算出查表的位置,然后迭加在表格首地址上,再来进行查表。当然,