interc.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 523 行 · 第 1/2 页
ASM
523 行
ASSUME ds:DGROUP
xor ax,ax
xchg ax,_Save_Request; clears _Save_Request (StopAndSave needs this)
test ax,ax ; any requests?
je XL1 ; 0 - NO
call StopAndSave_
XL1 LABEL near
ASSUME ds:nothing
pop ax
pop ds
popf
jmp cs:_old_int28
int28_handler_ endp
;
; *** INT XX Handlers *** (used by /i option)
;
public intx0_handler_
intx0_handler_ proc far
call intxx_splice
jmp cs:_old_intx0
intx0_handler_ endp
public intx1_handler_
intx1_handler_ proc far
call intxx_splice
jmp cs:_old_intx1
intx1_handler_ endp
public intx2_handler_
intx2_handler_ proc far
call intxx_splice
jmp cs:_old_intx2
intx2_handler_ endp
public intx3_handler_
intx3_handler_ proc far
call intxx_splice
jmp cs:_old_intx3
intx3_handler_ endp
public intx4_handler_
intx4_handler_ proc far
call intxx_splice
jmp cs:_old_intx4
intx4_handler_ endp
public intx5_handler_
intx5_handler_ proc far
call intxx_splice
jmp cs:_old_intx5
intx5_handler_ endp
public intx6_handler_
intx6_handler_ proc far
call intxx_splice
jmp cs:_old_intx6
intx6_handler_ endp
public intx7_handler_
intx7_handler_ proc far
call intxx_splice
jmp cs:_old_intx7
intx7_handler_ endp
;
; intxx_splice -- an INT XX has occurred; check whether an application
; return address is stored already (will be set if it isn't)
;
public intxx_splice
intxx_splice proc near
pushf
cmp cs:_sysCaller,0
jne intxx_go
push bp
mov bp,sp
push ax
mov ax,cs:intxx_retoff ; replace seg:off of caller with
xchg ax,6[bp] ; intxx_return address
mov word ptr cs:_SysCallerAddr,ax
mov ax,cs:intxx_retseg
xchg ax,8[bp]
mov word ptr cs:_SysCallerAddr+2,ax
mov cs:_sysCaller,1
mov cs:_SysCaught,1
pop ax
pop bp
intxx_go LABEL near
popf
ret
intxx_splice endp
;
; *** INT XX return interceptor ***
;
intxx_return proc far
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
ret ; return to application
intxx_return endp
;
; InDOS_ -- returns non-zero if DOS cannot be entered
;
public InDOS_
InDOS_ proc near
call DOSState ; sets carry if DOS is unavailable
sbb ax,ax ; 0 - OK, -1 - DOS unavailable
ret
InDOS_ endp
;
; VersionCheck -- initializes the addresses for internal DOS flags
; (InDOSAddr & ErrorModeAddr)
;
public VersionCheck_
VersionCheck_ proc near
push bx
push cx
push es
push di
push ds
push ss
pop ds
ASSUME ds:DGROUP
mov ah,34h
int 21h ; &InDOS -> es:bx
mov word ptr cs:InDOSAddr,bx
mov word ptr cs:InDOSAddr+2,es
mov ah,30h ; Get MS-DOS Version Number
int 21h ; sets bx=0, cx=0
xchg ah,al ; original order is major:al minor:ah
cmp ah,02h ; less than V2.xx?
jb Verror
cmp ax,030ah ; less than V3.10? (0ah = 10 decimal)
jb tough_search
cmp ax,0a00h ; OS/2 DOS box?
jae tough_search
;
; V3.10 and higher have the flags right beside each other
; (one byte below INDOS flag)
;
mov bx,word ptr cs:InDOSAddr
dec bx
jmp Vsuccess
tough_search:
mov cx,0ffffh
xor di,di ; ES is set to correct seg from 34h function
find_int28 LABEL near
mov ax,word ptr cs:LF2 ; scan for INT 28
try_again LABEL near
repne scasb
jne Verror
cmp ah,es:[di] ; check second byte for 28h
jne try_again
mov ax,word ptr cs:LF1+1 ; CMP opcode (+1 skips SS override)
cmp ax,es:[di][LF1-LF2]
jne try_test_op ; if it's not CMP
mov bx,es:[di][(LF1-LF2)+2] ; found offset
jmp VSuccess
try_test_op LABEL near
mov ax,word ptr cs:LF3+1 ; TEST opcode (+1 skips SS override)
cmp ax,es:[di][LF3-LF4]
jne find_int28
mov bx, es:[di][(LF3-LF4)+2]; found offset
jmp Vsuccess
Vsuccess LABEL near
mov word ptr cs:ErrorModeAddr,bx
mov word ptr cs:ErrorModeAddr+2,es
mov ax,1
Vexit LABEL near
pop ds
pop di
pop es
pop cx
pop bx
ret
Verror: xor ax,ax
jmp short Vexit
;
; the following are DOS code fragments that are used to find the code within
; DOS that checks the flags in question (see MSDOS encyclopedia)
;
LFnear LABEL near
LFbyte LABEL byte
LFword LABEL word
;
; *** PATTERN 1 ***
;
LF1: cmp ss:LFbyte,0 ; cmp ErrorMode,0
jne LFnear
LF2: int 28h
;
; *** PATTERN 2 ***
;
LF3: test ss:LFbyte, 0ffH ; test ErrorMode,0ffH
jne LFnear
push ss:LFword
LF4: int 28h
VersionCheck_ endp
;
; DOSState -- set carry if DOS cannot be called yet
;
DOSState proc near
push ax
push bx
push es
xor bx,bx
cmp bx,cs:InBIOS ; carry set if InBIOS != 0
jc bad
les bx,cs:ErrorModeAddr
mov ah,es:[bx]
les bx,cs:InDOSAddr
mov al,es:[bx]
xor bx,bx
cmp bx,ax ; carry set if ax != 0
bad: pop es
pop bx
pop ax
ret
DOSState endp
;
; DOSVer -- get DOS version number in ah:al (major:minor)
;
DOSVer proc near
push bx
push cx
mov ah,30h ; Get MS-DOS Version Number
int 21h ; sets bx=0, cx=0
xchg ah,al ; original order is major:al minor:ah
pop cx
pop bx
ret ; major:ah minor:al
DOSVer endp
_TEXT ends
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?