[设为首页]
中国-东莞·教育导航
  主页 | 教育资讯 | 推荐课程 | 公开课 | 考试 | 资格认证 | 外语 | 硕士考研 | 自考成考 | IT培训 | 金融财会 | 名校 | 学习资料
  导航:首页 - 汇编编写DOS下的内存驻留程序(3)

汇编编写DOS下的内存驻留程序(3)
作者:城市学习网 来源:网上收集 更新日期:2007-12-15 阅读次数:

  三 中断矢量
  3.1 IBM PC提供的中断
   IBM PC有两种基本形态的中断.如果是由外围设备所产生的中断就叫做硬件中断(Hardware interrupt),譬如:键盘,磁盘机和时钟等外围设备都可以产生硬件中断.外围设备所产生的中断信号都连接到中断控制器,中断控制器可以根据它们之间的重要性来安排优先顺序,以便使CPU有效地处理这些硬件信号.另一种中断是软件中断(Software interrupt),软件中断也叫做陷井(Trap),它是由执行中的软件所产生.虽然软件包中断的处理方式和硬件中断完全相同,但是通常软件中断是希望执行操作系统所提供的服务.
   表3.1是IBM PC所提供的中断,这些中断是根据中断号码和中断矢量(Interrupt vector)排列.
   IBM PC的用户或是编写应用程序的程序人员很少会直接接触到硬件中断,除非是使用某些特殊的硬件,或是需要较严格的要求时,最常被修改的硬件中断是敲键盘所产生的中断(9H),尤其是文本编辑的程序.大体而言,只有硬件设计者基是系统程序人员才会注意到所有在硬件中断;编写内存驻留程序的设计人员则只使用到部分硬件中断而已,尤其是:键盘中断和计时器(Timer)的中断.
   反之,软件中断对于任何编写汇编程序的人,甚至对编写高级语言程序的人都相当的重要.软件中断是应用程序进入到IBM PC操作系统的接口,经由这些接口应用程序才可以执行所要求的系统服务.
   其中软件中断中最重要,同时也是最常被汇编语言程序设计师所用到是DOS INT 21H.这个中断是执行DOS系统调用的软件中断,它可以让应用程序执行任何DOS的操作.
   接下来最有用的软件中断是ROM-BIOS(基本输入输出系统)所提供的中断.这些软件中断是IBM PC所提供的的低层次服务,譬如:键盘输入,显示器输出和磁盘机的输入与输出等.
