📄 clock.asm
字号:
; 程序说明
; 这是一个在ms-dos下在屏幕右上角显示时钟的程序。
; 程序实现了BISO功能调用读取实时时钟,并把程序
; 驻留内存,利用1CH中断实现电子钟计数。
; 本程序在masm 5.0下汇编通过,并且在ms-dos下
; 运行良好,实现了内存驻留,在dos做其他操作,
; 屏幕右上方始终显示一个绿色时间。
; 由于时间有限,不能改善程序,本想直接修改
; 显存来定位和显示时钟。
; 作者:
;
;
; 2007,11,7
code segment
assume ds:code,cs:code,es:code,ss:code
org 100h
main proc near
jmp init
timer dw 18 ;计数值,每18次为1秒钟
correct db 0 ; 修正值,每 5*18=90 次要修正一次timer
str db "00:00:00" ;时钟字符串
n1c:
;保护现场
PUSH ax
PUSH bx
PUSH cx
PUSH dx
PUSH si
PUSH di
PUSH bp
PUSH sp
PUSH es
PUSH ds
PUSH cs ;写数据段,使代码段和数据段一致
POP ds
STI ;关中断
DEC timer ; 1秒计数值-1
JZ time ; 十八次中断为一秒钟,转移到计数代码
JMP exit ;不足一秒退出中断
time:
MOV timer,18 ;重置计数值
INC str[7] ;秒钟的个位加 1
CMP str[7],'9' ;
JBE disp
MOV str[7],'0' ;个位清零
INC str[6] ;秒钟十位进位
CMP str[6],'6'
JB disp
MOV str[6],'0' ;
INC str[4] ;分钟的个位加 1
CMP str[4],'9'
JBE disp
MOV str[4],'0'
INC str[3] ;分钟十位进位
CMP str[3],'6'
JB disp
MOV str[3],'0'
INC str[1] ;时钟个位加 1
CMP str[1],'9'
JBE hour
MOV str[1],'0'
INC str[0] ;时钟十位进位
hour:
CMP str[0],'2'
JNE disp ;判断是否时钟十位为2
CMP str[1],'4' ;时钟十位为2,判断个位是否为4
JNE disp
MOV str[0],'0' ;24 小时,重新计数
MOV str[1],'0'
disp: ;显示时钟在屏幕右上角
; BIOS 13H 功能调用ES:BP=串地址CX=串长度,DH,DL=起始行列
;BH=页号,AL=1光标返回起始位置,BL=属性
MOV ax,cs
MOV es,ax ;把数据段(和代码段相同)放到es
MOV bp,offset str ;字符串偏移地址放到bp
MOV cx,8 ;字符串长度为8
MOV dh,0 ;第0行
MOV dl,71d ;第71列显示
MOV bl,0ah ;字符属性为绿色
MOV bh,0 ;在第0页上显示
MOV al,0 ;设置光标返回
MOV ah,13h ;调用BIOS 10H类型,13H功能中断显示字符串
INT 10h
INC correct ;修正值加1
CMP correct,5
JNE exit
INC timer ; 每5秒有5*18.2=91次中断,而现在才5*18=90次中断就电子钟有5秒
;所以快了一次中断时间,修正timer计数值,让它多计算一次中断
MOV correct,0
exit:
CLI ;开中断
;恢复现场
POP ds
POP es
POP sp
POP bp
POP di
POP si
POP dx
POP cx
POP bx
POP ax
IRET ;中断返回
init:
;int 27h 中断要求驻留内存的程序大小不能超过64k
;并且如果cs和ds不相同时,程序执行会失败
PUSH cs ;写数据段
POP ds
PUSH AX
PUSH CX
PUSH DX
MOV ah, 02h ;调用BIOS 功能读取实时时钟
INT 1ah ;CH 小时数(BCD码)
;MOV ax, 0eh ;CL 分钟数(BCD码)
;DH 秒数(BCD码)
MOV str[0],CH ;把实时时钟存到字符串
MOV str[1],CH
MOV str[3],CL
MOV str[4],CL
MOV str[6],DH
MOV str[7],DH
MOV CL,4 ;把时钟转化为ASCII码
SHR str[0],CL
ADD str[0],30H
AND str[1],0FH
ADD str[1],30H
SHR str[3],CL
ADD str[3],30H
AND str[4],0FH
ADD str[4],30H
SHR str[6],CL
ADD str[6],30H
AND str[7],0FH
ADD str[7],30H
POP DX
POP CX
POP AX
MOV dx,offset n1c ;中断程序入口地址
MOV ax,251ch ;写中断向量1CH
INT 21h
MOV ax,offset init ;
MOV dx,ax ;DX 为保持长驻程序最后一个字节
INT 27h ;程序驻留及退出
main endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -