在系统定时器(中断类型为8)的中断处理程序中,有一条中断指令INT 1CH,时钟中断每发生一次(约每秒中断18.2次)都要嵌套调用一次中断类型1CH的处理程序。在ROM BIOS例程中,1CH的处理程序只有一条IRET指令,实际上它并没有做任何工作,只是为用户提供了一个中断类型号。如果用户有某种定时周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的处理程序来代替原有的1CH中断程序。

  1CH作为用户使用的中断类型,可能已被其它功能的程序所引用,所以在编写新的中断程序时,应作下述工作:
  (1) 在主程序的初始化部分,先保存当前1CH的中断向量,再置新的中断向量。
  (2) 在主程序的结束部分恢复保存的1CH中断向量。

 
Purpose: ring and display a message every 10 seconds.
  ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  ;eg8-5.asm
  ;Purpose: ring and display a message every 10 seconds.
  ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

     .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   ;allot data segment
  mov    ds, ax

; save old interrupt vector
  mov    al, 1ch    ;al<=vector number
  mov    ah, 35h    ;to get interrupt vector
  int    21h      ;call DOS
  push   es       ;save registers for restore
  push   bx
  push   ds

;set new interrupt vector
  mov    dx, offset ring  ;dx<=offset of procedure ring
  mov    ax, seg ring    ;ax<=segment of procedure ring
  mov    ds, ax       ;ds<=ax
  mov    al, 1ch      ;al<=vector#
  mov    ah, 25h      ;to set interrupt vector
  int    21h        ;call DOS

  pop ds            ;restore ds
  in     al, 21h      ;set interrupt mask bits
  and    al, 11111110b
  out    21h, al
  sti

   mov    di, 20000
delay: mov si, 30000
delay1:dec si
   jnz    delay1
   dec   di
   jnz   delay

;restore old interrupt vector
   pop    dx        ;restore registers
   pop    ds
   mov   al, 1ch      ;al<=vector#
   mov    ah, 25h      ;to restore interrupt
   int   21h        ;call DOS

   mov    ax, 4c00h     ;exit
   int   21h
main endp


ring proc   near
   push   ds         ;save the working registers
   push   ax
   push   cx
   push   dx

   mov    ax, @data     ;allot data segment
   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   ;dx<=offset of msg
  mov    ah, 09h      ;to display msg
  int    21h        ;call DOS

  mov    dx, 100      ;dx<=turn on/off times(100)
  in     al, 61h      ;get port 61h
  and    al, 0fch      ;mask bits 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
  mov    al,20h      ;set EOI
  mov    20h,al
  pop    dx        ;restore the reg.
  pop    cx
  pop    ax
  pop    ds
  iret            ;interrupt return
ring endp

;-------------------------------------------------------------------------
  end start          ;end assemble