2. 双字节无符号数乘法
利用单字节乘法指令来扩展成多字节乘法运算,扩展时以字节为单位进行乘法运算。被乘数在R2、R3中,乘数在R4、R5中,乘积保存R0指向的20h~23h内存单元。运算法则见图2-3-2。
R2×R4R3×R5HR2×R5HR3×R4HR2×R5LR3×R4LR3R5R3×R5L+R2×R4H(R0-3)R2×R4L(R0-2)(R0-1)(R0)
图2-3-2 乘法运算法则
参考程序(A51\\2_3_2.ASM):
ORG 0000H LJMP MAIN ORG 0100H
MAIN: MOV R0,#23H ;运算结果低位地址 MOV A,R0 PUSH ACC CLR A MOV R7,#4
LP1: MOV @R0,A DEC R0 DJNZ R7,LP1 POP ACC MOV R0,A MOV A,R3 MOV B,R5 MUL AB MOV @R0,A MOV A,B DEC R0
MOV @R0,A ;保存运算的高8位 MOV A,R2 MOV B,R5 MUL AB ADD A,@R0 MOV @R0,A DEC R0 MOV A,B
;计算R2*R5
;此次运算低8位+R3*R5运算的高8位 ;计算R3*R5 ;计算的低8位保存
;运算结果存储单元清零
ADDC A,#00H MOV @R0,A INC R0 MOV A,R3 MOV B,R4 MUL AB ADD A,@R0 MOV @R0,A MOV A,B DEC R0 ADDC A,@R0 MOV @R0,A DEC R0 CLR A ADDC A,#00H MOV A,@R0 MOV A,R2 MOV B,R4 MUL AB INC R0 ADD A,@R0 MOV @R0,A MOV A,B DEC R0 ADDC A,@R0 MOV @R0,A NOP END
;R2*R5的高8位加进位位
;计算R3*R4
;计算R2*R4
;设置断点查看运算结果
SJMP MAIN ;如需进行下一次运算, 可修改R2 R3,R4 R5的值
实验步骤:
1) 编写程序,经编译、链接无误后装载到实验系统;
2) 设置被乘数R2, R3为03h, 50h、乘数R4, R5为04h, 60h; 3) 在SJMPMAIN语句行设置断点,然后运行程序; 4) 程序遇到断点后暂停,此时查看内存单元20h起始的内容,应为:00h、0Eh、7Eh、
00h;
5) 反复修改被乘数、乘数的值,验证程序的正确性。 3. 双字节除法
MCS-51指令系统中仅有单字节除法指令,若要扩展为双字节除法,可以采用“移位相减”的算法来实现。本例程的被除数在R7、R6中,除数在R5、R4中,将商存入R7、R6中,余数存入R3、R2中。程序流程图如图3-3-3所示。
参考程序(A51\\2_3_3.ASM):
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV A,R4
JNZ DDIV0 MOV A,R5 JZ ERROR
;除数为0,转ERROR
;执行程序前为R7R6(被除数), ;R5R4(除数)赋值
开始是除数=0?否;除数不为0,转DDIV0
余数寄存器R3 R2←0循环计数器R1←16DDIV0: MOV R2,#00H ;余数寄存器清零 MOV R3,#00H
MOV R1,#16 ;循环次数为16
DDIV1: CLR C;R3 R2 R7 R6左移1位 MOV A,R6 RLC A MOV R6,A MOV A,R7 RLC A MOV R7,A MOV A,R2 RLC A MOV R2,A MOV A,R3 RLC A MOV R3,A
MOV A,R2 ;部分余数减除数 SUBB A,R4 ;低8位相减 JC DDIV2 ;不够减, 转DDIV2 MOV R0,A ;暂存相减结果 MOV A,R3
SUBB A,R5 ;高8位相减 JC DDIV2 ;不够减, 转DDIV2 INC R6 ;够减, 则商为1 MOV R3,A ;相减结果送R3 R2中 MOV A,R0 MOV R2,A
DDIV2: DJNZ R1,DDIV1 ;16位未除完则继续 CLR F0 ;除数合法标志
SJMP MAIN ;设置断点观察结果, 可继续下一轮运算 ERROR: SETB F0 ;除数非法标志
SJMP MAIN ;设置断点观察结果, 可继续下一轮运算 END
余数、被除数左移1位←R3 R2 R7 R6置除数非法标志F0←1否部分余数≥除数?是商加1余数←余数-除数否R1-1=0?是置合法标志 F0←0结束图2-3-3 程序流程图实验步骤:
1) 编写程序,程序流程图如图2-3-3所示,经编译、链接无误后装载到实验系统; 2) 设置被除数R7, R6为46h,EEh、除数R5, R4为23h, 67h; 3) 在SJMPMAIN语句行设置断点,然后运行程序;
4) 程序遇到断点后暂停,此时查看寄存器R7, R6(商)与R3, R2(余数),应分别为
00h,02h与00h、20h;
5) 反复修改被除数、除数的值,验证程序的正确性。
四、实验心得
在这次实验中,我顺利运行了多字节的加法、双字节无符号乘法和双字节除法程序并得到了预期的结果,通过对程序进行分析,我对多字节数的运算在单片机内实现有了一个更深刻的认识,提高了对程序的分析理解能力。
实验四 查表程序设计实验
一、实验目的
学习查表程序的设计方法,熟悉MCS-51指令系统。
二、实验设备
PC计算机一台,Dais-52PRO+或Dais-PRO163C实验系统一套。
三、实验内容及步骤
1. 采用查表的方法将16进制数转换为ASCII码
根据ASCII码表可知,0~9的ASCII码为30h~39h,A~F的ASCII码为41h~46h,算法为(假定待转换的数存放在R7中):
当 R7≤9时,相应的ASCII码为:R7+30h;
当 R7>9时,相应的ASCII码为:R7+30h+07h。
参考程序(A51\\2_4_1.ASM):
ORG 0000H LJMP MAIN ORG 0100H
MAIN: MOV DPTR,#ASCII ;表格首地址送DPTR MOV A,R7 ;R7中为待转换的数 ANL A,#0FH ;取低4位 MOVC A,@A+DPTR ;查表
MOV R5,A ;低4位转换结果送R1 MOV A,R7
ANL A,#0F0H ;取待转换数的高4位 SWAP A ;高4位与低4位交换 MOVC A,@A+DPTR ;查表
MOV R6,A ;高4位转换结果送R2 SJMP MAIN ;设置断点观察结果 ASCII: DB \ END
实验步骤:
1) 编写程序,经编译、链接无误后装载到实验系统; 2) 设置待转换数据R7为8Ah;
3) 在SJMPMAIN语句行设置断点,然后运行程序; 4) 程序遇到断点后暂停,此时查看寄存器R6, R5的值,R6中为高4位转换结果38h,
R5中为低4位转换结果41h;
5) 反复修改R7的值,验证程序的正确性。