灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:4324回复:0

[汇编源码]汇编源码--alarm

楼主#
更多 发布于:2011-10-26 09:21
[pre]
cseg    segment para public 'code'org    100halarm    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 onintaddr equ 1ch*4        ; interrupt addresssegaddr equ 62h*4        ; segment address of first copymfactor equ 17478        ; minute conversion factor * 16whozat    equ 1234h        ; signaturecolor    equ 14h         ; color attribute    assume cs:cseg,ds:cseg,ss:nothing,es:nothing    jmp p150        ; start-up codejumpval dd 0            ; address of prior interruptsignature dw whozat        ; program signaturestate    db 0            ; '-' = off, all else = onwait    dw 18            ; wait time - 1 second or 18 tickshour    dw 0            ; hour of the dayatime    dw 0ffffh        ; minutes past midnite for alarmacount    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 frequencyaleng    dw 8080h        ; alarm length (loop count) may be from 1-FFFFdhours    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 stackestack    db 0            ; end of stackholdsp    dw 0            ; original spholdss    dw 0            ; original ssp000:                ; 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        ; returnp010:    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 p070p015:    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,axp018:    pop axp020:    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 amp030:    cmp ax,12        ; before noon?    jb p040a        ; yes - set am    jz p040p        ; noon - set pm    sub ax,12        ; convert the restp040p:    mov bl,'p'    jmp p040xp040a:    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 oncep060:    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 addressp061:    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 countp062:    mov bl,[si]        ; get next characterp063:    in al,dx        ; get crt status    test al,1        ; is it low?    jnz p063        ; no - wait    cli            ; no interruptsp064:    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 interruptsp080:    popf    pop ds    pop ax    jmp cs:[jumpval]p100    proc near        ; beep the speaker twice    call p120    push cx    mov cx,20000p105:    loop p105        ; wait around    pop cx    call p120    push cx    mov cx,20000p106:    loop p106        ; wait around    pop cx    call p120    retp100    endpp120    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 countp125:    loop p125        ; wait around    pop ax            ; restore original port value    out 61h,al        ; turn speaker off    pop cx    pop ax    retp120    endpp150:                ; 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         ; terminatep160:    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         ; terminatep200    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 zerop203:    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 p206p204:    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 p206p205:    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 cxp206:    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 p210p209:    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 p220p210:    retp200    endpp220    proc near        ; print message    push ax    mov ah,9    int 21h    pop ax    retp220    endpcopyr    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    endpcseg    endsend    alarm
[/pre]

喜欢0 评分0
游客

返回顶部