📄 clock.asm
字号:
.model small
.stack
.data
.code
.startup
h_m_s DB 8 DUP(':'),4 DUP(' ') ;存储时间
old1ch dw ?,? ;存储原中断向量1ch的内容
esccode db 0 ;用于保存Esc键的断开扫描码
MOV AX,0000H ;设置显示方式为40*25黑白文本方式
INT 10H
mov ax,3509h ;获取原中断向量09h的内容
int 21h
push es
push bx
cli ;关中断,以防止此时产生键盘中断
push ds
mov ax,2509h ;设计新中断向量09h内容
mov dx,seg quit
mov ds,dx
mov dx,offset quit
int 21h
pop ds
in al,21h ;读出IMR
push ax ;保存原IMR内容
and al,0fdh ;允许键盘中断(D1),其他不变
out 21h,al ;设置新IMR内容
mov byte ptr esccode,0 ;设置Esc键初值
MOV AX,351ch ;获取原中断向量1ch的内容
INT 21h
mov old1ch,es
mov old1ch+2,bx
PUSH DS
MOV AX,251ch ;设计新中断向量1ch内容
MOV DX,SEG clock
MOV DS,DX
MOV DX,OFFSET clock
INT 21h
POP DS
sti ;开中断
waite: cmp byte ptr esccode,81h ;循环等待按下并释放Esc键
jne waite ;中断服务程序设置esccode单元内容
PUSH DS
MOV AX,251ch ;恢复原中断向量1ch内容
MOV DX,old1ch
MOV DS,DX
MOV DX,old1ch+2
INT 21h
POP DS
cli ;关中断
pop ax
out 21h,al ;恢复原IMR内容
pop dx
pop ds
mov ax,2509 ;恢复原中断向量09h内容
int 21h
sti ;开中断
.exit 0
clock PROC ;显示系统时间的中断服务程序
STI
push si
push ax
push cx
push dx
MOV SI,0
MOV AH,2ch ;返回系统时间
INT 21h
MOV AL,CH
CALL bcdasc ;将时间数值(小时)转换成ASCII码字符
INC SI
MOV AL,CL
CALL bcdasc ;将时间数值(分)转换成ASCII码字符
INC SI
MOV AL,DH
CALL bcdasc ;将时间数值(秒)转换成ASCII码字符
CALL display ;直接写显存输出时间
pop si
pop ax
pop cx
pop dx
IRET
clock ENDP
bcdasc PROC ;将时间数值转换成ASCII码字符子程序
PUSH BX
CBW
MOV BL,10
DIV BL
ADD AL,30h
MOV h_m_s[SI],AL
INC SI
ADD AH,30h
MOV h_m_s[SI],AH
INC SI
POP BX
RET
bcdasc ENDP
display PROC ;直接写显存输出字符子程序
push ax
push es
push dx
push si
MOV AX,0b800h ;显存地址
MOV ES,AX ;es:di 指向显存地址
mov di,50*26h
mov si,0
disp: MOV AL,h_m_s[SI]
INC SI
CMP AL,' '
JZ disp0
CLD
STOSb ;将h_m_s[SI]指向的一个字节传送到es:di
inc di
JMP disp
disp0: pop ax
pop es
pop dx
pop si
RET
display ENDP
quit proc ;新的键盘中断服务程序
sti
push ax
in al,60h ;读取扫描码
mov esccode,al ;设置esccode单元为Esc键的扫描码
mov al,20h ;发送EOI命令
out 20h,al
pop ax
iret
quit endp
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -