10 Star 22 Fork 9

吴烜/asm_for_all

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Little_clock.asm 12.39 KB
一键复制 编辑 原始数据 按行查看 历史
ZandraWoo 提交于 10年前 . Update Little_clock.asm
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;程序名称:clock.asm
;功能:常驻计时器/闹钟
;环境:16BIT DOS实模式
;编译器:MASM 5.1-6X
;用法:看说明
;返回值:没有
;破坏寄存器:不适用
;
;
;这是吧上某人的功课吧
;这题目有普遍性,涉及的问题较多,所以独立发一帖,希望多些人看到.
;
;参照 “定时响铃”的例子及其它MASM程序的例子,实现 INT 1C
;MYINT1C 实现的功能在屏幕的右上角显示秒表或时钟,按ESC,
;退出程序。
;说明:
;1.实现基本的秒表功能,即参照8.5范例给出的响铃程序改写,
;实现简单的计时和暂停、中止等功能;
;2.时钟复杂一些,按照书后BIOS/DOS中断附表实现从系
;统取时间,并能够对其进行设置和相应的计时功能。
;
;解题
;DOS的常驻,时钟比较简单,基本上拦截1CH,抓取系统时间,
;找个地方显示一下就完事了,至于计时,方法也有许多,1CH
;本身就是每1/18.2秒运行一次,所以同时也有计时功能.
;常驻的方法用DOS的21H,AH=31H或者INT27也可以.
;这个小小CLOCK程式的计时和读时间不用任何中断int21h,ah=2ch
;或int 1Ah,而是直接读取40:6C - 40:6D的系统累加时间,这相容度好像
;还大,测试在windows/dos 和dosbox都能正常运行
;编译:因为程式是com,masm 5.x 须要exe2bin 转成com> exe2bin clock.exe clock.com
;masm 6.x的话加 ml /AT 的设定可直接转成com
;
;用法:
;clock ;在右上角显示时间
;clock u ; 移除常驻
;clock s mm:ss
;mm是分钟,ss是秒
;键入clock s 3:10  
;右上角显示倒数计时3:10 ..3:09...3:08 直到00:00时显示3秒红色 -alarm-文字
;然后回到正常系统时间
;若键入 clock s 10,程式会视为倒数10分钟,若只要倒数秒
;可键入 clock s 0:10 ;则数10秒
;
;若clock已经常驻,也可以键入clock s mm:ss 去设定新的倒数
;代码有简单的英文注解(要交功课的同学请自行添加/翻译注解)
;
;
;
.286
remove_ax equ 0AA01h
ask_ax equ 0AA02h
alarm_set_ask equ 0AA03h
exist_flag equ 0AAFFh
time_att equ 70h
alarm_att equ 0cfh
alarm_time equ 18*3 ; ? alarm seconds
cseg segment
assume cs:cseg
org 100h
begin: jmp init
;sign: db 'WooWoo'
old_off dw 0
old_seg dw 0
delay_count dw 0
time_up db 0
work_flag db 0
alarm_flag db 0
alarm_count dw alarm_time
;------------- tsr start ------------------
int_start: sti
cmp cs:work_flag,0 ;is it working ?
jz j10 ;yes, leave
iret
j10: mov cs:work_flag,1 ;set working flag
push es
push si
push di
push bp
pusha
cmp ax,remove_ax ; remove ?
jnz j20 ; no
popa
mov ax,cs ;restore old int 1ch
mov bx,exist_flag
mov cx,cs:old_off
mov dx,cs:old_seg
jmp j110
j20:
cmp ax,ask_ax ;is it ask exist
jnz j50 ;no
popa
mov bx,exist_flag
jmp j110
; do show time
j50: cmp ax,alarm_set_ask ;is it timer setting ?
jnz j52 ;no
mov delay_count,cx ;keep user timer
dec alarm_count ;init alarm
;
j52:
cmp delay_count,0 ;is it end timer
jnz j53 ;no
cmp alarm_count,alarm_time ;is it alarm time ?
jz j60 ; no
jmp short j55
.386
j53: xor eax,eax
dec delay_count
mov ax,delay_count
jnz j70
; time_up
j55:
dec alarm_count ;alarm end ?
jz j60 ;yes, back to current time
j59: mov bp,offset alarm_str ;print alarm string
mov bl,alarm_att
mov ax,cs
mov es,ax
jmp short j90
j60: mov ax,40h
mov es,ax
mov eax,dword ptr es:[006ch] ;get system time count
j70: mov ebx,10 ;change to hh:mm:ss format
mul ebx
mov ebx,182
xor edx,edx
div ebx ;total seconds
mov ebx,60
xor edx,edx
div ebx ;ax = min / edx = seconds
mov cl,dl ;second
xor edx,edx
div ebx ;ax = hour / edx = min
.286
mov di,cs
mov es,di
mov di,offset time_str
mov bp,di
add al,0
aam ;BCD format
or ax,3030h ;change to ASCII
xchg ah,al
stosw
inc di
mov al,dl
add al,0
aam
or ax,3030h
xchg ah,al
stosw
inc di
mov al,cl
add al,0
aam
or ax,3030h
xchg ah,al
stosw
mov alarm_count,alarm_time ;reset
mov bl,time_att
j90: mov dh,0 ;row
mov dl,80-8 ;column
mov cx,8
mov bh,0 ;page
mov ax,1300h ;print timer
int 10h
j100:
popa
j110: pop bp
pop di
pop si
pop es
mov cs:work_flag,0 ;clear flag
iret
;------------------------------------------------
time_str db '00:00:00',0
alarm_str db ' -alarm-',0
tsr_end equ $
not_exist db 'clock not install!','$'
release_str db 'clock removed!','$'
exist_str db 'clock already installed!','$'
install_str db 'clock installed',0dh,0ah
db 'type clock s mm:ss to set timer.',0dh,0ah
db 'type clock u to remove','$'
alarm_install db 'alarm installed',0dh,0ah,'$'
over_limit db 'over limit !!!',10,13,'$'
err_format db 'times format error !!!',10,13,'$'
minute dw 0
second dw 0
min_limit dw 60
sec_limit dw 60
alarm_set db 0
ratioa dw 10
ratiob dw 182
limit_time equ 10
init: mov si,82h
xor cx,cx
mov cl,[si-2] ;get length
jcxz s70
mov al,[si]
mov bx,cx
mov byte ptr ds:[si+bx-1],0 ;clear 0dh
and al,11011111b ;upcase
cmp al,'U' ;remove ?
jz s10
cmp al,'S' ;timer ?
jnz s70
call read_time ;change user input to hex number
mov alarm_set,0
jc short s70 ;input error
mov alarm_set,1
jmp short s70 ;input ok
s10: mov ax,remove_ax ;remove !
int 1ch
cmp bx,exist_flag
jz s20 ;aleady exist
mov dx,offset not_exist
s15: mov ah,9
int 21h
mov ah,4ch ;quit
int 21h
s20: push ax
push ax
push ds
mov ds,dx
mov dx,cx
mov ax,251ch ;reset old int
int 21h
pop ds
pop es ; get tsr cs
mov ax,word ptr es:[002ch]
mov es,ax
mov ah,49h ;release psp memory
int 21h
pop es
mov ah,49h ;release tsr memory
int 21h
mov dx,offset release_str
jmp short s15
s70: ; install, ask first
;
mov ax,remove_ax
int 1ch
cmp bx,exist_flag
jnz s75
cmp alarm_set,1
jz s77
mov dx,offset exist_str
jmp s15
; not install
s75:
mov al,1ch
mov ah,35h ;read old 1ch
int 21h
mov old_off,bx
mov old_seg,es
mov al,1ch
mov ah,25h ;read our 1ch
mov dx,offset int_start
int 21h
s77: cmp alarm_set,0
jz s80
mov ax,alarm_set_ask ;set alarm, cx = user input
mov cx,delay_count
int 1ch
;
mov dx,offset alarm_install
jmp short s90
s80: mov dx,offset install_str
s90: mov ah,9
int 21h
mov dx,offset tsr_end
int 27h ;stay my program and exit
;--------------------------------------------------------------
read_time: ;read user input and change to hex
add si,2 ;point to time set
mov di,offset minute
mov bx,offset min_limit
mov cx,2
push cs
pop es
rt10: xor ax,ax
lodsb
cmp byte ptr [si],':'
jz rt15
cmp byte ptr [si],0
jz rt15
sub al,'0'
mov ah,al
lodsb
rt15: sub al,'0'
aad
cmp ax,[bx]
jb rt20
mov dx,offset over_limit
rt16: mov ah,9
int 21h
jmp short readtx
rt20: stosw
inc bx
inc bx
dec cx
jz rt50
lodsb
cmp al,':'
jz rt10
cmp al,0
jz rt50
rt40: mov dx,offset err_format
jmp short rt16
rt50: call count_limit
jc rt40
ret
readtx: stc
ret
;------------------------------------------------------------------------------
count_limit: cmp minute,0
jnz cc20
cmp second,0
jnz cc20
cc10: stc
ret
cc20: mov ax,minute
mov bx,60
mul bx
add ax,second
cmp ax,limit_time
jb cc10
mul ratiob
div ratioa
mov delay_count,ax ;save user input
clc
ret
;------------------------------------------------------------------------------
cseg ends
end begin ; end program
http://pan.baidu.com/s/1o6IFrHw
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Assembly
1
https://gitee.com/zhishi/asm_for_all.git
git@gitee.com:zhishi/asm_for_all.git
zhishi
asm_for_all
asm_for_all
master

搜索帮助