下面一段程序是使用1CH的中断向量(系统定时器)用来每十秒扬声一次,并且显示一条信息。主程序内只是一个空的循环,1CH每秒中断约18.2次,每182次真正执行一次中断处理程序。
奇怪的是第一次写的空循环太多了,程序没执行完把它给结束了,用的是2K下的命令提示符,再次启动计算机的时候我的扬声器有的时候就会无缘无故的开始发声了,声音是那种几。。几。。几几的跟以前的M拨号上网一样,真难听
我如果在执行这个程序的话,那声音就没了,程序一执行完,声音又出来了
郁闷死了,那位高手指点一下,难道我重新启动计算机也初始不了扬声器的控制寄存器?还是扬声器坏了??
代码如下:
;*************************
;f.asm
;purpose:ring and display a message every 10 second

;*************************

        .model  small
        ;______________

        .stack
        ;________________

        .data

COUNT   DW      1
MSG     DB      'The bell is ringing!',0DH,0AH,'$'

        .code

;Main Program

MAIN    PROC    FAR
START:  MOV     AX,@DATA
        MOV     DS,AX

;Save old interrupt vector

        MOV     AL,1CH  ;send interrupt number to AL
        MOV     AH,35H  ;to get interrupt vector
        INT     21H     ;CALL DOS
        PUSH    ES      ; to save the interrupt number of 1CH
        PUSH    BX
        PUSH    DS

;Set new interrupt vector

        MOV     DX,OFFSET RING  ;send new interrupt offset to DX
        MOV     AX,SEG  RING    ;send new interrupt segment to DS
        MOV     DS,AX
        MOV     AL,1CH          ;to set new interrupt number
        MOV     AH,25H          ;set function number of DOS
        INT     21H             ;CALL DOS

        POP     DS              ;restore DS
        IN      AL,21H          ;set interrupt mask bit,0
        AND     AL,11111110B

        STI

        MOV     BX,10
DELAY:  MOV     DI,60000
DELAY1: MOV     SI,60000
DELAY2: DEC     SI
        JNZ     DELAY2
        DEC     DI
        JNZ     DELAY1
    DEC    BX
    JNZ    DELAY

;resotre old interrupt vector

        POP     DX
        POP     DS
        MOV     AL,1CH
        MOV     AH,25H
        INT     21H

;return DOS

        MOV     AH,4CH
        INT     21H
MAIN    ENDP



;Procedure RING
;purpose:ring every 10 seconds when substituted for interrupt 1CH

RING    PROC    NEAR
        PUSH    DS      ;save the working register
        PUSH    AX
        PUSH    CX
        PUSH    DX

        MOV     AX,@DATA        ;allot DS seg        
        MOV     DS,AX
        STI

;siren if it is time for ring

        DEC     COUNT   ;count for ring interval
        JNZ     EXIT    ;exit if not for ring time

        MOV     DX,OFFSET MSG   ; to display the message
        MOV     AH,09H
        INT     21H

        MOV     DX,100          ;inialized the turn on/off times
        IN      AL,61H          ;get port 61h
        AND     AL,0FCH         ;mask bit 0,1
        
SOUND:  XOR     AL,02           ;toggle bit 1
        OUT     61H,AL          ;output to port 61h

        MOV     CX,1400H        ;value of wait
WAIT1:  LOOP    WAIT1
        DEC     DX              ;control turn on/off 10 times
        JNE     SOUND
        MOV     COUNT,182       ;control ring interval delay(10s)

EXIT:
        CLI
        POP     DX      ;restore register
        POP     CX
        POP     AX
        POP     DS
        IRET
RING    ENDP

;______________________________
        END     START   ;end assemble