DATAS SEGMENT
sec db 24 ;倒数的秒数,可以随意更改
osec db 0
startmsg db "Counting down .... press [p] to puase, [c] to continue, [s] to stop",13,10,"$"
timesup db 13,10,"Times up!"
endmsg db 13,10,"Thanks for using, bye~$"
secStr db 6 dup ("$")
curpg db 0
ispause db 0
x db 0
y db 0
DATAS ENDS
STACKS SEGMENT
db 64 dup(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
push ax
push bx
push cx
push dx
MOV AX,DATAS
MOV DS,AX
lea dx,startmsg
call puts
;读取时间
mov ah,2ch
int 21h
mov osec,dh ;记下秒数
call getxy ;取得游标的位置
;倒数,显示倒数,查键盘。
;倒数的原理就是 osec 和现在秒数的对比得出
timer:
mov ah,2ch
int 21h
mov ah,6 ;检查键盘
mov dl,0ffh
int 21h
cmp al,"s" ;终止程式
jz done
cmp al,"p" ;暂停程式
jz pause
cmp al,"c" ;继续程式
jz continue
cmp ispause,0
jg timer
cmp osec,dh ;检查秒数的变化
jnz interval
jmp timer
interval:
mov osec,dh ;更新秒数
dec sec
call showcountdown ;显示倒数秒数(sec)
cmp sec,0
jg timer
lea dx,timesup
call puts
jmp done
pause:
mov ispause,1
jmp timer
continue:
mov ispause,0
jmp timer
puts:
mov ah,9
int 21h
ret
showcountdown:
call setxy ;保持显示倒数的位置
xor ax,ax
xor dx,dx
mov al,sec
cbw
mov bl,10
div bl
add al,"0"
add ah,"0"
lea bx,secStr
mov byte ptr[bx],al
mov byte ptr [bx+1],ah
mov dx,bx
call puts
ret
;读取游标的位置
getxy:
mov ah,3
int 10h
mov x,dl
mov y,dh
mov curpg,bh
ret
;设置游标的位置
setxy:
mov ah,2
mov bh,curpg
mov dl,x
mov dh,y
int 10h
ret
done:
pop dx
pop cx
pop bx
pop ax
MOV AH,4CH
INT 21H
CODES ENDS
END START