题目
编写一个中断处理程序,要求在主程序运行期间每隔 10秒响铃一次,同时显示‘The bell is ring!’
思路
在系统定时器(中断类型为8)的中断定时器中,有一条中断指令INT 1CH,时钟中断每发生一次(约每秒中断18.2次)都要嵌套调用一次中断类型1CH的处理程序。在ROM BIOS例程中,1CH的处理程序只有一条IRET指令,实际上它并没有做任何工作,只是为用户提供了一个中断类型号。如果用户有某种定时周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的处理程序来代替原有的1CH中断程序。
1CH作为用户使用的中断类型,可能已被其他功能的程序所引用,所以在编写新的中断程序时,应做如下工作:
(1)在主程序初始化部分,先保存当前1CH的中断向量,再设置新的中断向量
(2)在主程序结束部分恢复保存的1CH中断向量。
代码
;编写一个中断处理程序,要求在主程序运行期间,
; 每隔 10秒响铃一次,同时显示‘The bell is ring!’
datasg segment
count dw 1
mess db 'The bell is ring!',0ah,0dh,'$'
datasg ends
codesg segment
main proc far
assume cs:codesg,ds:datasg,es:datasg
start:
push ds
xor ax,ax
push ax
mov ax,datasg
mov ds,ax
mov es,ax
;---------------------
mov al,1ch ;中断号
mov ah,35h
int 21h ;取原中断向量
push es
push bx ;存放在es:bx中,保存原中断向量
push ds ;保护数据段
mov dx,offset ring
mov ax,seg ring
mov ds,ax ;设置新的中断向量 ds:dx
mov al,1ch
mov ah,25h
int 21h
pop ds ;设置完取出数据段
in al,21h ;21h中断屏蔽寄存器
and al,11111110b
out 21h,al ;设置中断屏蔽位,允许定时器中断
sti ;开中断
mov di,2000
delay:
mov si,30000
delay1:
dec si
jnz delay1
dec di
jnz delay
pop dx
pop ds
mov al,1ch
mov ah,25h
int 21h
ret
main endp
ring proc far
push ds
push ax
push cx
push dx
mov ax,datasg
mov ds,ax
sti ;开中断,允许更高级的中断
; EOI ;允许同级或低级的中断
dec count
jnz exit
mov dx,offset mess ;显示The bell is ring
mov ah,09
int 21h
mov dx,100
in al,61h
and al,11111100b
sound:
xor al,2
out 61h,al
mov cx,140h
wait1:
loop wait1
dec dx
jne sound ;响铃
mov count,182
exit:
cli ;关中断
pop dx
pop cx
pop ax
pop ds
iret
ring endp
codesg ends
end start
调试
响铃