3.2 键盘输入的方法
   以下就以IBM PC从键盘读取字符为例子,来说明中断的工作方式.IBM PC从键盘读取字符时,使用了两种不同形式中断,亦即:硬件中断和软件中断.当使用者从键盘敲下一个键时,键盘的线路就会送出一个信号.这个信号会造成硬件中断发生,从而触发低层次的键盘中断处理程序开始执行.这个中断处理程序马上从键盘的硬件读取使用者所敲入的字符,然后把它放到一个队列中,如果这个队列填满时,键盘中断处理程序会使IBM PC发出一声响.键盘中断处理程序做完这些事情之后,它就把控制权交还给原先被中断的程序.如果有一个程序希望从键盘读取一个字符时,它就发出适当的软件中断信号,这时候就由相对应的中断处理程序去检查键盘队列,并且传回队列中的第一个字符.
   上面所介绍的键盘输入工作方式,在中断驱动系统中很普遍地采用.这和做法可以把实际上需要输入的应用程序和实际上执行输入的处理部分分开来.这种做法也可以用在其它不同形式的输入和输出外围设备.
  3.3 改变输入矢量
   中断矢量储存在IBM PC最前面的400H个字节中.每一个矢量的长度是四个字节组成,这四个字节内所存放的是中断处理程序执行的地址值.其中前两个字节包含地址值的位移(Offset)部分,后面的两个字节则包含了段(Segment)部分.
   中断矢量有两种修改方法.可以直接地设置中断矢量的地址值,或是使用DOS所提供的系统调用设置中断矢量的地址值.
   3.3.1 直接设置中断矢量
    因为中断矢量只是存放地址值的存储位置,因此我们可以直接地把地址存放到存储位置中.以下是一个小例子:
      mov ax,0
      mov es,ax
      mov word ptr es:24,offset Keyboard
      mov word ptr es:26,seg Keyboard
    在许多情况下,上面的程序都可以正确地执行.但是如果上面的程序正在执行时突然敲下一个键的话,就可能会问题;而最糟的情 况是发生:第三个MOV已经执行完毕,而第四个MOV尚未执行时.如果在此时敲下任何键的话,键盘中断矢量都没有任何意义,而造成整个系 统死机.因此我们可以在设置中断矢量时,让中断无效,譬如:
      mov ax,0
      mov es,ax
      cli
      mov word ptr es:24,offset Keyboard
      mov word ptr es:26,seg Keyboard
    上面的做法在大部分的情况下都可以正确地执行.但是CLI这个指令无法停止NMI中断(不可屏蔽中断),因此如果发生NMI中断时就 没用办法.  下面的这一种做法虽然比较复杂,但是对于所有的中断都有效,这包括了NMI中断在内:
      mov word ptr kbd-ptr[0],offset Keyboard
      mov word ptr kbd-ptr[2],seg Keyboard
      mov di,0      ;Use Di to Set ES to zero
      mov es,di      ;Set ES to destination segment
      mov di,24      ;Set DI to destination offset
      mov si,offset kbdptr    ;set SI to source offset
      mov cx,2      ;Set word count to 2
      cld       ;Set direction to forward   
      cli        ;Disable interrupts
      rep movsw     ;Copy the new vector
      sti       ;Enable interrupts
      kbdptr  dd  ?
    上面的程序中,kbdptr是两个字节(WORD)的指针(Pointer),其中包含了键盘 中断处理程序的起始志趣值.REP这个指令将根据寄存 器CX所设置的次数来重复执行MOVSW,而整个指令就如同单一的指令一样.NMI中断不能够发生在一个完整的指令中.因为地址值搬移的操 作都能包含在一个单一指令中,因此可以免除任何中断的干扰.
   3.3.2 使用DOS来设置中断矢量
    因为要想安全地设置中断矢量需要一些技巧,因此DOS提供了一项特殊的服务,以帮助程序人员安全地设置中断矢量,如果只使用 DOS所提供的这项服务来设定中断矢量的话,那么就不必担心会发生前面所叙述的差错.DOS同时也提供了:读取中断矢量的服务.因为读 取中断矢量的内容不会修改系统的状态;因此若直接写程序读取,也很安全.但是如果你要自己直接读取中断矢量的内容时,就必须计算 出中断矢量的位置.而DOS已经提供了这项服务.
    使用DOS所提供的系统调用,来读取中断矢量的内容时,必须利用INT 21H中的函数35H(读取中断矢量),这个函数热气矢量号码来 计算中断矢量的地址,然后返回其中的内容.以下就是一个例子:

