51汇编第三章第四章部分题目的参考答案
更新时间:2024-06-09 19:52:01 阅读量: 综合文库 文档下载
- 51单片机汇编推荐度:
- 相关推荐
第三部分 MCS-51汇编语言程序设计
3-1 对下述程序进行人工汇编。
ORG 2000H
CLR C MOV R2,#3 LOOP: MOV A,@RO ADDC A,@R1 MOV @R0,A INC R0 INC R1
DJNZ R2,LOOP JNC NEXT MOV @RO,#01H SJMP $ NEXT: DEC R0
SJMP $
解:首先可查出各指令的机器码,确定每条指令的起始地址。然后,再计算出相对转移指令的偏移量。结果如下:
2000H:C3 CLR C 2001H:7A 03 MOV R2,#3 2003H:E6 LOOP: MOV A,@RO 2004H:37 ADDC A,@R1 2005H:F6 MOV @R0,A 2006H:08 INC R0 2007H:09 INC R1 2008H:DA F9 DJNZ R2,LOOP 200AH:50 04 JNC NEXT 200CH:76 01 MOV @RO,#01H 200EH:80 FE SJMP $ 2010H:18 NEXT: DEC R0 2011H:80 FE SJMP $
(1)设R0=20H,R1=25H。若(20H)=80H,(21H)=90H,(22H)=A0H,(25H)=A0H,(26H)=6FH,(27H)=30H,则程序执行后,结果如何?
解:此程序执行三次加法,被加数存在以20H为首地址的单元,加数则存在以25H为首地址的单元。每次相加的结果如下:
(20H)=(20H)+(25H)+Cy=80H+A0H+0 =20H,Cy=1 (21H)=(21H)+(26H)+Cy=90H+6FH+1 =00H,Cy=1 (22H)=(22H)+(27H)+Cy=A0H+30H+1=D1H,Cy=0
程序将两个三字节相加,执行结果存在22H, 21H和20H中,结果为D1 00 20H。 (2)若27H单元内容改为6FH,则结果有何不同? 解:此时,第三次相加的结果有变化:
(22H)=A0H+6FH+01H=0IH,Cy=1。
由于最后相加后Cy=1,所以还使得(23H) =01,R0指向23H。表示两个3字节数相加后,和为4字
节数。结果等于01010020H。
3-2 试用除法指令编程,将两个存于20H单元内的BCD数变成ASCII码后存入21H和22H单元。并计算程序所占用的内存字节数和所需的机器周期数。
解:将20H内两个BCD数送到A,再将A的内容除以16,就相当于把A的内容右移4位,结果使A中保留一个BCD数,B中存入另一个BCD数,并且都是在低4位。然后使高4位分别变为3,就可变成ASCII码。程序如下:
字节数 机器周期数 MOV A,20H 2 1 MOV B,#10H 3 2 DIV AB 1 4 ORL A,#30H 2 1 MOV 21H,A 2 1 ORL B,#30H 3 2 MOV 22H,B 3 2 SJMP $ END
所以,程序所占内存为16字节,执行程序需13个机器周期。最后一条短转移指令只用来表示程序结束,真正执行时又是一条无限循环语句。所以,一般不计算这条指令的字节数和机器周期数。
3-3 将20H单元内两个BCD数相乘,要求积亦应为BCD数,并把积存入21H单元。 解:MCS-51系统中有乘法指令,但所完成的是两个8位二进制数的相乘,也就是积不是BCD数。因此相乘以后还要进行二进制数—BCD数的转换。由于两个BCD数相乘,积不会超过100。因此只须将乘积除以10,其商就是积的十位数,余数就是积的个位数。程序如下: MOV A,20H ; 两个BCD数送A
MOV B,#16 ; 准备A内容右移4位 DIV AB ;两个BCD数分别存入A,B MUL AB ;两个BCD数相乘,积为二进制数 MOV B,#10 ;准备除以10
DIV AB ;A中为十位数,B中为个位数 SWAP A ;十位数移至高4位 ORL A,B ;并入个位数 MOV 21H,A ;存结果 SJMP $ END
此题也可以不用乘法指令,而通过加法来完成。这也是完成BCD数乘法的一般方法。每次相加以后,通过十进制调整指令把和变为BCD数。这样经过多次循环,就可以得到所求的积,并且已经变成为BCD数了。程序如下:
MOV A,20H ; 两个BCD数送A MOV B,#16 ; 准备将两个BCD数分开 DIV AB ;两个BCD数分别存入A,B JZ NEXT ;若A=0,积为0 MOV R0,0 ;R0中存乘数 MOV R1,B ;R1中存被乘数 CLR A
LOOP:ADD A,R1 ;做循环加法
DA A ;对部分积作十进制调整 DJNZ R0,LOOP
NEXT:MOV 21H,A ;存结果
SJMP $ END
若仅从这个题目而言,当然是第一种解法效率高,执行时间短。但第二种解法提供了完成BCD数乘法的一般思路。
3-4 求16位带符号二进制补码的绝对值。16位数放在NUM和NUM + 1单元。求出的绝对值亦放在原数的单元内,低位先存。
解:只需先取出16位补码数的高8位,判别其符号位以确定正负。若为正数,则绝对值就是原数。若为负数,则求补以后可得绝对值。当然,这里应该是对16位数求补。有关程序如下:
NUM DATA 21H
MOV R0,#NUM+1 ;取高8位地址 MOV A,@R0 ;取高8位到A
JNB ACC.7,NEXT ;若为正数,绝对值即原数 CPL A ;若为负数,高8位求反 MOV @R0, A ;存入原单元 DEC R0 ;地址指向NUM单元 MOV A,@R0 ;取出低8位数 CPL A ;低8位求反 ADD A,#01H ;加1 MOV @R0, A ;存入原单元
JNC NEXT ;低8位加1无进位,则结束 INC R0 ;指向高8位地址 INC @R0 ;高8位加1 END
NEXT: SJMP $
3-5 求16位补码数所对应的原码。16位补码存放在COMP和COMP + 1单元。转换后的原码亦存于这两个单元。低8位先存。
解:此题的解法与上一题相似。只是对负数补码求原码时,符号位应仍保持为1,而将其余各位求反加一。具体做法当然有很多种,以下程序中是用异或指令来实现的。另外,求反加1的实现方法也用了与上题略有不同的方法。程序如下:
COMP DATA 21H
MOV R0,#COMP+1 ;指向高8位地址 MOV A,@R0 ;取出高8位数
JNB ACC.7,NEXT ;正数不用变换
XRL A,#7FH ;符号位不变,其余各位求反 MOV @R0, A ;送回COMP+1单元 DEC R0 ;指向COMP单元 MOV A,@R0 ;取出低8位数 CPL A ;求反 ADD A,#01H ;加1
MOV @R0, A ;送回COMP单元
INC R0 ;指向高8位地址 CLR A
ADDC A,@R0 ;高8位加进位 MOV @R0,A ;送回COMP+1单元
NEXT: SJMP $
END
3 -6从20H单元开始存放一组带符号数,其数目已存在1FH单元。要求统计出其中大于0、等于0和小于0的数的数目,并将结果分别存入ONE,TWO,THREE三个单元。
解:这是一个多分支程序。利用累加器判零条件转移指令以及位地址内容判1条件转移指令,就可以完成>0,=0或<0的判别。再编程时要注意不同分支之间不要发生交叉。程序如下:
ONE DATA 1CH TWO DATA 1DH THREE DATA 1EH
MOV R0,#20H ;数据块首地址 MOV R1,1FH ;取数据块长度到R1 MOV A,R1
JZ FINISH ;长度为0则结束 CLR A
MOV ONE,A ;计数单元清0 MOV TWO,A MOV THREE,A
LOOP: MOV A,@R0 ;取数 INC R0 ;修改地址指针 JZ NEXT2 ;A=0,转向NEXT2 JB ACC.7,NEXT3 ; A<0,转向NEXT3 INC ONE ;A>0,ONE单元加1 SJMP NEXT1
NEXT3: INC THREE ; A<0,THREE单元加1 SJMP NEXT1
NEXT2: INC TWO ;A=0,TWO单元加1 NEXT1: DJNZ R1,LOOP ;长度减1不为0则返回 FINISH:SJMP $ END
也可以用三个工作寄存器(如用R2,R3,R4)作为计数单元存放并统计A>O,A=0,A<0的数目。最后待循环结束统计完成后,把结果送入ONE,TWO, THREE单元即可。这样虽然多用一些寄存器,但一般而言,执行程序的速度可加快。
3-7 在内部数据存贮器中的X和Y单元各有一个带符号数,要求按照以下条件来进行运算,结果送入Z单元。(注:0算正偶数。)
解:一个8位带符号数的正负和奇偶都可以通过位检测指令来实现:正负可通过检测符号位
D7来决定:0为正数,1为负数;奇偶可通过检测最低位D0来决定:0为偶数,1为奇数。程序如下:
X DATA 20H Y DATA 21H Z DATA 22H MOV A,X
JNB ACC.0,EVEN ;偶数转EVEN JB ACC.7,NEG1 ;负奇数转NEG1 ADD A,Y ;正奇数则X+Y SJMP NEXT
NEG1: ORL A,Y ;负奇数则X∨Y SJMP NEXT
EVEN: JB ACC.7,NEG2 ;负偶数转NEG2 ANL A,Y ;正偶数则X∧Y SJMP NEXT
NEG2: XRL A,Y ;负偶数则X⊕Y NEXT: MOV Z,A
SJMP $
END
上述程序中,判断的顺序(奇偶、正负)可以有多种,因此程序的操作顺序(加、与、或等)也要变化。
3-8 在128分支程序中是用AJMP指令实现分支转移的。若用长转移指令LJMP来代替AJMP指令,以便子程序入口地址可在64KB范围内安排。试修改原来的程序,使之能适应新的要求。修改后的程序最多能有几个分支?
解:由于LJMP指令是3字节指令,所以在转移到分支表之前要对分支号(存于R3中)做一次乘3的操作。而用AJMP指令时是先执行一次乘2的操作。修改后的程序如下: MOV A,R3
RL A ;A←A×2 ADD A,R3 ; A←3×R3 MOV DPTR,#BRTAB ;分支表首地址送DPTR JMP @A+DPTR ;第一次转移
BRTAB: LJMP ROUT00 ;转移到第一个分支入口 LJMP ROUT01 ;转移到第二个分支入口 ┆
这样修改以后,分支的数目将有所变化。由千A中是8位无符号数,最大值为255,除以3以后的整数值为:255/3 = 85。所以最多只能有85个分支。而分支入口可以在64 kB范围内安排。 3-9 如果在上题的情况下,85个分支入口不够用,仍要求有128个分支,则应如何修改程序?
解:为了实现128个分支,R3中存放的分支号为0-127。R3的值乘以3以后可以分为两种情况,当R3≤85时,乘以3以后不产生进位,而当R3>85时,乘以3以后就会产生进位。因此可以安排两个分支转移表,即分支0到分支85为一个分支表,分支86到分支127为一个表。分别有各自的入口地址BRTAB1和BRTAB2。按照R3×3以后是否有进位来转移到不同的分支表。还应该注意的是当R3>85以后,乘以3以后的值(不计进位)不是0,3,6,?,而是2,5,8,?,因此,还要做一些调整。修改以后的程序如下:
MOV A,R3
解:因为是求最小值,所以初始化时应将MINI单元送入8位最大值0FFH。然后与数据区中的数据逐一比较,选出最小值。程序如下:
MINI DATA 20H LEN DATA 21H BLOCK DATA 22H
MOV R0,#BLOCK ;R0为地址指针 MOV R1,LEN ;长度置R1
MOV MINI,#0FFH ;MINI单元先置最大值 MOV A,RI ;检测长度 JZ FINI ;为零则结束 LOOP:MOV A,@R0 ;取一个数 INC R0 ;修改指针 CJNE A,MINI,00H ;A与(MINI)比较 JNC NEXT ;A≥(MINI),不代换 MOV MINI,A ;A<(MINI),(MINI)←A NEXT: DJNZ R1,IOOP FINI: SJMP $ END
3-18 在内部RAM的BLOCK单元的数据块内存放着若干带符号数,数据块长度存于LEN单元。要求对数据块内的正数和负数分别相加,相加的结果分别存入SUM1和SUM2单元。设相加的结果不超过8位二进制数。
解:只需用位条件转移指令判别数的正负后,分别相加。加法可以直接在SUM1和SUM2单元上进行,也可以用两个工作寄存器作为工作单元来进行。两者只是相令字节数有点差别,执行时间没有多少差别。程序如下:
SUM1 DATA 20H SUM2 DATA 21H LEN DATA 22H BLOCK DATA 23H
MOV R0,#BLOCK ;R0为地址指针 MOV R1,LEN ;R1为长度 MOV SUM1,#00H ;正数和先清0 MOV SUM2,#00H ;负数和先清0 MOV A,R1 ;检测长度 JZ FINI ;为零则结束 LOOP: MOV A,@R0 ;取一个数
INC R0 ;修改指针 JB ACC.7,NEXT1 ;负数转NEXT1 ADD A,SUM1 ;正数求和 MOV SUM1,A ;存部分和 SJMP NEXT2
NEXT1: ADD A,SUM2 ;负数求和
MOV SUM2,A ;存部分和
NEXT2: DJNZ R1,LOOP FINI: SJMP $
END
3-19 在3-18中,若相加结果超过8位二进制数,程序又该如何编写?
解:设正数和存于SUM1和SUM1+1两个单元,负数和存于SUM2和SUM2+1两个单元,都是低8位先存。相加时也要按16位相加:加正数时,高8位为全0;加负数时,高8位为全1。加高8位时当然要用ADDC指令。程序如下:
SUM1 DATA 20H SUM2 DATA 22H LEN DATA 24H BLOCK DATA 25H
MOV R0,#BLOCK ;R0为地址指针 MOV R1,LEN ;R1为长度 CLR A
MOV SUM1,A ;各个和单元清0 MOV SUM1+1,A MOV SUM2,A MOV SUM2+1,A
MOV A,R1 ;检测长度 JZ FINI ;为零则结束 LOOP: MOV A,@R0 ;取一个数
INC R0 ;修改指针 JB ACC.7,NEXT1 ;负数转NEXT1 ADD A,SUM1 ;正数低8位求和 MOV SUM1,A CLR A ADDC A,SUM1+1 MOV SUM1+1,A SJMP NEXT2
NEXT1: ADD A,SUM2 ;负数低8位和
MOV SUM2,A MOV A,SUM2+1
ADDC A,#0FFH ;负数高8位和 MOV SUM2+1,A
NEXT2: DJNZ R1,LOOP FINI: SJMP $ END
3-20 有10组三字节的被加数和加数,分别存放于从FIRST和SECOND开始的区域中。求这10组数的和,并将和存入以SUM开始的单元,低位先存。设和仍为三字节。
解:10组数有10组和。这样也需要3个地址指针分别指向被加数、加数以及和,设分别用R0, R1和R2。但R2是不能用来寄存器间接寻址的。以下程序中采用R1和R2交换内容的方法来解决这个问题。这样做不需要占用其它内存单元,可节省资源。当然,程序的指令数有所增加。如果内存资源不太紧张,则不一定采用这个方法。程序如下:
FIRST DATA 20H SECOND DATA 40H SUM DATA 60H
MOV R0,#FIRST ;被加数地址指针 MOV R1,#SECOND ;加数地址指针 MOV R2,#SUM ;和地址指针 MOV R4,#10 ;10组数 LOOP:MOV R3,#3 ;每组3字节 CLR C
LOOP1:MOV A,@R0 ;取被加数 ADDC A,@R1 ;加一个字节 XCH A,R1 ;开始R1与R2交换 XCH A,R2
XCH A,R1 ;完成R1与R2交换 MOV @R1,A ;存部分和 XCH A,R1 ;R1与R2再次交换 XCH A,R2
XCH A,R1 ;完成交换
INC R0 INC R1 INC R2
DJNZ R3,LOOP1 ;组内循环 DJNZ R4,LOOP ;10组数循环 SJMP $ END
3-21 在3-20题中,将求10组数的和变为求10组数的总和,试编写有关程序。设总和亦为三字节数。
解:由于是求10组数的总和,所以加完一组数以后,还要与以前的结果求和。这样也需要3个地址指针。只是被加数和加数的指针是连续修改的,和的指针移动2次以后又回到原来的位里。程序如下:
SUM DATA 20H FIRST DATA 23H SECOND DATA 43H CLR A
MOV SUM,A ;和单元清0 MOV SUM+1,A MOV SUM+2,A
MOV R1,#FIRST ;被加数地址指针 MOV R2,#SECOND ;加数地址指针 MOV R3,#10 ;10组数 LOOP:MOV R0,#SUM ;和的指针
MOV R4,#3 ;3个字节
CLR C
LOOP1:MOV A,@R0 ;取部分和
ADDC A,@R1 ;加倍加数一个字节 MOV @R0,A ;送回 INC R0
INC R1
DJNZ R4,LOOP ;加3个字节 MOV R0,#SUM MOV R4,#3 CLR C
PUSH 01H ;保存R1的值 PUSH 02H
POP 01H ;R2的值送入R1
LOOP2: MOV A,@R0 ;取部分和
ADDC A,@R1 ;加加数一个字节 MOV @R0,A ;送回 INC R0 ;修改指针
INC R1
DJNZ R4,LOOP2 ;加3个字节 PUSH 01H ; R1的值入栈 POP 02H ;送回R2 POP 01H ;恢复R1
DJNZ R3,LOOP ;加10组数 SJMP $ END
3-22 在3-21题中,若和超过三个字节,应如何编写程序。
解:按题意,和单元需4个字节。加完3个字节后,取决于有无进位,安排第4个和单元是否进行加1操作。程序如下:
SUM DATA 20H FIRST DATA 24H SECOND DATA 44H CLR A
MOV SUM,A ;和单元清0 MOV SUM+1,A MOV SUM+2,A MOV SUM+3,A
MOV R1,#FIRST ;被加数地址指针 MOV R2,#SECOND ;加数地址指针 MOV R3,#10 ;10组数 LOOP:MOV R0,#SUM ;和的指针
MOV R4,#3 ;3个字节
CLR C
LOOP1:MOV A,@R0 ;取部分和
ADDC A,@R1 ;加被加数一个字节 MOV @R0,A ;送回 INC R0
INC R1
DJNZ R4,LOOP1 ;加3个字节 JNC NEXT1 ;无进位转NEXT1
INC SUM+3 ;有进位SUM+3单元加1
NEXT1: MOV R0,#SUM
MOV R4,#3 CLR C
PUSH 01H ; R1进栈 PUSH 02H ;R2进栈 POP 01H ;R2的值送入R1
LOOP2: MOV A,@R0 ;取部分和
ADDC A,@R1 ;加上加数一个字节 MOV @R0,A
INC R0 ;修改指针
INC R1
DJNZ R4,LOOP2 ;加3个字节 JNC NEXT2 ;无进位则转移 INC SUM+3 ;有进位SUM+3单元加1
NEXT2: PUSH 01H ; R1的值入栈,实际为R2值
POP 02H ;送回给R2 POP 01H ;恢复R1
DJNZ R3,LOOP ;加10组数 SJMP $ END
3-23 若累加器A中存放的是一个16进制数,将它转换为相应的ASCII码,并将结果存入RAM的20H单元。若A中不是16进制数,则将20H单元置为FFH。试编写有关程序。
解:用查表程序来完成此转换,编程最为简单。设A中存放的16进制数放在低4位。
CJNE A,#10H,00H
JNC NEXT1 ;A≥10H,不是16进制数 ADD A,#8 ;是16进制数,准备查表 MOVC A,@A+PC ;查表 SJMP NEXT2
NEXT1: MOV A,#0FFH NEXT2: MOV 20H,A
SJMP $
ASCTAB: DB ‘0,1,2,3,4’ DB ‘5,6,7,8,9’ DB ‘A,B,C,D,E,F’ END
3-24 在内部RAM的DATAD开始的区域存放有10个单字节十进制数(内含两位BCD数),试编一程序求其累加和,设和将超过2位BCD数,即可能为3位BCD数。结果存入SUM和SUM+1单元(低位先存)。
解:此题可直接进行十进制相加:执行加法指令以后作一次十进制调整。而百位数不需作十进制调整,因为总和不会大于990。程序如下:
SUM DATA 20H DATAD DATA 22H MOV R0,#DATAD
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中给定的科目代号以及学生的序号来算出查表的位置,然后迭加在表格首地址上,再来进行查表。当然,
因为没有16位加法指令,DPTR要分为高低两个8位来相加。程序中用R2存查表项的列号,R3存查表项得行号。程序如下:
TERM EQU 10 ;被统计课程代号 NUM EQU 50 COURDE EQU 15
MOV R2,#TERM ;R2存列号 CLR A
MOV R3,A ;R3存行号 MOV R4,A ;总成绩先为0 MOV R5,A
MOV R6, #NUM ;循环NUM次
LOOP: ACALL PICK ;调用查表子程序 CLR C
ADD A,R4 ;累加成绩低位 DA A MOV R4,A CLR A
ADDC A,R5 ;累加成绩高位 DA A MOV R5,A
INC R3 ;到下一行再查表
DJNZ R6,LOOP
SJMP $
PICK: MOV DPTR,#TAB ;表格首地址 MOV A,R3 MOV B,#COURSE MUL AB ADD A,DPL MOV DPL,A MOV A,B ADDC A,DPH MOV DPH
MOV A,R2 ;再加上列号 MOVC A,@A+DPTR ;查表 RET
3-30 编写16位无符号数除以8位无符号数的除法程序。被除数存于R1R0中,R1为高8位,除数存于R2中。运算后,商存于R0中,余数存于R1中。除数为0则置OVER单元为1。
解:按照题意,商为8位,故只需执行8次循环比较,也意味着被除数的高8位一定小于除数。然后就可以按照“左移相减”方法来进行比较。即将被除数左移一位以后,取出高9位来与除数相减(比较),若够减则商为1,并将差值(余数)代替被除数高8位。若不够减则商为0,被除数高8位不修改。然后左移一位进行下一次比较,直到得到8位商为止。程序如下:
OVER DATA 20H
MOV OVER,#00H ;复位溢出标志 MOV A,R2 ;取除数
JNZ START ;除数不为0则开始 MOV OVER,#01H ;置位溢出标志 SJMP $ ;结束 START:MOV R3,#08H ;8次循环 LOOP: CLR C
MOV A,R0 ;被除数低8位 RLC A MOV R0,A
MOV A,R1 ;被除数高8位
RLC A MOV R1 MOV F0 CLR C SUBB A JNC NEXT ; JNB F0NEXT1: MOV R1 INC R0NEXT: DJNZ R3 SJMP $ END
,A ,C
,R2 ;,NEXT
,A ;
,LOOP ; 与除数比较 大于等于除数转移 余数送回 不够8次,返回
正在阅读:
51汇编第三章第四章部分题目的参考答案06-09
2018-2019年初中物理北师大版《第十四章 电磁现象》《七、直流电03-09
你来比划我来猜题目06-09
【新版】人美版六年级美术下册《剪纸中的古老记忆》说课稿04-16
氯气的性质05-13
七年级英语下册专项练习之完成句子(一)05-11
交通灯附带原理图05-21
中外民营航空比较研究05-25
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 第四章
- 汇编
- 目的
- 答案
- 参考
- 第三章
- 部分
- 放射卫生现场检查笔录模板
- 全球气候变化下的中国应对策略
- 2windows部分
- 2018年在全县人力资源和社会保障工作会议上的讲话
- 学习科学与教育技术授课教案
- 高考必背古诗文理解性默写(64篇)
- 三自教育心得体会
- 《机电一体化系统》形成性作业(一
- 2018-2019-金工实习报告总结-推荐word版(3页)
- 用友PDM&U8整合应用方案(汽配行业版)
- 侵权责任法补充责任论文资料片段--昭月
- 第3课时 十加几、十几加几及相应减法
- 湖南关于推动产业技术创新战略联盟构建与发展的-湖南科技厅
- 林两传与康拜玉手法精髓
- 2011年第4季度高温浓烟演习战评总结
- 公共危机论文
- 过程装备与控制工程 陕西科技大学文件检索 模版 - 图文
- (仅供参考)数学组校本研修学分认定材料范例
- 医药厂家如何操作OTC市场终端
- 石化20万吨每年芳烃项目监理大纲 - 图文