📄 时钟程序.asm
字号:
.model small
.stack 100h
.data
enter db 0dh,0ah,'$';回车换行
;显示时间
sdate db 0,0,0,0,',',0,0,',',0,0,' $'
dlen db 0
stime db 0,0,':',0,0,':',0,0,' $'
tlen db 0
;菜单
alarm db 0
mu db '-------CLOCK MENU------- $'
mulen db 0
sd db 'a--set Date$'
sdlen db 0
st1 db 's--set Time$'
st1len db 0
qu db 'q--quit$'
qulen db 0
spac db ' '
splen db 79
;输入以及错误提示信息
strin db 'input a number$'
err db 'input Error$'
retry db 'input again?y/n$'
setd db '-----Setting Date-------$'
iny db 'Please Input a Number of Year.$'
inm db 'Please Input a Number of Month.$'
ind db 'Please Input a Number of Day.$'
surd db 'Are You Sure to Setting Date?y/n$'
ine db 'The Number You Input is not Suit for Data,Try again?y/n$'
sets db 'Setting Success!',0dh,0ah,'Press any Key to return.$'
sete db 'Setting Error.$'
rty db 'Retry?y/n$'
sett db '-----Setting Time-------$'
inh db 'Please Input a Number of Hour.$'
inf db 'Please Input a Number of Minute.$'
surt db 'Are You Sure to Setting Time?y/n$'
inet db 'The Number You Input is not Suit for Time,Try again?y/n$'
.code
;延时子程序
waitf proc
push cx
push ax
lop6: mov cx,7000;一次延时100ms
waitf_loop:
in al,61h
and al,10h
cmp al,ah
je waitf_loop
mov ah,al
loop waitf_loop
dec bx;延时次数放在bx中
jnz lop6
pop ax
pop cx
ret
waitf endp
;显示bx中数字的子程序
put_num proc
push ax
push cx
push dx
push si
mov ax,bx
mov cx,0
lop1: mov dx,0;取bx中各位数入栈
mov si,10
div si
add dx,30h
push dx
inc cx
cmp ax,0
jz op
jmp lop1
op: pop dx;显示,显示次数在cx中
mov ah,02h
int 21h
loop op
pop si
pop dx
pop cx
pop ax
ret
put_num endp
;将bx中的cl个数转成ascii码放到si指定的内存中
put_num2_cxsi proc
push ax
push dx
push bx
push di
mov ax,bx
mov ch,cl
lpp1: mov dx,0;除10入栈
mov di,10
div di
add dx,30h
push dx
dec cl
cmp cl,0
jnz lpp1
mov cl,ch
lpp2: pop dx;堆放到指定内存单元
mov [si],dl
inc si
dec cl
cmp cl,0
jnz lpp2
pop di
pop bx
pop dx
pop ax
ret
put_num2_cxsi endp
;显示字符串,参数是显示该字符串的偏移位置
show macro string,off
push ax
push dx
lea dx,string
add dx,off
mov ah,09h
int 21h
pop dx
pop ax
endm
;把cl个ascii码的字符转成数字放到bx中
in_num_cl proc
push ax
push dx
mov ch,cl
inp1: mov bx,0
show strin,0
show enter,0
inp2: mov ah,01h
int 21h
cmp al,30h;判断是否0-9
js inerr
cmp al,3ah
jns inerr
mov dh,0
mov dl,al
mov ax,bx;bx乘以10
shl ax,1
shl ax,1
shl ax,1
shl bx,1
add bx,ax
sub dl,30h
add bx,dx
dec cl
jnz inp2
jmp ine1
;出错处理
inerr: mov cl,ch
show enter,0
show err,0
show retry,0
show enter,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz inp1
cmp al,'Y'
jz inp1
ine1:
pop dx
pop ax
ret
in_num_cl endp
;把日期放入到指定的内存里
showdate proc
push ax
push bx
push cx
push dx
push di
push si
;取日期
mov ah,2ah
int 21h
;转成ascii码后放入内存
mov bx,cx
mov cl,4
lea si,sdate
call put_num2_cxsi;放年份
inc si
mov bh,0
mov bl,dh
mov cl,2
call put_num2_cxsi;放月份
inc si
mov bh,0
mov bl,dl
mov cl,2
call put_num2_cxsi;放日子
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
showdate endp
;把时间放到指定的内存空间
showtime proc
push ax
push bx
push cx
push dx
push si
push di
;取时间
mov ah,2ch
int 21h
;转成ascii码后放入内存
lea si,stime
push cx
mov bh,0
mov bl,ch
mov cl,2
call put_num2_cxsi;放小时
inc si
pop cx
mov bh,0
mov bl,cl
mov cl,2
call put_num2_cxsi;放分钟
inc si
mov bh,0
mov bl,dh
mov cl,2
call put_num2_cxsi;放秒
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
showtime endp
;显示主菜单
show_menu proc
push ax
push bx
push cx
push dx
push bp
;取当前光标信息
mov ah,01h
int 10h
;逐条显示菜单
mov bl,07h
mov ch,0
mov cl,mulen
mov dh,0
mov dl,0
lea bp,mu
mov al,01h
mov ah,13h
int 10h
mov cl,sdlen
inc dh
mov dl,0
lea bp,sd
mov al,01h
mov ah,13h
int 10h
inc dh
mov dl,0
mov cl,st1len
lea bp,st1
mov al,01h
mov ah,13h
int 10h
inc dh
mov dl,0
mov cl,qulen
lea bp,qu
mov al,01h
mov ah,13h
int 10h
pop bp
pop dx
pop cx
pop bx
pop ax
ret
show_menu endp
;显示日期和时间
show_dt proc
mov ah,01h
int 10h
mov bl,07h
mov ch,0
mov cl,dlen
mov dh,0
mov dl,80
sub dl,cl
lea bp,sdate
mov al,01h
mov ah,13h
int 10h
lea bp,stime
mov cl,tlen
mov dl,80
sub dl,cl
mov al,01h
mov ah,13h
int 10h
sdtr: ret
show_dt endp
;清行,行数放在si中
clear_scr_si proc
push ax
push bx
push cx
push dx
push bp
mov ah,01h
int 10h
mov dh,0
mov ch,0
mov bl,07h
lea bp,spac
lcp1:
mov dl,0
mov cl,splen
mov al,01h
mov ah,13h
int 10h
inc dh
dec si
jnz lcp1
pop bp
pop dx
pop cx
pop bx
pop ax
ret
clear_scr_si endp
;设置日期
setDate proc
push ax
push bx
push cx
push dx
;输入年
pre0: show setd,0
show enter,0
show iny,0
show enter,0
mov cl,4
call in_num_cl
show enter,0
push bx
;输入月
pre1: show inm,0
show enter,0
mov cl,2
call in_num_cl
show enter,0
cmp bx,13
js nex1
show ine,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz pre1
cmp al,'Y'
jz pre1
show sete,0
show enter,0
jmp sete1
nex1: push bx
;输入日
pre2: show ind,0
show enter,0
mov cl,2
call in_num_cl
show enter,0
cmp bx,31
js nex2
show ine,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz pre2
cmp al,'Y'
jz pre2
show sete,0
show enter,0
jmp sete2
nex2:
;设置输入的日期
mov dl,bl
pop bx
mov dh,bl
pop bx
mov cx,bx
show surd,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz set1
cmp al,'Y'
jz set1
show sete,0
show enter,0
jmp seend
set1: mov ah,2bh
int 21h
cmp al,0
jz suc1
show sete,0
show rty,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz pre0
cmp al,'Y'
jz pre0
jmp seend
suc1: show sets,0
mov ah,01h
int 21h
jmp seend
sete2: pop bx
sete1: pop bx
seend: pop dx
pop cx
pop bx
pop ax
ret
setDate endp
;设置时间
setTime proc
push ax
push bx
push cx
push dx
;输入小时
prt0: show sett,0
prt00: show enter,0
show inh,0
show enter,0
mov cl,2
call in_num_cl
show enter,0
cmp bx,24
js net0
show inet,0
mov ah,01h
int 21h
cmp al,'y'
jz prt00
cmp al,'Y'
jz prt00
show enter,0
show sete,0
jmp stend
net0: push bx
;输入分钟
prt1: show inf,0
show enter,0
mov cl,2
call in_num_cl
show enter,0
cmp bx,60
js net1
show inet,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz prt1
cmp al,'Y'
jz prt1
show sete,0
show enter,0
jmp stte1
net1:
;设置输入的时间
mov dx,0
mov cl,bl
pop bx
mov ch,bl
show surt,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz stt1
cmp al,'Y'
jz stt1
show sete,0
show enter,0
jmp stend
stt1: mov ah,2dh
int 21h
cmp al,0
jz sut1
show sete,0
show rty,0
mov ah,01h
int 21h
show enter,0
cmp al,'y'
jz prt0
cmp al,'Y'
jz prt0
jmp stend
sut1: show sets,0
mov ah,01h
int 21h
jmp stend
stte1: pop bx
stend: pop dx
pop cx
pop bx
pop ax
ret
setTime endp
;程序初始化子程序,计算各个字符串的长度
start_pro proc
push si
push di
lea si,sdate
lea di,dlen
lea cx,dlen
sub cx,si
dec cx
mov [di],cl
lea si,stime
lea di,tlen
lea cx,tlen
sub cx,si
dec cx
mov [di],cl
lea si,sd
lea di,sdlen
mov cx,di
sub cx,si
dec cx
mov [di],cl
lea si,st1
lea di,st1len
mov cx,di
sub cx,si
dec cx
mov [di],cl
lea si,qu
lea di,qulen
mov cx,di
sub cx,si
dec cx
mov [di],cl
lea si,mu
lea di,mulen
mov cx,di
sub cx,si
dec cx
mov [di],cl
pop di
pop si
ret
start_pro endp
;取得int 16h时所获得的字符
getchar proc
push ax
mov ah,01h
int 21h
pop ax
ret
getchar endp
START:
MOV AX,@DATA
MOV DS,AX
mov ax,ds
mov es,ax
call start_pro;初始化
mov si,30;清屏
call clear_scr_si
call show_menu;显示菜单
stee:
call showdate;更新时间日期
call showtime
call show_dt;显示时间日期
;判断键盘是否有字符读入
mov ah,01h
int 16h
jz last;没有就跳转到延时块
;根据按键跳转到相应的功能
cmp al,'a'
jz sa0
cmp al,'A'
jz sa0
cmp al,'s'
jz ss0
cmp al,'S'
jz ss0
cmp al,'q'
jz ep
cmp al,'Q'
jz ep
call getchar
call show_menu
jmp last
sa0: mov si,10;设置日期
call clear_scr_si
call getchar
call setDate
mov si,30
call clear_scr_si
call show_menu
jmp stee
ss0: mov si,10;设置时间
call clear_scr_si
call getchar
call setTime
mov si,30
call clear_scr_si
call show_menu
jmp stee
;延时
last: mov bx,5
call waitf
show enter,0
jmp stee
;结束程序
ep:
mov si,30
call clear_scr_si
MOV AH,4CH
INT 21H
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -