单片机汇编之查找最大数

本题来自实验作业。此乃我写的源码,特在此分享。仅供参考,若有不足,不吝赐教!

;;;;本程序从键盘获取输入存入片内RAM 30H为首地址的单元,R7保存十六进制数个数,R0保存最大数
ORG 00H
LCALL GETKEY ;从键盘获取数据,十六进制格式为 2FH, 不支持0x2F, 和小写字母: feH FEh
LCALL MAX	;找出最大数
SJMP $

;;从片内RAM取数,并找出最大数
MAX:
MOV R1, #30H ;数据地址指针 
MOV R0, #0H ;存较大数
WHIL: ;取下一个数,比较大小
MOV A, @R1
CLR C
SUBB A, R0 
JC JUD ; c=1 是个较小数,跳过
MOV A, @R1	; 存较大数
MOV R0, A
JUD: ;判断是否还有数,有数就进入循环
INC R1
DJNZ R7, WHIL
MOV 40H, R0
RET

;;串口通信模式1初始化
initmod1: 
MOV TMOD, #20H ; 设置T1为模式2
MOV TL1, #0E8H ; 装入定时常数, 波特率1200bit/s
MOV TH1, #0E8H ; 自动重装
MOV SCON, #50H ;设置串行通信模式1 ,允许接收
SETB TR1 ; 启动T1
RET

;;;获取键盘输入,数据暂存50H, 再转换成数字存进30H
GETKEY:
LCALL String ;输出提示字符串
LCALL Input	 ;获取键盘输入的字符串
LCALL Hex
RET


;提示字符串:Enter a group hexadecimal numbers end with H:
MSG: DB 0x45,0x6e,0x74,0x65,0x72,0x20,0x61,0x20,0x67,0x72,0x6f,0x75,0x70,0x20,0x68,0x65,0x78,0x61,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x20,0x6e,0x75,0x6d,0x62,0x65,0x72,0x73,0x20,0x65,0x6e,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x48,0x3a,0x00

;;发送字符串
String:
LCALL initmod1 ;串口通信模式1初始化
MOV DPTR, #MSG ;取发送数据区首地址
Show:
CLR A 
MOVC A, @A+DPTR 
JZ Finish   ;检查字符是否为结束标志0H, A=0,则字符输出完成
MOV SBUF, A ;在UART窗口显示字符
CLR TI 
JNB TI, $ 
INC DPTR 
SJMP Show 
Finish:
CLR TR1 ;关闭定时器T1
RET

;;读取键盘输入字符串并存入以50H为首地址的单元
Input:
LCALL initmod1 ;串口通信模式1初始化
MOV R0, #50H   ;设接收数据的地址指针为R0
Read: ;从UART窗口读取数据并打印
CLR RI 
JNB RI, $ 
MOV A, SBUF 
CJNE A, #0DH, Continue ;检查回车字符0DH, 不是回车继续读取
SJMP ReadOver ;回车字符,结束读取
Continue: ;打印用户输入并保存
MOV SBUF, A   ;打印接收到的数据
CLR TI
JNB TI, $
CJNE A, #08H, Store ;检查退格字符\b, 不是退格,则保存数据
DEC R0        ;是退格,数据指针回退
SJMP Read
Store:
MOV @R0, A    ;保存数据
INC R0        ;后移数据指针
SJMP Read 	  ;循环读取
ReadOver: 	  ;读取结束,在字符串后加上结束符0H
MOV @R0, #00H
CLR TR1 	  ;关闭定时器
RET

;;将首地址为50H的单元中的字符串转化为十六进制数,存30H, 个数存R7
Hex:	;注意十六进制字母不支持小写
MOV R3, #30H 	;R3指向存放十六进制数的地址
MOV R1, #90H 	;R1指向存放中间结果的地址
MOV R2, #00H 	;R2存放中间结果的位数
MOV R0, #50H 	;R0指向数据源
MOV R7, #00H 	;R7存放最后结果个数
SJMP Wh 
While:
INC R0 			;有些分支直接跳转过来,R0还没加1,只好这样做了。
Wh:
MOV A, @R0
JZ TransOver ;A=0,为字符串结束标志
CLR C
SUBB A, #48H 	;检查是否为十六进制后缀H 48H
JZ Derive 		;A=0,跳转。将前面的数字合成一个数字
MOV A, @R0
CLR C
SUBB A, #30H 	;将字符转化为数字
JC While 		;C=1,A<30H。不是数字
CJNE A, #0AH, C1 ;大于等于10,C=0
C1:JC It 		;小于10, C=1,跳转,标号必须首字母大写
CLR C
SUBB A, #07H 	;大于10,再减7,可得字母对应的十六进制数字
CJNE A, #0AH, C2 ;与10比较
C2:JC While 	;结果小于10,不是十六进制字符
CJNE A, #10H, C3 ;与16比较
C3:JNC While 	;大于等于16,不是十六进制字符
It: 	;小于10大于0直接存数
MOV @R1, A 		;将转化后的数字存进中间结果单元
INC R1 			;前后移中间结果位置
INC R2 			;记录中间结果位数
SJMP While
Derive: 		;将中间结果合成为最后结果
MOV R1, #90H 	;将R1重新指向开始位置
CLR A
Der:
MOV B, #10H
MUL AB
ADD A, @R1
INC R1
DJNZ R2, Der
MOV 90H, A 		;先把结果存进90H
MOV A, R3 		;R3不能间址,只好借助其他寄存器
INC R3
INC R7
MOV R1, A
MOV @R1, 90H
MOV R1, #90H
SJMP While 
TransOver:
RET

END
上一篇:MS SQL server对象类型type


下一篇:c# – 为什么CLR不编译溢出const,但是对于变量它呢?