home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_48.arc / TRAP.ARC / TRAP.ASM < prev   
Assembly Source File  |  1989-05-16  |  7KB  |  274 lines

  1. ;Support code from Micro Cornucopia Magazine Issue #48
  2.  
  3. ;Micro Cornucopia
  4. ;PO Box 223
  5. ;Bend, OR 97709
  6.  
  7.  
  8. ;************************************************************************
  9. ;** 4/17/89 *    TRAP.ASM    *   Version 0.00            *
  10. ;************************************************************************
  11. ;*                                    *
  12. ;*  Invalid Opcode, Divide by 0, and attempt to execute at 0:0 Trap    *
  13. ;*                                    *
  14. ;************************************************************************
  15. ;* Copyright (c) 1989, PC Tech, Inc.   All Rights Reserved        *
  16. ;* Permission granted for use, but not for sale.            *
  17. ;*                                    *    
  18. ;* PC Tech            tel: 612-345-4555            *
  19. ;* 907 North 6th St.        fax: 612-345-5514            *
  20. ;* Lake City, MN 55041                            *
  21. ;*                        written by Laine Stump    *    
  22. ;************************************************************************
  23. ;*                                    *
  24. ;* TRAP is a TSR (Terminate Stay Resident) program that traps out all    *
  25. ;* Invalid Opcode Exception interrupts and Divide by 0 interrupts,    *
  26. ;* then displays a stack dump, register dump, and dump of the code at     *
  27. ;* the point that caused the bad interrupt.                *
  28. ;*                                    *
  29. ;************************************************************************
  30. ;*    assemble with MASM 5.1, LINK, and EXE2BIN (use MAKE.BAT)    *
  31. ;************************************************************************
  32. ReportToPrinter    equ 0    ;0 to screen, 1 to LPT1:
  33.  
  34.     .186
  35.     .MODEL    SMALL,C
  36.  
  37. CODE    segment PUBLIC 'CODE'
  38.     assume    cs:code
  39. FIRSTBYTE    equ    this byte ;between here & LASTBYTE remains res.
  40.  
  41.     ORG    100h
  42. START:    JMP    MAIN    ;init code is at end so we can get rid of it.
  43.  
  44.  INCLUDE ROMCALLS.INC
  45.  INCLUDE DOSCALLS.INC
  46.  INCLUDE SUBROUTS.ASM
  47.  
  48. ;***************************************************************************
  49. ; Trap for Invalid Opcodes - also checks for attempt to execute at 0:0
  50. ;
  51. InvOpTrap:
  52.   pusha
  53.   mov    bp, sp
  54.   push    ds
  55.   push    es
  56.   mov    es, PALL_CS[bp]
  57.   mov    di, PALL_IP[bp]
  58.   mov    ax, es    ;check for attempt to execute at 0:0
  59.   or    ax, di
  60.   jnz    @f
  61.  
  62.   ;an attempt was made to execute at 0:0
  63.   call    IP_StringOut
  64.   db "Attempt to Execute at 0:0 Exception",cr,lf,0
  65.   jmp    short CI_10
  66.  
  67. @@: ;normal invalid opcode
  68.   call    IP_StringOut
  69.   db "Illegal OpCode Exception",cr,lf,0
  70. ;*  jmp    CRASHIT
  71.  
  72. CRASHIT: ;print exception, then do int 3 (Debugger Breakpoint)
  73. ; enter with message to print in cs:si, interrupt # in DX,
  74. ; exception address in es:di
  75.  
  76.   mov    ax,es
  77.   call    HexWord
  78.   mov    al,':'
  79.   call    Putc
  80.   mov    ax,di
  81.   call    HexWord
  82.   call    Space
  83.   call    Space
  84.   sub    bx, bx
  85.   mov    cx, 8
  86. @@:
  87.   mov    al, es:[di+bx]    ;dump opcodes bytes at CS:IP
  88.   call    HexByte
  89.   call    Space
  90.   inc    bx
  91.   loop    @b
  92.   call    CRLF
  93. CI_10:
  94.   call    DumpRegs    ;dump registers at time of exception
  95.   call    DumpStack    ;stack at time of exception
  96.   RomCall    Keyboard, GetKey
  97.   pop    es
  98.   pop    ds
  99.   popa
  100.   int    3        ;break out to debugger (if running)
  101.  
  102. ;***************************************************************************
  103. ;    DIVIDE BY 0 EXCEPTION HANDLER
  104. ;
  105. ;  The divide by 0 exception handler is org'ed at a special
  106. ;  address so that an attempt to execute at 0:0 (where the divide
  107. ;  by 0 exception vector is stored) will cuase an easily identifiable
  108. ;  exception.
  109. ;
  110. ;  this was done because a program running wild very often ends up
  111. ;  at location 0:0. This can happen because of a jump or call indirect
  112. ;  through an uninitialized long pointer, or (very commonly) by executing
  113. ;  an INT xx for an interrupt whose vector has not been initialized (and 
  114. ;  is therefore 0:0.
  115. ;
  116. ;  Remember that DOS's COMMAND.COM sets its own Divide by 0 interrupt, so
  117. ;  if you install this one from ROM before DOS boots, it will be 
  118. ;  overwritten. The runtime libraries of many languages also set up their
  119. ;  own Divide by 0 interrupt. This means that if you want to catch this
  120. ;  kind of bug (attempt to execute at 0), you must be very careful about
  121. ;  when you initialize the vector, and what programs you run.
  122. ;
  123. ;  Even though the actual exception for an attempt to execute at 
  124. ;  0:0 will be for an Invalid Opcode exception, the Invalid Opcode exception
  125. ;  handler differentiates it by noticing that CS:IP is 0:0 when the
  126. ;  exception occurs
  127. ;
  128. ORG    266h    ;assure the byte at 0:0 is 66h (an invalid instruction)
  129.         ;so it will cause an INT 6. Watch out that this doesn't
  130. Div0Trap:    ;cause earlier code to be overwritten!!!!
  131.   pusha
  132.   mov    bp, sp
  133.   push    ds
  134.   push    es
  135.   mov    es, PALL_CS[bp]
  136.   mov    di, PALL_IP[bp]
  137.   call    IP_StringOut
  138.   db    "Divide by 0 Exception",cr,lf,0
  139.   jmp    CRASHIT
  140.  
  141. ;***************************************************************************
  142. ;
  143. ;  Display a dump of registers as they were at time exception occurred
  144. ;
  145. DumpRegs:
  146.   call    IP_StringOut
  147.   db " AX   BX   CX   DX    DI   SI    BP   SP"
  148.   db "    CS   DS   ES   SS    IP  Flag",cr,lf,0
  149.   mov    ax,pall_ax[bp]
  150.   call    HexWord
  151.   call    Space
  152.   mov    ax,pall_bx[bp]
  153.   call    HexWord
  154.   call    Space
  155.   mov    ax,pall_cx[bp]
  156.   call    HexWord
  157.   call    Space
  158.   mov    ax,pall_dx[bp]
  159.   call    HexWord
  160.   call    Space
  161.   call    Space
  162.   mov    ax,pall_di[bp]
  163.   call    HexWord
  164.   call    Space
  165.   mov    ax,pall_si[bp]
  166.   call    HexWord
  167.   call    Space
  168.   call    Space
  169.   mov    ax,pall_bp[bp]
  170.   call    HexWord
  171.   call    Space
  172.   lea    ax, PALL_FLAGS[bp+2]    ;this is value before INT
  173. ;*  mov    ax,pall_sp[bp]        ;this is junk value in middle of PUSHA
  174.   call    HexWord
  175.   call    Space
  176.   call    Space
  177.   mov    ax,pall_cs[bp]
  178.   call    HexWord
  179.   call    Space
  180.   mov    ax,pall_ds[bp]
  181.   call    HexWord
  182.   call    Space
  183.   mov    ax,pall_es[bp]
  184.   call    HexWord
  185.   call    Space
  186.   mov    ax,ss
  187.   call    HexWord
  188.   call    Space
  189.   call    Space
  190.   mov    ax,pall_ip[bp]
  191.   call    HexWord
  192.   call    Space
  193.   mov    ax,pall_flags[bp]
  194.   call    HexWord
  195.   call    Space
  196.   call    CRLF
  197.   ret
  198.  
  199. ;***************************************************************************
  200. ;
  201. ;  Display a dump of the stack as it was when exception occurred
  202. ;
  203.  
  204. DumpStack:
  205.   call    IP_StringOut
  206.     db "Stack Dump: ",cr,lf,0
  207.   lea    si, PALL_FLAGS[bp+2]
  208.   mov    cx, 8
  209. DST_00:
  210.   push    cx
  211.   mov    ax,ss
  212.   call    HexWord
  213.   mov    al,':'
  214.   call    Putc
  215.   mov    ax,si
  216.   call    HexWord
  217.   call    Space
  218.   mov    cx, 8
  219. @@:
  220.  
  221.   mov    ax,ss:[si]
  222.   call    HexWord
  223.   call    Space
  224.   add    si,2
  225.   loop    @b
  226.   call    CRLF
  227.   pop    cx
  228.   loop    DST_00
  229.   ret
  230.  
  231. ;******************************************
  232.  
  233. LASTBYTE    equ    this byte
  234. ;
  235. ;  Below this point is used only during initialization, then discarded.
  236. ;
  237. IntInfo    STRUC
  238.   IntNo        DB    ?
  239.   IntVector    DW    ?
  240. IntInfo    ENDS
  241. ;
  242. ;  table of new interrupt vectors to install
  243.  
  244. NewIntTable \
  245.   IntInfo    <0,Div0Trap>
  246.   IntInfo    <6,InvOpTrap>    ;Intel Invalid Opcode exception
  247.   IntInfo    <0,0>        ;END OF TABLE
  248. ;************************************************************************
  249.  
  250.     assume    ds:code
  251.  
  252. MAIN    PROC NEAR
  253.     call    IP_StringOut
  254.     DB 'PC Tech Invalid Opcode & Divide by 0 Exception Trap',CR,LF
  255.     DB '    Copyright (c) 1989, PC Tech, Inc.',CR,LF,0
  256.     SUB    SI,SI
  257. MAINLOOP:
  258.         MOV    AL,NewIntTable[si].IntNo
  259.         MOV    DX,NewIntTable[si].IntVector
  260.         OR    DX,DX
  261.         JZ    DONE
  262.     DOS    SET_VECTOR
  263.     ADD    SI, size IntInfo
  264.     JMP    MAINLOOP
  265.  
  266. DONE:    MOV    PrinterFlag, ReportToPrinter
  267.     MOV     DX,(LASTBYTE-FIRSTBYTE+15)/16
  268.     MOV    AL,0
  269.     DOS    KEEP_PROCESS
  270. MAIN    ENDP
  271.  
  272. CODE    ends
  273.     end     START
  274.