想做个电子钟附加倒计器的功能,可是输入倒计时时间后输出的是乱码,求高手指点迷津,感谢感谢!
时间:2011-01-16
来源:互联网
CLEAR_SCREEN MACRO OP1,OP2,OP3,OP4
PUSH AX ;入栈保护现场
PUSH BX
PUSH CX
PUSH DX
MOV AH,06H ;向上滚屏
MOV AL,00H ;全屏幕为空白
MOV BH,79H ;空白区域缺省属性
MOV CH,OP1 ;左上角行号
MOV CL,OP2 ;左上角列号
MOV DH,OP3 ;右下角行号
MOV DL,OP4 ;右下角列号
INT 10H ;BIOS 对屏幕及显示器中断调用
POP DX ;出栈显示数据
POP CX
POP BX
POP AX
ENDM
;******************************光标定位********************************************
CURSOR_POSITION MACRO ROW,CLM ; 设置光标位置宏定义
PUSH AX ;入栈保护现场
PUSH BX
PUSH CX
PUSH DX
MOV AH,2
MOV BH,0 ; 光标页号
MOV DH,ROW ; 光标行号
MOV DL,CLM ; 光标列号
INT 10H ; BIOS 对屏幕及显示器中断调用
MOV AH,1 ; 置光标类型,不显示光标
MOV CH,20H
INT 10H
POP DX ;出栈显示数据
POP CX
POP BX
POP AX
ENDM
;**********************************字符显示******************************************
SHOW MACRO B ;宏定义 显示寄存器中内容
LEA DX,B ;将b的首地址给DX
MOV AH,9 ;显示器I/O,多字符输出
INT 21H ;DOS中断调用
ENDM
;*******************************从键盘输入一个字符********************************************
INPUT MACRO
PUSH AX
MOV AH, 1
INT 21H
MOV BL, AL
POP AX
ENDM
;********************************读取键盘状态*********************************************
SCANKEY MACRO
PUSH AX
MOV AH, 01H
INT 16H
POP AX
ENDM
;**********************************读取键盘值**********************************************
INPKEY MACRO
PUSH AX
MOV AH, 00H
INT 16H
MOV BL, AL
POP AX
ENDM
;*******************************定义数据段***************************************************************
DATA SEGMENT
mess1 db ' Welcome You To Come Here! ','$',0ah,0dh
mess3 db 'The Date Time is now:',0ah,0dh,'$'
mess4 db 'The Time is:',0ah,0dh,'$'
mess5 db '00:00:00',0ah,0dh,'$'
D_BUF1 db 20 ;在数据段开辟一时间显示缓冲区
D_BUF2 db 20
T db 20
SECOND DB 0
COUNT1 DW 0 ;秒
COUNT2 DW 0 ;分
COUNT3 DW 0 ;时
DATEDIS DB ' 00 - 00 - 0000',0AH,'$' ;显示DATE
TIMEDIS DB ' 00 ',3AH,' 00 ',3AH,' 00 ',0AH,'$'
DATA ENDS
;***********************************定义堆栈段
STACK SEGMENT
db 100 dup(?)
STACK ENDS
;***********************************定义指令段
CODE SEGMENT
ASSUME cs:code,ss:stack,ds:data
START:
MOV AH,0 ;设置显示模式
MOV AL,3 ;文字 分辨率80*25 颜色16
INT 10H ;BIOS 对屏幕及显示器中断调用
CLEAR_SCREEN 00H,00H,50H,50H ;调用宏定义 设置区域
MOV AX,DATA ;数据段首地址给AX
MOV DS,AX ;数据段首地址给DS
MOV AX,STACK ;堆栈段首地址给AX
MOV SS,AX ;堆栈段首地址给SS
CURSOR_POSITION 1,1
SHOW mess1
LOOP1: CALL TIMEDISPLAY
SCANKEY
JE LOOP1
INPKEY
CMP BL, 44H
JE DATE
CMP BL, 48H
JE CHRO
CMP BL, 51H
JE QUIT
JMP LOOP1
QUIT: CURSOR_POSITION 15H,1H
MOV AH, 4CH
INT 21H
DATE: CALL DATEDISPLAY
CALL TIMEDISPLAY
SCANKEY
JE DATE
INPKEY
CMP BL, 4CH
JNE DATE
CLEAR_SCREEN 0FH,0FH,10H,37H
CURSOR_POSITION 0EH,15
JMP LOOP1
CHRO: CALL CHRONOGRAPH
CALL TIMEDISPLAY
SCANKEY
JE CHRO
INPKEY
CMP BL, 4CH
JNE CHRO
CLEAR_SCREEN 0FH,0FH,10H,37H
CURSOR_POSITION 0EH,15
JMP LOOP1
;***********************秒表子程序***************************
CHRONOGRAPH PROC NEAR
CHPH: CALL TIMEDISPLAY
SCANKEY
CALL DELAY_1
JE INTPUT
INPKEY
CMP BL, 53H
JE STAT
JMP INTPUT
INTPUT: CURSOR_POSITION 0AH, 1DH
LEA SI,T
INPUT ; 小时十位
MOV [SI], BL
;CALL TIMEDISPLAY
INC SI
INPUT ;小时个位
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT ;冒号
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
;CALL TIMEDISPLAY
INC SI
INPUT
MOV[SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
STAT: CALL TIMEDISPLAY
CALL TIME
SCANKEY
JE STAT
INPKEY
CMP BL, 50H
JE PAUSE
CMP BL, 54H
JE PAUSE
JMP STAT
PAUSE:CALL TIMEDISPLAY
SCANKEY
JE PAUSE
INPKEY
CMP BL, 47H
JE STAT
CMP BL, 43H
CALL TIMEDISPLAY
JMP PAUSE
CHRONOGRAPH ENDP
JMP LOOP1
;***********************时间显示子程序***********************
TIMEDISPLAY PROC NEAR ;定义时间显示子程序
MOV AH,2CH ;取当前系统时间
INT 21H ;
MOV BX,10 ;
LEA DI,TIMEDIS ;TIMEDIS的首地址给DI
MOV AL,CH ;小时传递给AL
XOR AH,AH ;AH清零
DIV BL ;小时的十位为AH,个位为AL
ADD AX,3030H ;转为ASCII码
MOV [DI+1],AX ;将小时存入[DI+1]
MOV AL,CL ;将分钟传递给AL
XOR AH,AH ;AH 清零
DIV BL ;分钟的高位为AH,低位为AL
ADD AX,3030H ;转为ASCII码
MOV [DI+6],AX ;将分钟存入[DI+6]
MOV AL,DH ;将秒传递给AL
XOR AH,AH ;AH清零
DIV BL ;秒的高位存入AH,低位存入AL
ADD AX,3030H ;转换ASCII码
MOV [DI+11],AX ;将秒存入 [DI+11]
CURSOR_POSITION 8,21H
SHOW TIMEDIS ;显示TIMEDIS中内容 系统时间
RET ;时间调用返回
TIMEDISPLAY ENDP
;************************延迟时间子程序****************************
DELAY PROC
PUSH CX
MOV CX, 0FFFH
NEXT_D: NOP
LOOP NEXT_D
POP CX
RET
DELAY ENDP
;*************************短延时*******************************************
DELAY_1 PROC
PUSH CX
MOV CX, 00FFH
NEXT_D1: NOP
LOOP NEXT_D1
POP CX
RET
DELAY_1 ENDP
;********************************日期显示子程序****************************
DATEDISPLAY PROC NEAR ;定义日期显示子程序
MOV AH,2AH ;取当前系统日期
INT 21H ;
MOV AX, CX ;送年份入AX(二进制数)
MOV BX, 10 ;(BX)=10
LEA SI, DATEDIS + 14 ;使SI指向年的最后一位
MOV CX, 4 ;(CX)=4
PUSH DX ;保存月日
TAB: XOR DX, DX ;DX清零
DIV BX ;(DX,AX)/BX,商送AX,余数送DX()
ADD DL, 30H ;余数与30H相加变为字符的ASCII码
MOV [SI], DL ;余数送入SI所指向的字节区
DEC SI ;SI减一
LOOP TAB ;循环 (将4个8字节的年份存入SI)
POP DX ;DX还原
MOV AL, DL ;日送AL
XOR AH, AH ;AH清零
DIV BL ;AX/BL,商送AH,余数送AL
ADD AX, 3030H ;转变为数字字符的ASCII码
SUB SI, 4 ;使SI指向日的第一位
MOV [SI], AX ;(AX)送SI所指向的字节区(将4位表示变为8位表示)
MOV AL, DH ;月送AL
XOR AH, AH ;AH清零
DIV BL ;AX/BL, 商送AH,余数送AL
ADD AX, 3030H ;转变为数字字符的ASCII码
SUB SI, 5 ;使SI指向月的第一位
MOV [SI], AX ;(AX)送SI所指向的字节区
CURSOR_POSITION 10H,28H
SHOW DATEDIS ;显示日期
CURSOR_POSITION 10H,10H
SHOW mess3
RET ;调用后返回
DATEDISPLAY ENDP
;*********************将2进制数转换成10进制数********************
CHANGE PROC NEAR
MOV CX,10D ;显示十位
CALL DECDIV
MOV CX,1 ;显示个位
CALL DECDIV
RET
CHANGE ENDP
DECDIV PROC NEAR ;转化成字符显示
MOV DX,0
DIV CX
MOV BX,0
ADD AL,30H ;转换成ASCII
MOV AH,0EH
INT 10H ;显示一个字符
MOV AX,DX
RET
DECDIV ENDP
;***********时间*************************
TIME PROC
PUSH AX
PUSH DX
MAIN:
MOV AH, 2
INT 1AH
CMP DH, SECOND
JNE GET
JMP NEXT
GET: MOV SECOND, DH
MOV AL, [SI]
DEC SI
MOV AH, [SI]
DEC SI
MOV COUNT1, AX
DEC SI
MOV BL, [SI]
DEC SI
MOV BH, [SI]
DEC SI
MOV COUNT2, BX
DEC SI
MOV CL, [SI]
DEC SI
MOV CH, [SI]
MOV COUNT3, CX
MOV DX, COUNT1
CMP DX, 0H
JNE C
CMP COUNT2, 0H
JNE A
CMP COUNT3, 0H
JNE B
JMP NEXT
C:DEC COUNE1
JMP NEXT4
A:DEC COUNT2
MOV COUNT1,32H
JMP NEXT4
B:DEC COUNT3
MOV COUNT2,32H
JMP NEXT4
NEXT4: CURSOR_POSITION 10H,28H
MOV AX,COUNT1
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
CURSOR_POSITION 10H, 2BH
MOV AX, COUNT2
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
CURSOR_POSITION 10H, 2EH
MOV AX,COUNT3
CALL CHANGE
NEXT: POP DX
POP AX
RET
TIME ENDP
CODE ENDS
END START
PUSH AX ;入栈保护现场
PUSH BX
PUSH CX
PUSH DX
MOV AH,06H ;向上滚屏
MOV AL,00H ;全屏幕为空白
MOV BH,79H ;空白区域缺省属性
MOV CH,OP1 ;左上角行号
MOV CL,OP2 ;左上角列号
MOV DH,OP3 ;右下角行号
MOV DL,OP4 ;右下角列号
INT 10H ;BIOS 对屏幕及显示器中断调用
POP DX ;出栈显示数据
POP CX
POP BX
POP AX
ENDM
;******************************光标定位********************************************
CURSOR_POSITION MACRO ROW,CLM ; 设置光标位置宏定义
PUSH AX ;入栈保护现场
PUSH BX
PUSH CX
PUSH DX
MOV AH,2
MOV BH,0 ; 光标页号
MOV DH,ROW ; 光标行号
MOV DL,CLM ; 光标列号
INT 10H ; BIOS 对屏幕及显示器中断调用
MOV AH,1 ; 置光标类型,不显示光标
MOV CH,20H
INT 10H
POP DX ;出栈显示数据
POP CX
POP BX
POP AX
ENDM
;**********************************字符显示******************************************
SHOW MACRO B ;宏定义 显示寄存器中内容
LEA DX,B ;将b的首地址给DX
MOV AH,9 ;显示器I/O,多字符输出
INT 21H ;DOS中断调用
ENDM
;*******************************从键盘输入一个字符********************************************
INPUT MACRO
PUSH AX
MOV AH, 1
INT 21H
MOV BL, AL
POP AX
ENDM
;********************************读取键盘状态*********************************************
SCANKEY MACRO
PUSH AX
MOV AH, 01H
INT 16H
POP AX
ENDM
;**********************************读取键盘值**********************************************
INPKEY MACRO
PUSH AX
MOV AH, 00H
INT 16H
MOV BL, AL
POP AX
ENDM
;*******************************定义数据段***************************************************************
DATA SEGMENT
mess1 db ' Welcome You To Come Here! ','$',0ah,0dh
mess3 db 'The Date Time is now:',0ah,0dh,'$'
mess4 db 'The Time is:',0ah,0dh,'$'
mess5 db '00:00:00',0ah,0dh,'$'
D_BUF1 db 20 ;在数据段开辟一时间显示缓冲区
D_BUF2 db 20
T db 20
SECOND DB 0
COUNT1 DW 0 ;秒
COUNT2 DW 0 ;分
COUNT3 DW 0 ;时
DATEDIS DB ' 00 - 00 - 0000',0AH,'$' ;显示DATE
TIMEDIS DB ' 00 ',3AH,' 00 ',3AH,' 00 ',0AH,'$'
DATA ENDS
;***********************************定义堆栈段
STACK SEGMENT
db 100 dup(?)
STACK ENDS
;***********************************定义指令段
CODE SEGMENT
ASSUME cs:code,ss:stack,ds:data
START:
MOV AH,0 ;设置显示模式
MOV AL,3 ;文字 分辨率80*25 颜色16
INT 10H ;BIOS 对屏幕及显示器中断调用
CLEAR_SCREEN 00H,00H,50H,50H ;调用宏定义 设置区域
MOV AX,DATA ;数据段首地址给AX
MOV DS,AX ;数据段首地址给DS
MOV AX,STACK ;堆栈段首地址给AX
MOV SS,AX ;堆栈段首地址给SS
CURSOR_POSITION 1,1
SHOW mess1
LOOP1: CALL TIMEDISPLAY
SCANKEY
JE LOOP1
INPKEY
CMP BL, 44H
JE DATE
CMP BL, 48H
JE CHRO
CMP BL, 51H
JE QUIT
JMP LOOP1
QUIT: CURSOR_POSITION 15H,1H
MOV AH, 4CH
INT 21H
DATE: CALL DATEDISPLAY
CALL TIMEDISPLAY
SCANKEY
JE DATE
INPKEY
CMP BL, 4CH
JNE DATE
CLEAR_SCREEN 0FH,0FH,10H,37H
CURSOR_POSITION 0EH,15
JMP LOOP1
CHRO: CALL CHRONOGRAPH
CALL TIMEDISPLAY
SCANKEY
JE CHRO
INPKEY
CMP BL, 4CH
JNE CHRO
CLEAR_SCREEN 0FH,0FH,10H,37H
CURSOR_POSITION 0EH,15
JMP LOOP1
;***********************秒表子程序***************************
CHRONOGRAPH PROC NEAR
CHPH: CALL TIMEDISPLAY
SCANKEY
CALL DELAY_1
JE INTPUT
INPKEY
CMP BL, 53H
JE STAT
JMP INTPUT
INTPUT: CURSOR_POSITION 0AH, 1DH
LEA SI,T
INPUT ; 小时十位
MOV [SI], BL
;CALL TIMEDISPLAY
INC SI
INPUT ;小时个位
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT ;冒号
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
;CALL TIMEDISPLAY
INC SI
INPUT
MOV[SI], BL
; CALL TIMEDISPLAY
INC SI
INPUT
MOV [SI], BL
; CALL TIMEDISPLAY
STAT: CALL TIMEDISPLAY
CALL TIME
SCANKEY
JE STAT
INPKEY
CMP BL, 50H
JE PAUSE
CMP BL, 54H
JE PAUSE
JMP STAT
PAUSE:CALL TIMEDISPLAY
SCANKEY
JE PAUSE
INPKEY
CMP BL, 47H
JE STAT
CMP BL, 43H
CALL TIMEDISPLAY
JMP PAUSE
CHRONOGRAPH ENDP
JMP LOOP1
;***********************时间显示子程序***********************
TIMEDISPLAY PROC NEAR ;定义时间显示子程序
MOV AH,2CH ;取当前系统时间
INT 21H ;
MOV BX,10 ;
LEA DI,TIMEDIS ;TIMEDIS的首地址给DI
MOV AL,CH ;小时传递给AL
XOR AH,AH ;AH清零
DIV BL ;小时的十位为AH,个位为AL
ADD AX,3030H ;转为ASCII码
MOV [DI+1],AX ;将小时存入[DI+1]
MOV AL,CL ;将分钟传递给AL
XOR AH,AH ;AH 清零
DIV BL ;分钟的高位为AH,低位为AL
ADD AX,3030H ;转为ASCII码
MOV [DI+6],AX ;将分钟存入[DI+6]
MOV AL,DH ;将秒传递给AL
XOR AH,AH ;AH清零
DIV BL ;秒的高位存入AH,低位存入AL
ADD AX,3030H ;转换ASCII码
MOV [DI+11],AX ;将秒存入 [DI+11]
CURSOR_POSITION 8,21H
SHOW TIMEDIS ;显示TIMEDIS中内容 系统时间
RET ;时间调用返回
TIMEDISPLAY ENDP
;************************延迟时间子程序****************************
DELAY PROC
PUSH CX
MOV CX, 0FFFH
NEXT_D: NOP
LOOP NEXT_D
POP CX
RET
DELAY ENDP
;*************************短延时*******************************************
DELAY_1 PROC
PUSH CX
MOV CX, 00FFH
NEXT_D1: NOP
LOOP NEXT_D1
POP CX
RET
DELAY_1 ENDP
;********************************日期显示子程序****************************
DATEDISPLAY PROC NEAR ;定义日期显示子程序
MOV AH,2AH ;取当前系统日期
INT 21H ;
MOV AX, CX ;送年份入AX(二进制数)
MOV BX, 10 ;(BX)=10
LEA SI, DATEDIS + 14 ;使SI指向年的最后一位
MOV CX, 4 ;(CX)=4
PUSH DX ;保存月日
TAB: XOR DX, DX ;DX清零
DIV BX ;(DX,AX)/BX,商送AX,余数送DX()
ADD DL, 30H ;余数与30H相加变为字符的ASCII码
MOV [SI], DL ;余数送入SI所指向的字节区
DEC SI ;SI减一
LOOP TAB ;循环 (将4个8字节的年份存入SI)
POP DX ;DX还原
MOV AL, DL ;日送AL
XOR AH, AH ;AH清零
DIV BL ;AX/BL,商送AH,余数送AL
ADD AX, 3030H ;转变为数字字符的ASCII码
SUB SI, 4 ;使SI指向日的第一位
MOV [SI], AX ;(AX)送SI所指向的字节区(将4位表示变为8位表示)
MOV AL, DH ;月送AL
XOR AH, AH ;AH清零
DIV BL ;AX/BL, 商送AH,余数送AL
ADD AX, 3030H ;转变为数字字符的ASCII码
SUB SI, 5 ;使SI指向月的第一位
MOV [SI], AX ;(AX)送SI所指向的字节区
CURSOR_POSITION 10H,28H
SHOW DATEDIS ;显示日期
CURSOR_POSITION 10H,10H
SHOW mess3
RET ;调用后返回
DATEDISPLAY ENDP
;*********************将2进制数转换成10进制数********************
CHANGE PROC NEAR
MOV CX,10D ;显示十位
CALL DECDIV
MOV CX,1 ;显示个位
CALL DECDIV
RET
CHANGE ENDP
DECDIV PROC NEAR ;转化成字符显示
MOV DX,0
DIV CX
MOV BX,0
ADD AL,30H ;转换成ASCII
MOV AH,0EH
INT 10H ;显示一个字符
MOV AX,DX
RET
DECDIV ENDP
;***********时间*************************
TIME PROC
PUSH AX
PUSH DX
MAIN:
MOV AH, 2
INT 1AH
CMP DH, SECOND
JNE GET
JMP NEXT
GET: MOV SECOND, DH
MOV AL, [SI]
DEC SI
MOV AH, [SI]
DEC SI
MOV COUNT1, AX
DEC SI
MOV BL, [SI]
DEC SI
MOV BH, [SI]
DEC SI
MOV COUNT2, BX
DEC SI
MOV CL, [SI]
DEC SI
MOV CH, [SI]
MOV COUNT3, CX
MOV DX, COUNT1
CMP DX, 0H
JNE C
CMP COUNT2, 0H
JNE A
CMP COUNT3, 0H
JNE B
JMP NEXT
C:DEC COUNE1
JMP NEXT4
A:DEC COUNT2
MOV COUNT1,32H
JMP NEXT4
B:DEC COUNT3
MOV COUNT2,32H
JMP NEXT4
NEXT4: CURSOR_POSITION 10H,28H
MOV AX,COUNT1
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
CURSOR_POSITION 10H, 2BH
MOV AX, COUNT2
CALL CHANGE
MOV AH, 2
MOV DL, ':'
INT 21H
CURSOR_POSITION 10H, 2EH
MOV AX,COUNT3
CALL CHANGE
NEXT: POP DX
POP AX
RET
TIME ENDP
CODE ENDS
END START
作者: xuyayayaya 发布时间: 2011-01-16
单独调试一下显示子程序呢?
作者: masmaster 发布时间: 2011-01-16
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28