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 + -
显示快捷键?