主题:扬声器
下面一段程序是使用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
奇怪的是第一次写的空循环太多了,程序没执行完把它给结束了,用的是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