Old_Keyboard_IO  dd  ?
      mov al,16h
      mov ah,35h
      int 21h
      mov word ptr Old_Keyboard_IO,bx  ;Offset of interrupt handler
      mov word ptr Old_Keyboard_IO,es  ;Segment of interrupt handler
    用DOS来设置中断矢量例子:
      New_Keyboard_IO  dd  ?
      mov word ptr New_Keyboard_IO,bx  ;Offset of interrupt handler
      mov word ptr New_Keyboard_IO,es  ;Segment of interrupt handler
      mov al,16h
      mov ah,25h
      int 21h


  3.4 检查中断矢量
   这里都是采用COM格式编程,可以建立一个BAT文件来处理写好的程序,以减少击键次数.设BAT文件名为MAKE.BAT:
      MASM %1
      LINK  %1
      EXE2BIN %1.EXE %1.COM
   如果写好的程序名为MACRO.ASM,则可敲入:
      C:\MAKE MACRO.ASM
   即可.
  3.5 显示中断矢量
   下面这个例子可以列出所有的重要的中断矢量内容,在刚刚打开PC时,并且没有执行任何驻留程序时,可以发现所有的中断矢量段值都相同,这些地址值所存放的是ROM的程序.当你修改中断矢量之后,就可以利用这个程序观察到中断矢量的变化.以下就是IVEC.ASM的内容:
     cseg    segment para public 'CODE'
      org     100h
      jmp start
      assume  cs:cseg,ds:cseg
     start: 
      mov     bx,cs                   ;Make data seg be the same as
      mov     ds,bx                   ;the code seg
      call    vectors
     waitIn:
      mov ah,0bh
      int 21h
      cmp al,0ffh
      jne waitIn
      mov     ah,4ch
      int     21h
     
     ;Scan through display table,prinying two vectors per line
     ;If any record has an interrupt #=zero,this indicates
     ;end of the table.
     
      mov     di,offset disptab       ;Pointer to start of table
      mov     dh,0                    ;Zero out top half of DX
     vloop: 
      mov     dl,[di]                 ;Get the interrupt number
      cmp     dl,0                    ;If it's zero,we are done
      je      vdone                   ;so exit loop
      add     di,1                    ;Advance pointer 1 byte
      mov     si,[di]                 ;Get pointer to description
      call    dvector                 ;Call the display routine
      add     di,2                    ;Get the interrupt number
      mov     dl,[di]                 ;Advance to the next record       
      cmp     dl,0                    ;If it's zero,we are done
      je      vdone                   ;so exit loop
      add     di,1                    ;Advance pointer 1 byte
      mov     si,[di]                 ;get pointer to description
      call    dvector                 ;Call the display routine
      add     di,2                    ;Advance to the next record
      jmp     vloop                  
     vdone:                   ;Print final CRLF
      ret
     vectors endp
     ;----------------------------------------------------------------------------
     ;Displays an interrupt vector.Display is in the form of
     ;,,:
     ;where ,and
     ;are all dexadecimal numbers
     ;Call with
     ;DX     -interrupt number
     ;DS:SI  -pointer to banner string
     ;----------------------------------------------------------------------------
     dvector proc    near
      call    dstring                 ;Display the string in DS:SI
      call    dbyte                   ;Display the byte in DL
      call    dspace                  ;Display a space
      call dspace
      ;
      mov     al,dl                   ;move the interrupt number to AL
      mov     ah,35h                  ;Function is Get interrupt vector
      int     21h
      mov     dx,bx                   ;Move BX to DX so we can display
      call    ddword                  ;double-word in ES:DX
      call dEndFra
      call    dcrlf                   ;Display a newline
      ret
     dvector endp  
     ;----------------------------------------------------------------------------
     ;DS:SI points to ASCII string to be printed
     ;----------------------------------------------------------------------------
     dstring proc    near
      push    si
      push    ax
     dis:    mov     al,[si]                 ;Fetch the next character
      cmp     al,0                    ;If it's zero,we are done
      je      disdone        
      call    dchar                   ;If not,point it
      inc     si                      ;Advance pointer to nest char
      jmp     dis
     disdone:pop     ax
      pop     si
      ret
     dstring endp

 ;----------------------------------------------------------------------------  
     ;ES:DX contains double word to be displayed
     ;----------------------------------------------------------------------------
     ddword  proc    near
      push    dx                      ;Save offset temporarily
      mov     dx,es                   ;Move segment to DX
      call    dsword                  ;Display segment
      call    dcolon                  ;Print a ";"
   ;          call    dcrlf
      pop     dx                      ;Restore offset to DX
      call    dsword                  ;Display offset
      ret
     ddword  endp
     ;----------------------------------------------------------------------------
     ;DX containes single word to be displayed
     ;----------------------------------------------------------------------------
     dsword  proc    near
      push    dx                      ;Save low byte temporarily
      mov     dl,dh                   ;Move high byte to low byte
      call    dbyte                   ;Display high byte
      pop     dx                      ;Restore low byte to DL
      call    dbyte                   ;Display low byte
      ret
     dsword  endp
     ;----------------------------------------------------------------------------
    ;DL contains byte to be displayed
     ;----------------------------------------------------------------------------
     dbyte   proc    near
      push    ax                      ;Save any registers used
      push    dx                     
      push    si
      push    dx                      ;Save low nybble temporarily
      push    cx                      ;Save CX
      mov     cl,4                    ;Set shift count to 4
      shr     dx,cl                   ;Shift high nybble into low nybble
      and     dx,0fh                  ;Mask out all but low nybble
      mov     si,dx                   ;Use low nybble as index into
      mov     al,hextab[si]           ;hexadecimal character table
      call    dchar                   ;Display character
      pop     cx                      ;Restore CX
      pop     dx                      ;Restore low nybble
      and     dx,0fh                  ;Mask out all but low nybble
      mov     si,dx                   ;Use low nybble as an index into
      mov     al,hextab[si]           ;hexadecimal character table
      call    dchar                   ;Display character
      pop     si                      ;Restore registers
      pop     dx
      pop     ax
      ret
     dbyte   endp
     ;----------------------------------------------------------------------------
     ;Display a ":"
     ;----------------------------------------------------------------------------
     dcolon  proc    near
      mov     al,':'
      call    dchar
      ret
     dcolon  endp
     ;----------------------------------------------------------------------------
     ;Display a " "
     ;----------------------------------------------------------------------------
     dspace  proc    near
      mov     al,' '
      call    dchar
      ret
     dspace  endp
     ;----------------------------------------------------------------------------
     ;Display a Carriage Return/Line Feed
     ;----------------------------------------------------------------------------
     dcrlf   proc    near
      mov     al,0dh
      call    dchar
      mov     al,0ah
      call    dchar
      ret
     dcrlf   endp
     ;----------------------------------------------------------------------------
     ;Display the character contained in AL
     ;----------------------------------------------------------------------------
     dchar   proc    near
      push    ax
      push    bx
      mov     bh,1
      mov     ah,0eh
      int     10h
      pop     bx
      pop     ax
      ret
     dchar   endp

  ;----------------------------------------------------------------------------
     ;Data define
     ;----------------------------------------------------------------------------
     hextab  db      '0123456789ABCDEF',0
     disptab db      05h                     ;Print screen
      dw      v05
      db      19h                     ;Bootstrap loader
      dw      v19                    
      db      08h                     ;Timer tick
      dw      v08
      db      1ah                     ;Real_time clock
      dw      v1a
      db      09h                     ;Keyboard input
      dw      v09    
      db      1bh                     ;CTRL_Break handler
      dw      v1b    
      db      0bh                     ;Comm.port 1
      dw      v0b                    
      db      1ch                     ;Timer control
      dw      v1c
      db      0ch                     ;Comm.port 0
      dw      v0c
      db      1dh                     ;Pointer to video parameter table
      dw      v1d
      db      0dh                     ;Hard disk controller
      dw      v0d
      db      1eh                     ;Pointer to disk parameter table
      dw      v1e
      db      0eh                     ;Floppy disk controller
      dw      v0e                    
      db      1fh                     ;Pointer graphics character table
      dw      v1f
      db      0fh                     ;Printer controller
      dw      v0f            
      db      20h                     ;Program terminate
      dw      v20
      db      10h                     ;Video driver
      dw      v10
      db      21h                     ;DOS universal function
      dw      v21
      db      11h                     ;Equipment check
      dw      v11            
      db      22h                     ;Pointer to termination handler
      dw      v22
      db      12h                     ;Memorey size check
      dw      v12
      db      23h                     ;Pointer to Ctrl_C handler
      dw      v23
      db      13h                     ;Disk driver
      dw      v13
      db      24h                     ;Pointer to critical error handler
      dw      v24
      db      14h                     ;Communications driver
      dw      v14
      db      25h                     ;Absolute disk read
      dw      v25
      db      15h                     ;Cassette driver
      dw      v15
      db      26h                     ;Absolute disk write
      dw      v26    
      db      16h                     ;Keyboard driver
      dw      v16
      db      27h                     ;Terminate and stay resident
      dw      v27
      db      17h                     ;Printer driver
      dw      v17
      db      2fh                     ;Print spooler
      dw      v2f
      db      18h                     ;Rom basic
      dw      v18
      db      0
      dw      0

