发信人: justice()
整理人: yangcs(2000-02-20 13:20:42), 站内信件
|
【 以下文字转载自 Windows 讨论区 】 【 原文由 Andy 所发表 】 想必用过WINDOWS3.X操作系统的朋友都知道(或用过)“附件”中“日历”应用 程序,该应用程序其中有一个非常实用的定时功能,即事先设定好时间,到时该 程序会给予提示。我用汇编语言编写了一个 DOS下的定时程序,此程序基本实现 了上述功能,相当于一个DOS下的隐形“小闹钟”。
设计思想:
此程序是一个部分内存驻留程序,运行时接受一个时间参数并保存起来,再 调用DOS功能调用2CH,从机器中读取机器时间,也保存起来,然后重编时钟中断 8H,系统每调用约1091次新时钟中断,使保存的机器时间增加1分(正常走时), 并与保存 的输入时间进行比较,若相等则用直接写屏的方法输出一个含有“It is the time!”信息的窗口,并且窗口的颜色在不断变化,此窗口信息持续显示 一分钟。
设计方法:
初始化部分:
⑴通过检查cs:[80]存放的值是否为零,来检查是否有参数,若为零则没有参 数,输出帮助信息退出。
⑵有参数,则检查是否为“?”,如参数为“?”则输出帮助信息。
⑶参数若不是“?”,检查是否为“q”,若是该参数,则检测该程序是否已 驻留,
若已驻留,则用DOS功能调用49H以释放内存,否则输出程序没有驻留的信息。
⑷不是q,通过子程序atom检测是否在0 ̄9之间,是转化为十进制数,存入t ime1中;用DOS功能调用2CH读机器时间,并存入time中;然后检测是否驻留(方 法略),没驻留过,驻留退出。
驻留部分:重编时钟中断new_int8,先调用原中断,然后调用设置时间和比 较程序段timer。
timer用变量tick1统计调用时钟中断8H次数,每1091次调用settime调整tim e的值,即增加1分钟;然后比较time和time1,相等调用display显示一个窗口给 予提示;display用直接写屏显示提示信息,程序的使用:
运行:DINGSHI/时:分 定时为几时几分,若正常驻留返回信息
The dingshi.com was installed.
若参数不是数字,则返回信息
The parameter is not correct!
若已驻留过,返回信息
The dingshi already had been installed!
DINGSHI/? 输出帮助信息
Syntax: dingshi/hh:mm or q
Example: dingshi/14:24 (install)
dingshi/q (removes from memory)
DINGSHI/q 若已驻留过,使之退出内存,返回信息
The dingshi.com removes from memory!
若没驻留过,返回信息
The dingshi.com do not in memory!
使用注意事项:
①本程序中的时间参数为24小时制。
②因本程序要读取机器时间,所以机器时间一定要正确,且应先设置时间, 再运
行此程序,否则本程序运行错误。
;****************************************
;此在DOS6.22下调试通过
;本程序通过以下编译转化成dingshi.com后使用
; masm dingshi
; link dingshi
; exe2bin dingshi.exe dingshi.com
;****************************************
cseg segment para public 'code'
assume cs:cseg,ds:cseg
org 100h
start: jmp initialize
old_int8 dd ? ;存放原时钟中断的地址
seg_graph equ 0b800h ;彩显段址(若为黑白改为0b000h)
bj dw 0 ;预设背景色
bj1 db 0
bj2 db 0
tick1 dw 0 ;此三变量分别统计中断次数
refresh dw 0
time db 2 dup(0) ;存放时间
time1 db 2 dup(0)
new_int8 proc far ;新时钟中断
sti
pushf
assume ds:nothing
call dword ptr cs:old_int8 ;先调用原时钟中断
call setdisp ;然后调用控制时间设置、显示定时信息子程序
iret
new_int8 endp
setdisp proc near ;控制时间设置、显示定时信息子程序
assume cs:cseg,ds:cseg
push ds
push bx
push ax
mov bx,cs
mov ds,bx
inc tick1
cmp tick1,1091 ;约为60*18.18
jl tdone
call setclock ;调用设置时间,增加1分
mov tick1,0
tdone: inc refresh ;统计中断次数
cmp refresh,5 ;中断五次检验一次是否到时
jl bdone
mov ax,word ptr cs:time
cmp word ptr cs:time1,ax
jne bdone
call disply ;显示到时信息
mov refresh,0 ;复0
bdone: pop ax
pop bx
pop ds
ret
setdisp endp
setclock proc near ;设置时间子程序
minet: cmp byte ptr time[1],59 ;判断分位是否为59
je tenthmin
inc byte ptr time[1] ;不是加1
jmp setdone
tenthmin:mov byte ptr time[1],0 ;分位复0
cmp byte ptr time[0],23 ;判断小时位是否为23
je nexthour
inc byte ptr time[0] ;不是加1
jmp setdone
nexthour:mov byte ptr time[0],0 ;小时位复0
setdone:ret
setclock endp
disply proc near ;直接写屏显示到时信息子程序
push ax
push di
push si
push es
push bx
push cx
mov ax,seg_graph
mov es,ax ;设置显示段址
mov di,1660 ;设置显示窗口偏移量
add bj,1000h ;下次调用背景增加
mov bx,word ptr bj
mov cx,5 ;总共五行
aaaa: push cx
mov cx,20 ;每行20个字符宽
bbbb: mov word ptr es:[di],bx
inc di
inc di
loop bbbb
add di,120
pop cx
loop aaaa
mov di,1986 ;直接写信息偏移量
lea si,msg
mov cx,13
cccc:
lodsb
stosb
inc di
loop cccc
pop cx
pop bx
pop es
pop si
pop di
pop ax
ret
disply endp
initialize: ;初始化程序
mov ax,cs
mov ds,ax
mov di,80h
cmp byte ptr cs:[di],0 ;查看命令行有无参数
mov dx,offset helpmsg
je ffff ;没有跳转按默认清屏
dddd: inc di
cmp byte ptr cs:[di],'/' ;查找参数引导符'/'
jne dddd
eeee: inc di
cmp byte ptr cs:[di],' ' ;检查是否要求帮助
je eeee
cmp byte ptr cs:[di],'?' ;检查是否要求帮助
jne gggg
mov dx,offset helpmsg ;输出帮助信息
ffff: jmp stop
gggg: cmp byte ptr cs:[di],'q' ;是否要退出
je mmmm
push di ;查找定时参数并设置
dec di
hhhh: inc di
inc bj1
cmp byte ptr cs:[di],':'
jne hhhh
cmp byte ptr bj1,2
mov bj1,0
jne kkkk
pop di
call atom
mov byte ptr time1[0],al
iiii: inc di
inc di
push di
dec di
jjjj: inc di
inc bj1
cmp byte ptr cs:[di],0dh
jne jjjj
mov byte ptr bj2,1
cmp byte ptr bj1,2
jne kkkk
pop di
call atom
mov byte ptr time1[1],al
jmp init1
kkkk: pop di
call atom
mov bl,10
mul bl
mov bl,al
inc di
call atom
add al,bl
cmp byte ptr bj2,1
je llll
mov byte ptr time1[0],al
jmp iiii
llll:
mov byte ptr time1[1],al
jmp init1
mmmm: mov al,08h
mov ah,35h
int 21h
cmp bx,0113h ;驻留过吗?(通过检查偏移量是否本程序的)
mov dx,offset msg5
jnz stop ;没有,转
push ds
mov ds,word ptr es:old_int8[2] ;把驻留前的中断段址:偏移是写回
mov dx,word ptr es:old_int8
mov ax,2508h
int 21h
push es
mov ax,es:[2ch]
mov es,ax
mov ah,49h ;释放环境变量区
int 21h
pop es
mov ah,49h ;释放程序区
int 21h
pop ds
mov dx,offset msg4
stop: mov ah,09h
int 21h
mov ah,4ch
int 21h
init1:
mov al,08h
mov ah,35h
int 21h
cmp bx,0113h
mov dx,offset msg1
je stop
mov word ptr old_int8,bx
mov word ptr old_int8[2],es
mov dx,offset new_int8
mov al,08h
mov ah,25h
int 21h
mov ah,2ch
int 21h ;取机器时间
mov byte ptr cs:time[0],ch ;保存时间
mov byte ptr cs:time[1],cl
mov al,dh
mov bl,18
mul bl
mov word ptr cs:tick1,ax ;秒数*18给tick1,微调
mov ah,9
mov dx,offset msg2 ;输出提示信息
int 21h
mov dx,offset initialize
mov ax,3100h
mov cl,4
shr dx,cl
inc dx
int 21h
atom proc near ;检测cs:[di]中的字符是否在0~9之间,并转化为十进制数
mov al,byte ptr cs:[di]
cmp al,30h
mov dx,offset msg6
jl stop
cmp al,39h
jg stop
sub al,30h
ret
atom endp
helpmsg db 10,13,'Syntax: dingshi/hh:mm or q'
db 10,13,'Example: dingshi/14:24 (install)'
db 10,13,' dingshi/q (removes from memory)',10,1 3,24h
msg db "It is a time!" ;到时时输出信息
msg1 db "The dingshi.com already has been installed!",13,10,24h
msg2 db "The dingshi.com was installed.",13,10,24h
msg4 db "The dingshi.com removes from memory!",13,10,24h
msg5 db "The dingshi.com do not in memory!",13,10,24h
msg6 db "The parameter is not correct!",13,10,24h
cseg ends
end start
-- 射门的感觉
——————————————————————————
| | | | | |
| | |----------| | |
| |------------------------------------| |
| |
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.102.157.66] -- ※ 转载:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]
|
|