home *** CD-ROM | disk | FTP | other *** search
- ;Support code from Micro Cornucopia Magazine Issue #48
-
- ;Micro Cornucopia
- ;PO Box 223
- ;Bend, OR 97709
-
-
- ;************************************************************************
- ;** 4/17/89 * TRAP.ASM * Version 0.00 *
- ;************************************************************************
- ;* *
- ;* Invalid Opcode, Divide by 0, and attempt to execute at 0:0 Trap *
- ;* *
- ;************************************************************************
- ;* Copyright (c) 1989, PC Tech, Inc. All Rights Reserved *
- ;* Permission granted for use, but not for sale. *
- ;* *
- ;* PC Tech tel: 612-345-4555 *
- ;* 907 North 6th St. fax: 612-345-5514 *
- ;* Lake City, MN 55041 *
- ;* written by Laine Stump *
- ;************************************************************************
- ;* *
- ;* TRAP is a TSR (Terminate Stay Resident) program that traps out all *
- ;* Invalid Opcode Exception interrupts and Divide by 0 interrupts, *
- ;* then displays a stack dump, register dump, and dump of the code at *
- ;* the point that caused the bad interrupt. *
- ;* *
- ;************************************************************************
- ;* assemble with MASM 5.1, LINK, and EXE2BIN (use MAKE.BAT) *
- ;************************************************************************
- ReportToPrinter equ 0 ;0 to screen, 1 to LPT1:
-
- .186
- .MODEL SMALL,C
-
- CODE segment PUBLIC 'CODE'
- assume cs:code
- FIRSTBYTE equ this byte ;between here & LASTBYTE remains res.
-
- ORG 100h
- START: JMP MAIN ;init code is at end so we can get rid of it.
-
- INCLUDE ROMCALLS.INC
- INCLUDE DOSCALLS.INC
- INCLUDE SUBROUTS.ASM
-
- ;***************************************************************************
- ; Trap for Invalid Opcodes - also checks for attempt to execute at 0:0
- ;
- InvOpTrap:
- pusha
- mov bp, sp
- push ds
- push es
- mov es, PALL_CS[bp]
- mov di, PALL_IP[bp]
- mov ax, es ;check for attempt to execute at 0:0
- or ax, di
- jnz @f
-
- ;an attempt was made to execute at 0:0
- call IP_StringOut
- db "Attempt to Execute at 0:0 Exception",cr,lf,0
- jmp short CI_10
-
- @@: ;normal invalid opcode
- call IP_StringOut
- db "Illegal OpCode Exception",cr,lf,0
- ;* jmp CRASHIT
-
- CRASHIT: ;print exception, then do int 3 (Debugger Breakpoint)
- ; enter with message to print in cs:si, interrupt # in DX,
- ; exception address in es:di
-
- mov ax,es
- call HexWord
- mov al,':'
- call Putc
- mov ax,di
- call HexWord
- call Space
- call Space
- sub bx, bx
- mov cx, 8
- @@:
- mov al, es:[di+bx] ;dump opcodes bytes at CS:IP
- call HexByte
- call Space
- inc bx
- loop @b
- call CRLF
- CI_10:
- call DumpRegs ;dump registers at time of exception
- call DumpStack ;stack at time of exception
- RomCall Keyboard, GetKey
- pop es
- pop ds
- popa
- int 3 ;break out to debugger (if running)
-
- ;***************************************************************************
- ; DIVIDE BY 0 EXCEPTION HANDLER
- ;
- ; The divide by 0 exception handler is org'ed at a special
- ; address so that an attempt to execute at 0:0 (where the divide
- ; by 0 exception vector is stored) will cuase an easily identifiable
- ; exception.
- ;
- ; this was done because a program running wild very often ends up
- ; at location 0:0. This can happen because of a jump or call indirect
- ; through an uninitialized long pointer, or (very commonly) by executing
- ; an INT xx for an interrupt whose vector has not been initialized (and
- ; is therefore 0:0.
- ;
- ; Remember that DOS's COMMAND.COM sets its own Divide by 0 interrupt, so
- ; if you install this one from ROM before DOS boots, it will be
- ; overwritten. The runtime libraries of many languages also set up their
- ; own Divide by 0 interrupt. This means that if you want to catch this
- ; kind of bug (attempt to execute at 0), you must be very careful about
- ; when you initialize the vector, and what programs you run.
- ;
- ; Even though the actual exception for an attempt to execute at
- ; 0:0 will be for an Invalid Opcode exception, the Invalid Opcode exception
- ; handler differentiates it by noticing that CS:IP is 0:0 when the
- ; exception occurs
- ;
- ORG 266h ;assure the byte at 0:0 is 66h (an invalid instruction)
- ;so it will cause an INT 6. Watch out that this doesn't
- Div0Trap: ;cause earlier code to be overwritten!!!!
- pusha
- mov bp, sp
- push ds
- push es
- mov es, PALL_CS[bp]
- mov di, PALL_IP[bp]
- call IP_StringOut
- db "Divide by 0 Exception",cr,lf,0
- jmp CRASHIT
-
- ;***************************************************************************
- ;
- ; Display a dump of registers as they were at time exception occurred
- ;
- DumpRegs:
- call IP_StringOut
- db " AX BX CX DX DI SI BP SP"
- db " CS DS ES SS IP Flag",cr,lf,0
- mov ax,pall_ax[bp]
- call HexWord
- call Space
- mov ax,pall_bx[bp]
- call HexWord
- call Space
- mov ax,pall_cx[bp]
- call HexWord
- call Space
- mov ax,pall_dx[bp]
- call HexWord
- call Space
- call Space
- mov ax,pall_di[bp]
- call HexWord
- call Space
- mov ax,pall_si[bp]
- call HexWord
- call Space
- call Space
- mov ax,pall_bp[bp]
- call HexWord
- call Space
- lea ax, PALL_FLAGS[bp+2] ;this is value before INT
- ;* mov ax,pall_sp[bp] ;this is junk value in middle of PUSHA
- call HexWord
- call Space
- call Space
- mov ax,pall_cs[bp]
- call HexWord
- call Space
- mov ax,pall_ds[bp]
- call HexWord
- call Space
- mov ax,pall_es[bp]
- call HexWord
- call Space
- mov ax,ss
- call HexWord
- call Space
- call Space
- mov ax,pall_ip[bp]
- call HexWord
- call Space
- mov ax,pall_flags[bp]
- call HexWord
- call Space
- call CRLF
- ret
-
- ;***************************************************************************
- ;
- ; Display a dump of the stack as it was when exception occurred
- ;
-
- DumpStack:
- call IP_StringOut
- db "Stack Dump: ",cr,lf,0
- lea si, PALL_FLAGS[bp+2]
- mov cx, 8
- DST_00:
- push cx
- mov ax,ss
- call HexWord
- mov al,':'
- call Putc
- mov ax,si
- call HexWord
- call Space
- mov cx, 8
- @@:
-
- mov ax,ss:[si]
- call HexWord
- call Space
- add si,2
- loop @b
- call CRLF
- pop cx
- loop DST_00
- ret
-
- ;******************************************
-
- LASTBYTE equ this byte
- ;
- ; Below this point is used only during initialization, then discarded.
- ;
- IntInfo STRUC
- IntNo DB ?
- IntVector DW ?
- IntInfo ENDS
- ;
- ; table of new interrupt vectors to install
-
- NewIntTable \
- IntInfo <0,Div0Trap>
- IntInfo <6,InvOpTrap> ;Intel Invalid Opcode exception
- IntInfo <0,0> ;END OF TABLE
- ;************************************************************************
-
- assume ds:code
-
- MAIN PROC NEAR
- call IP_StringOut
- DB 'PC Tech Invalid Opcode & Divide by 0 Exception Trap',CR,LF
- DB ' Copyright (c) 1989, PC Tech, Inc.',CR,LF,0
- SUB SI,SI
- MAINLOOP:
- MOV AL,NewIntTable[si].IntNo
- MOV DX,NewIntTable[si].IntVector
- OR DX,DX
- JZ DONE
- DOS SET_VECTOR
- ADD SI, size IntInfo
- JMP MAINLOOP
-
- DONE: MOV PrinterFlag, ReportToPrinter
- MOV DX,(LASTBYTE-FIRSTBYTE+15)/16
- MOV AL,0
- DOS KEEP_PROCESS
- MAIN ENDP
-
- CODE ends
- end START