v05     db      186,5 dup (20h),'Print screen:',26 dup (20h),0
     v08     db      186,5 dup (20h),'Timer tick controller:',17 dup (20h),0
     v09     db      186,5 dup (20h),'Keyboard input:',24 dup (20h),0                      
     v0b     db      186,5 dup (20h),'Communication port 1:',18 dup (20h),0
     v0c     db      186,5 dup (20h),'Communication port 0:',18 dup (20h),0
     v0d     db      186,5 dup (20h),'Hard disk controller:',18 dup (20h),0
     v0e     db      186,5 dup (20h),'Floppy disk controller:',16 dup (20h),0
     v0f     db     186,5 dup (20h),'Printer controller:',20 dup (20h),0
     v10     db      186,5 dup (20h),'Video driver:',26 dup (20h),0
     v11     db      186,5 dup (20h),'Equipment check:',23 dup (20h),0     
     v12     db      186,5 dup (20h),'Memory size check:',21 dup (20h),0
     v13     db      186,5 dup (20h),'Disk driver:',27 dup (20h),0
     v14     db      186,5 dup (20h),'Communication driver:',18 dup (20h),0
     v15     db      186,5 dup (20h),'Cassette driver:',23 dup (20h),0
     v16     db      186,5 dup (20h),'Keyboard driver:',23 dup (20h),0
     v17     db      186,5 dup (20h),'Printer driver:',24 dup (20h),0
     v18     db      186,5 dup (20h),'ROM BASIC:',29 dup (20h),0
     v19     db      186,5 dup (20h),'Bootstrap loader:',22 dup (20h),0
     v1a     db      186,5 dup (20h),'Real_time clock:',23 dup (20h),0
     v1b     db      186,5 dup (20h),'Ctrl_break handler:',20 dup (20h),0
     v1c     db      186,5 dup (20h),'Timer control:',25 dup (20h),0
     v1d     db      186,5 dup (20h),'Video parameter table:',17 dup (20h),0
     v1e     db      186,5 dup (20h),'Disk parameter:',24 dup (20h),0
     v1f     db     186,5 dup (20h),'Graphic character table:',15 dup (20h),0
     v20     db      186,5 dup (20h),'Programe terminate:',20 dup (20h),0
     v21     db      186,5 dup (20h),'DOS universal function:',16 dup (20h),0
     v22     db     186,5 dup (20h),'Terminate vector:',22 dup (20h),0
     v23     db      186,5 dup (20h),'Ctrl_C vector:',25 dup (20h),0
     v24     db      186,5 dup (20h),'Critical error vector:',17 dup (20h),0
     v25     db      186,5 dup (20h),'Absolute disk read:',20 dup (20h),0
     v26     db      186,5 dup (20h),'Absolute disk write:',19 dup (20h),0
     v27     db      186,5 dup (20h),'Terminate and stay resident:',11 dup (20h),0
     v2f     db      186,5 dup (20h),'Print spooler:',25 dup (20h),0
     cseg    ends
    end     start


报 名 此 课 程 / 咨 询 相 关 信 息
【预约登门】 【网上咨询】 【订座试听】 【现在报名】
课程名称
汇编编写DOS下的内存驻留程序(3)
真实姓名
* 性 别
联系电话
* E-mail:
所在地区
咨询内容

      

相关文章:

Copyright© 2014 www.dgedu.com.cn 东莞教育在线 版权所有
中国·东莞
粤ICP备06023013号