您当前位置: 圣才学习网首页 >> IT类 >> 编程技术库

DOS汇编源码系列教程——alarm

扫码手机阅读
用圣才电子书APP或微信扫一扫,在手机上阅读本文,也可分享给你的朋友。
评论(0
来源:网络 作者:未知
这个都是过去DOS时代的汇编源码,虽然已经过去了,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言,大多人掌握即可,不一定要深入研究.......
cseg  segment para public 'code'
org  100h
alarm  proc far
; Memory-resident program to intercept the timer interrupt and display the
; system time in the upper right-hand corner of the display.
; This program is run as 'ALARM hh:mm x', where hh:mm is the alarm time and
; x is '-' to turn the display off. Any other value of x or no value will
; turn the clock on
intaddr equ 1ch*4    ; interrupt address
segaddr equ 62h*4    ; segment address of first copy
mfactor equ 17478    ; minute conversion factor * 16
whozat  equ 1234h    ; signature
color  equ 14h     ; color attribute
  assume cs:cseg,ds:cseg,ss:nothing,es:nothing
  jmp p150    ; start-up code
jumpval dd 0      ; address of prior interrupt
signature dw whozat    ; program signature
state  db 0      ; '-' = off, all else = on
wait  dw 18      ; wait time - 1 second or 18 ticks
hour  dw 0      ; hour of the day
atime  dw 0ffffh    ; minutes past midnite for alarm
acount  dw 0      ; alarm beep counter - number of seconds (5)
atone  db 5      ; alarm tone - may be from 1 to 255 - the
        ; higher the number, the lower the frequency
aleng  dw 8080h    ; alarm length (loop count) may be from 1-FFFF
dhours  dw 0      ; display hours
  db ':'
dmins  dw 0      ; display minutes
  db ':'
dsecs  dw 0      ; display seconds
  db '-'
ampm  db 0      ; 'A' or 'P' for am or pm
  db 'm'
tstack  db 16 dup('stack  ')  ; temporary stack
estack  db 0      ; end of stack
holdsp  dw 0      ; original sp
holdss  dw 0      ; original ss
p000:        ; interrupt code
  push ax     ; save registers
  push ds
  pushf
  push cs
  pop ds      ; make ds=cs
  mov ax,wait    ; check wait time
  dec ax      ; zero?
  jz p010     ; yes - 1 second has elapsed
  mov wait,ax    ; not this time
  jmp p080    ; return
p010:  cli      ; disable interrupts
  mov ax,ss    ; save stack
  mov holdss,ax
  mov holdsp,sp
  mov ax,ds
  mov ss,ax    ; point to internal stack
  mov sp,offset estack
  sti      ; allow interrupts
  push bx     ; save other registers
  push cx
  push dx
  push es
  push si
  push di
  push bp
  mov ax,18    ; reset wait time
  mov wait,ax
  mov al,state    ; are we disabled?
  cmp al,'-'
  jnz p015    ; no
  jmp p070
p015:  mov ah,0    ; read time
  int 1ah     ; get time of day
  mov ax,dx    ; low part
  mov dx,cx    ; high part
  mov cl,4
  shl dx,cl    ; multiply by 16
  mov bx,ax
  mov cl,12
  shr bx,cl    ; isolate top 4 bits of ax
  add dx,bx    ; now in upper
  mov cl,4
  shl ax,cl    ; multiply by 16
  mov bx,mfactor    ; compute minutes
  div bx      ; minutes in ax, remainder in dx
  cmp ax,atime    ; time to sound the alarm?
  jnz p020    ; no
  call p100    ; yes - beep the speaker twice
  push ax
  mov ax,acount    ; get beep count
  dec ax      ; down by 1
  mov acount,ax    ; save beep count
  cmp ax,0    ; is it zero?
  jnz p018    ; no - keep alarm on
  mov ax,0ffffh    ; turn off alarm
  mov atime,ax
p018:  pop ax
p020:  mov dsecs,dx    ; save remainder
  mov bx,60    ; compute hours
  xor dx,dx    ; zero it
  div bx      ; hours in ax, minutes in dx
  mov dmins,dx    ; save minutes
  cmp ax,0    ; midnight?
  jnz p030    ; no
  mov ax,12    ; yes
  jmp p040a    ; set am
p030:  cmp ax,12    ; before noon?
  jb p040a    ; yes - set am
  jz p040p    ; noon - set pm
  sub ax,12    ; convert the rest
p040p:  mov bl,'p'
  jmp p040x
p040a:  mov bl,'a'
p040x:  mov ampm,bl
  aam      ; fix up hour
  cmp ax,hour    ; top of the hour?
  jz p060     ; no
  mov hour,ax
  call p120    ; beep the speaker once
p060:  add ax,3030h    ; convert hours to ascii
  xchg ah,al
  mov dhours,ax
  mov ax,dmins    ; get minutes
  aam
  add ax,3030h    ; convert to ascii
  xchg ah,al
  mov dmins,ax
  mov ax,dsecs    ; get seconds (remainder)
  xor dx,dx
  mov bx,60
  mul bx
  mov bx,mfactor
  div bx      ; seconds in ax
  aam
  add ax,3030h
  xchg ah,al
  mov dsecs,ax
  xor ax,ax    ; check monitor type
  mov es,ax
  mov ax,es:[410h]  ; get config byte
  and al,30h    ; isolate monitor type
  cmp al,30h    ; color?
  mov ax,0b000h    ; assume mono
  jz p061     ; its mono
  mov ax,0b800h    ; color screen address
p061:  mov dx,es:[463h]  ; point to 6845 base port
  add dx,6    ; point to status port
  mov es,ax    ; point to monitor
  mov bh,color    ; color in bh
  mov si,offset dhours  ; point to time
  mov di,138    ; row 1, col 69
  cld
  mov cx,11    ; loop count
p062:  mov bl,[si]    ; get next character
p063:  in al,dx    ; get crt status
  test al,1    ; is it low?
  jnz p063    ; no - wait
  cli      ; no interrupts
p064:  in al,dx    ; get crt status
  test al,1    ; is it high?
  jz p064     ; no - wait
  mov ax,bx    ; move color & character
  stosw      ; move color & character again
  sti      ; interrupts back on
  inc si      ; point to next character
  loop p062    ; done?
p070:  pop bp      ; restore registers
  pop di
  pop si
  pop es
  pop dx
  pop cx
  pop bx
  cli      ; no interrupts
  mov ax,holdss
  mov ss,ax
  mov sp,holdsp
  sti      ; allow interrupts
p080:  popf
  pop ds
  pop ax
  jmp cs:[jumpval]
p100  proc near    ; beep the speaker twice
  call p120
  push cx
  mov cx,20000
p105:  loop p105    ; wait around
  pop cx
  call p120
  push cx
  mov cx,20000
p106:  loop p106    ; wait around
  pop cx
  call p120
  ret
p100  endp
p120  proc near    ; beep the speaker once
  push ax
  push cx
  mov al,182
  out 43h,al    ; setup for sound
  mov al,0
  out 42h,al    ; low part
  mov al,atone    ; get alarm tone
  out 42h,al    ; high part
  in al,61h
  push ax     ; save port value
  or al,3
  out 61h,al    ; turn speaker on
  mov cx,aleng    ; get loop count
p125:  loop p125    ; wait around
  pop ax      ; restore original port value
  out 61h,al    ; turn speaker off
  pop cx
  pop ax
  ret
p120  endp
p150:        ; start of transient code
  mov dx,offset copyr
  call p220    ; print copyright
  mov ax,0
  mov es,ax    ; segment 0
  mov di,segaddr+2  ; this program's prior location
  mov ax,es:[di]    ; get prior code segment
  mov es,ax    ; point to prior program segment
  mov di,offset signature
  mov cx,es:[di]    ; is it this program?
  cmp cx,whozat
  jnz p160    ; no - install it
  call p200    ; set state & alarm
  int 20h     ; terminate
p160:  mov di,segaddr+2  ; point to int 62h
  mov ax,0
  mov es,ax    ; segment 0
  mov ax,ds    ; get current ds
  mov es:[di],ax    ; set int 62h
  mov si,offset jumpval
  mov di,intaddr    ; point to timer interrupt
  mov bx,es:[di]    ; get timer ip
  mov ax,es:[di+2]  ; and cs
  mov [si],bx    ; save prior ip
  mov [si+2],ax    ; and cs
  mov bx,offset p000
  mov ax,ds
  cli      ; clear interrupts
  mov es:[di],bx    ; set new timer interrupt
  mov es:[di+2],ax
  sti      ; set interrupts
  push ds
  pop es
  call p200    ; set state & alarm
  mov dx,offset p150  ; last byte of resident portion
  inc dx
  int 27h     ; terminate
p200  proc near    ; set state & alarm
  mov si,80h    ; point to command line
  mov ax,0
  mov di,0ffffh    ; init hours
  mov bh,0
  mov ch,0
  mov dh,0    ; : counter
  mov es:[state],bh  ; turn clock on
  mov cl,[si]    ; get length
  jcxz p210    ; it's zero
p203:  inc si      ; point to next char
  mov bl,[si]    ; get it
  cmp bl,'-'       ; is it a minus?
  jnz p204    ; no
  mov es:[state],bl  ; turn clock off
  push dx
  mov dx,offset msg3  ; print msg
  call p220
  pop dx
  jmp p206
p204:  cmp dh,2    ; seen 2nd colon?
  jz p206     ; yes - ignore seconds
  cmp bl,':'       ; colon?
  jnz p205    ; no
  inc dh
  cmp dh,2    ; second colon?
  jz p206     ; yes - ignore seconds
  push cx
  push dx
  mov cx,60
  mul cx      ; multiply current ax by 60
  pop dx
  pop cx
  mov di,ax    ; save hours
  mov ax,0
  jmp p206
p205:  cmp bl,'0'
  jb p206     ; too low
  cmp bl,'9'
  ja p206     ; too high - can be a problem
  sub bl,'0'       ; convert it to binary
  push cx
  push dx
  mov cx,10
  mul cx      ; multiply current value by 10
  add ax,bx    ; and add latest digit
  pop dx
  pop cx
p206:  loop p203    ; done yet?
  cmp di,0ffffh    ; any time to set?
  jz p210     ; no
  add ax,di    ; add hours
  cmp ax,24*60
  jb p209     ; ok
  mov dx,offset msg1  ; print error message
  call p220
  jmp p210
p209:  mov es:[atime],ax  ; save minutes past midnight
  mov ax,5
  mov es:[acount],ax  ; set alarm count
  mov dx,offset msg2  ; print set msg
  call p220
p210:  ret
p200  endp
p220  proc near    ; print message
  push ax
  mov ah,9
  int 21h
  pop ax
  ret
p220  endp
copyr  db 'Alarm - Clock',10,13,'$'
msg1  db 'Invalid time - must be from 00:00 to 23:59',10,13,'$'
msg2  db 'Resetting alarm time',10,13,'$'
msg3  db 'Turning clock display off',10,13,'$'
alarm  endp
cseg  ends
end  alarm
 

小编工资已与此挂钩!一一分钱!求打赏↓ ↓ ↓

如果你喜欢本文章,请赐赏:

已赐赏的人
最新评论(共0条)评论一句