interc.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 523 行 · 第 1/2 页

ASM
523
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;*               DESCRIBE IT HERE!
;*
;*****************************************************************************


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; these routines are part of a system largely described in SAMPLE.C
;
        name    INTERC

        extrn   StopAndSave_        : near
        extrn   WriteMark_          : near
        extrn   WriteOvl_           : near
        extrn   StartTimer_         : near
        extrn   StopTimer_          : near
        extrn   RememberComm_       : near

DGROUP  group   _DATA
_DATA   segment word public 'DATA'
        extrn   _Save_Request       : word
_DATA   ends

_TEXT   segment word public 'CODE'
;
; code segment data
;
int21_retseg    dw      SEG int21_return
int21_retoff    dw      OFFSET int21_return

intxx_retseg    dw      SEG intxx_return
intxx_retoff    dw      OFFSET intxx_return

InDOSAddr       dd      ?
ErrorModeAddr   dd      ?
InBIOS          dw      ?

                public  _old_int28,_old_int21,_old_int13
_old_int28      dd      ?
_old_int21      dd      ?
_old_int13      dd      ?

                public  _old_intx0,_old_intx1,_old_intx2,_old_intx3
                public  _old_intx4,_old_intx5,_old_intx6,_old_intx7
_old_intx0      dd      ?
_old_intx1      dd      ?
_old_intx2      dd      ?
_old_intx3      dd      ?
_old_intx4      dd      ?
_old_intx5      dd      ?
_old_intx6      dd      ?
_old_intx7      dd      ?

                public _SysCallerAddr
                public _SysCaught
                public _SysNoDOS
_SysCallerAddr  dd      ?
_SysCaught      db      ?
_SysNoDOS       db      ?

_sysCaller      db      ?
;
; code starts here
;
        ASSUME  cs:_TEXT,ds:nothing,es:nothing

;
; *** INT 13 handler ***
;
        public  int13_handler_
int13_handler_  proc    far
        inc     word ptr cs:InBIOS  ; say we're in the BIOS
        pushf                       ; invoke old handler
        call    cs:_old_int13
        pushf                       ; save flags
        dec     word ptr cs:InBIOS  ; we're out of BIOS
        popf                        ; restore flags
        ret     2                   ; return to caller
int13_handler_  endp

;
; *** Overlay handler ***
;
        public  ovl_handler_
ovl_handler_    proc    far
        push    ax              ; save registers
        push    bx              ; ...
        push    cx              ; ...
        push    dx              ; ...
        push    si              ; ...
        push    ds              ; ...
        mov     si,seg DGROUP   ; setup DS registers
        mov     ds,si           ; ...
        call    WriteOvl_       ; write out current ovl state
        pop     ds              ; restore registers
        pop     si              ; ...
        pop     dx              ; ...
        pop     cx              ; ...
        pop     bx              ; ...
        pop     ax              ; ...
        ret                     ; return to caller
ovl_handler_    endp

;
; *** INT 03 Handler ***
;
        public  int03_handler_
int03_handler_  proc    far     ; mark interceptor
        push    bp              ; save bp
        mov     bp,sp           ; get access to stack
        push    ds              ; save registers
        push    si              ; ...
        mov     si,seg DGROUP   ; setup DS register
        mov     ds,si           ; ...
        test    dx,dx           ; if dx is non-NULL, this is a real mark
        jz      NoMark          ; otherwise, it signals callgraph info
IsMark  LABEL   near            ; we have a real mark
        mov     bx,2[bp]        ; get interrupt offset
        dec     bx              ; back up to start of opcode
        mov     cx,4[bp]        ; get interrupt segment
        call    WriteMark_      ; write out the mark
        jmp     EndMark         ; return to program
NoMark  LABEL   near            ; we have new callgraph information
        mov     ax,bx
        mov     dx,cx
        call    RememberComm_   ; remember common storage area
EndMark LABEL   near            ; resume program execution
        pop     si              ; restore registers
        pop     ds              ; ...
        pop     bp              ; ...
        iret                    ; return to caller
int03_handler_  endp

;
; UnHook -- temporarily stop the timer
;
UnHook  LABEL   near
        push    ds
        push    ax
        mov     ax,seg DGROUP
        mov     ds,ax
        call    StopTimer_
        pop     ax
        pop     ds
        call    cs:_old_int21      ;this is a far indirect call
        pushf
        push    ds
        push    ax
        mov     ax,seg DGROUP
        mov     ds,ax
        ASSUME  ds:DGROUP
        call    StartTimer_
        cli
        xor     ax,ax
        xchg    ax,_Save_Request; clears _Save_Request (StopAndSave needs this)
        test    ax,ax           ; any requests?
        jz      UnHook1         ; zero -> NO
        call    DOSState        ; is DOS stable?
        jc      UnHook1         ; carry set -> NO
        call    StopAndSave_    ; _Save_Request must be 0 (DOS will be called)
UnHook1 LABEL   near
        ASSUME  ds:nothing
        pop     ax
        pop     ds
        popf
        retf    2               ; return and ignore flags

;
; *** INT 21 Handler ***
;
        public  int21_handler_
int21_handler_ proc far
        pushf
        cmp     cs:_sysCaller,0
        jne     XDD1
        cmp     cs:_SysNoDOS,0
        jne     XDD1
        popf
        pop     word ptr cs:_SysCallerAddr   ; pop off seg:off of caller
        pop     word ptr cs:_SysCallerAddr+2 ; (without changing flags)
        push    cs:int21_retseg ; replace with unwind21 seg:off
        push    cs:int21_retoff ; (without changing flags)
        pushf
        mov     cs:_sysCaller,1
        mov     cs:_SysCaught,1

XDD1    LABEL   near
        cmp     ax,2508h        ; setting the timer interrupt?
        je      UnHook          ; do magic
        cmp     ax,3508h        ; getting the timer interrupt?
        je      UnHook          ; do magic

        popf
        jmp     cs:_old_int21

;
; *** INT 21 return interceptor ***
;
int21_return LABEL near         ; we will be returning to the application
        push    word ptr cs:_SysCallerAddr+2 ; push seg:off of caller
        push    word ptr cs:_SysCallerAddr   ; (without changing flags)
        mov     cs:_SysCaught,0 ; no more samples assigned to application now
        mov     cs:_sysCaller,0
        pushf
        push    ds
        push    ax
        mov     ax,DGROUP
        mov     ds,ax
        ASSUME  ds:DGROUP
        cli
        xor     ax,ax
        xchg    ax,_Save_Request; clears _Save_Request (StopAndSave needs this)
        test    ax,ax           ; any requests?
        jz      XL2             ; zero -> NO
        call    DOSState        ; is DOS stable?
        jc      XL2             ; carry set -> NO
        call    StopAndSave_    ; _Save_Request must be 0 (DOS will be called)
XL2     LABEL   near
        ASSUME  ds:nothing
        pop     ax
        pop     ds
        popf
        retf
int21_handler_  endp

;
; *** INT 28 Handler ***
;
        public  int28_handler_
int28_handler_  proc    far
        pushf
        push    ds              ; get addressability for DGROUP
        push    ax
        mov     ax,DGROUP
        mov     ds,ax

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?