📄 dianzibiao.asm
字号:
stack segment stack 'stack'
dw 32 dup(?)
stack ends
data segment
RE DB 'READY$'
COUNT DW 1091 ;每次中断55ms ,1091次达60m,计时停止
TENSEC DB '0' ;设置存储时间区
SECOND DB '0:'
MS3 DB '0'
MS2 DB '0'
MS1 DB '0',0DH
STORE DW 0,0
data ends
code segment
main proc far
assume cs:code,ds:data,ss:stack
push ds
mov ax,0
push ax
mov ES,AX
mov ax,data
mov ds,ax
MOV DI,OFFSET STORE ;保存系统时钟的中断服务程序
MOV AX,ES:20H ;入口地址
MOV [DI],AX
INC DI
INC DI
MOV AX,ES:22H
MOV [DI],AX
MOV BH,70H ;清屏,屏幕由0行0列至24行80列
MOV CH,0
MOV CL,0
MOV DH,24
MOV DL,80
MOV AL,0
MOV AH,7
INT 10H
MOV DL,20H ;中断程序入口地址送中断向量表
MOV AX,OFFSET TIME
MOV [DI],AX
INC DI
INC DI
MOV AX,CS
MOV [DI],AX
MOV DX,OFFSET RE ;显示READY,准备
MOV AH,9
INT 21H
DISPLAY: MOV BH,0 ;置光标位置于12行36列(显示器软中断调用)
MOV DH,12
MOV DL,36
MOV AH,2
INT 10H
MOV BL,7CH ;显示时间,秒设置为白底红字
MOV AL,TENSEC
MOV AH,14
INT 10H
MOV AL,SECOND
MOV AH,14
INT 10H
MOV BL,0FAH ;‘:’设置为白底红字闪烁
MOV AL,SECOND+1
MOV AH,14
INT 10H
MOV BL,7EH ;毫秒设置为白底黄字
MOV AL,MS3
MOV AH,14
INT 10H
MOV AL,MS2
MOV AH,14
INT 10H
MOV AL,MS1
MOV AH,14
INT 10H
LL:MOV AH,1 ;键盘I/O中断调用,检测有无键入
INT 16H
JZ LL ;无键入跳回等待,有键入则检测其功能
CMP AL,'S'
JZ START ;为S则跳转到START开始
CMP AL,'Z'
JZ ZERO ;为Z则跳转到ZERO清屏
CMP AL,'H'
JZ HALT ;为H则跳转到HALT暂停
CMP AL,'C'
JZ CONT ;为C则跳转到CONT继续
CMP AL,'E'
JZ EXIT ;为E则跳转到EIXT退出
MOV AL,TENSEC ;10秒位与6比较,未到60秒则返回显示
CMP AL,'6'
JNZ DISPLAY
MOV DI,20H ;恢复系统时钟的中断向量表
MOV AX,STORE
MOV [DI],AX
INC DI
INC DI
MOV AX,STORE+2
MOV [DI],AX
JMP EXIT
START: MOV AL,36H
OUT 43H,AL
MOV AL,0
OUT 40H,AL
OUT 40H,AL
ZERO: MOV TENSEC,'0' ;清零程序,寄存时间全变为0
MOV WORD PTR SECOND,'0:'
MOV MS3,'0'
MOV MS2,'0'
MOV MS1,'0'
MOV BH,0 ;显示00:000
MOV DH,12
MOV DL,36
MOV AH,2
INT 10H
MOV AH,9
MOV DX,OFFSET TENSEC
INT 21H ;转至暂停程序,等待新键入
HALT: MOV AL,50H ;8253选择计数器1,0方式,OUT1输出为低电平,计数暂停
OUT 43H,AL
JMP LL ;跳回,等待新键入
CONT: MOV AL,1 ;8253选择计数器1计数1次,完毕后OUT1输出高电平,继续
OUT 41H,AL
JMP DISPLAY ;跳回继续显示
EXIT: MOV AH,4CH
INT 21H
main endp
TIME PROC FAR ;中断程序
DEC COUNT ;软件计数器减1
JNZ MD ;到60秒,则调用报警程序
CALL BEEP
MD: ADD MS1,5 ;千位毫秒加5
CMP MS1,'9' ;大于9则MS2加1,MS1减10
JLE MD1
INC MS2
SUB MS1,10
MD1: ADD MS2,5 ;百位毫秒加5
CMP MS2,'9' ;大于9则MS3加1,MS2减10
JLE MD2
INC MS3
SUB MS2,10
MD2: CMP MS3,'9' ;大于9则SECOND加1,M3减10
JLE MD3
INC SECOND
SUB MS3,10
MD3: CMP SECOND,'9' ;大于9则TENSEC加1,SECOND减10
JLE MD4
INC TENSEC
SUB SECOND,10
MD4: MOV AL,20H ;中断结束命令
OUT 20H,AL
IRET
TIME ENDP
Beep proc ;报警程序
PUSHF ;保存所有的标志位
CLI ;关中断
MOV BL,20 ;蜂鸣常数,鸣叫10s
MOV AL,0B6H ;计数器2的控制字,工作在方式3
OUT 43H,AL
MOV AX,533H ;1000Hz分屏值,分高低字节两次送入
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H ;读取8255B端口的状态
MOV AH,AL
OR AL,3
OUT 61H,AL ;打开蜂鸣器
SUB CX,CX ;设置等待500ms的常数值
WAIT1: LOOP WAIT1 ;等待10s
DEC BL
JNZ WAIT1
MOV AL,AH ;恢复8255B端口的原来值,关蜂鸣器
OUT 61H,AL
RET
Beep endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -