Copyright © Microsoft Corporation. This document is an archived reproduction of a version originally published by Microsoft. It may have slight formatting modifications for consistency and to improve readability. |
Code | Definition |
00 | Divide error |
01 | Debug exception (single-step and hardware debugging) |
02 | NMI interrupt |
03 | Breakpoint |
04 | INTO detected overflow |
05 | BOUND range exceeded |
06 | Invalid opcode |
07 | Coprocessor device not available |
08 | Double fault |
0A | Invalid Task State Segment (TSS) |
0B | Segment not present |
0C | Stack fault |
0D | General protection fault (GPF) |
0E | Page fault |
Figure 4 SoftIce IDT Output
Int | Type | Sel:Offset | Attributes | Symbol/Owner | |
IDTbase=80036400 Limit=07FF | |||||
0000 | IntG32 | 0008:8013C354 | DPL=0 | P | _KiTrap00 |
0001 | IntG32 | 0008:8013C49C | DPL=3 | P | _KiTrap01 |
0002 | IntG32 | 0008:0000137E | DPL=0 | P | |
0003 | IntG32 | 0008:8013C764 | DPL=3 | P | _KiTrap03 |
0004 | IntG32 | 0008:8013C8B8 | DPL=3 | P | _KiTrap04 |
0005 | IntG32 | 0008:8013C9F4 | DPL=0 | P | _KiTrap05 |
0006 | IntG32 | 0008:8013CB4C | DPL=0 | P | _KiTrap06 |
0007 | IntG32 | 0008:8013D068 | DPL=0 | P | _KiTrap07 |
0008 | TaskG | 0050:000013D8 | DPL=0 | P | |
0009 | IntG32 | 0008:8013D3A8 | DPL=0 | P | _KiTrap09 |
000A | IntG32 | 0008:8013D4A8 | DPL=0 | P | _KiTrap0A |
000B | IntG32 | 0008:8013D5CC | DPL=0 | P | _KiTrap0B |
000C | IntG32 | 0008:8013D8BC | DPL=0 | P | _KiTrap0C |
000D | IntG32 | 0008:8013DABC | DPL=0 | P | _KiTrap0D |
000E | IntG32 | 0008:8013E468 | DPL=0 | P | _KiTrap0E |
000F | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0010 | IntG32 | 0008:8013E8D4 | DPL=0 | P | _KiTrap10 |
0011 | IntG32 | 0008:8013E9E8 | DPL=0 | P | _KiTrap11 |
0012 | TaskG | 00A0:8013E7D4 | DPL=0 | P | |
0013 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0014 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0015 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0016 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0017 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0018 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0019 | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001A | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001B | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001C | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001D | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001E | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
001F | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
0020 | Reserved | 0008:00000000 | DPL=0 | NP | |
0021 | TrapG16 | 00C7:00000696 | DPL=3 | P | |
0022 | Reserved | 0008:00000000 | DPL=0 | NP | |
0023 | Reserved | 0008:00000000 | DPL=0 | NP | |
0024 | Reserved | 0008:00000000 | DPL=0 | NP | |
0025 | Reserved | 0008:00000000 | DPL=0 | NP | |
0026 | Reserved | 0008:00000000 | DPL=0 | NP | |
0027 | Reserved | 0008:00000000 | DPL=0 | NP | |
0028 | Reserved | 0008:00000000 | DPL=0 | NP | |
0029 | Reserved | 0008:00000000 | DPL=0 | NP | |
002A | IntG32 | 0008:8013B8A6 | DPL=3 | P | _KiGetTickCount |
002B | IntG32 | 0008:8013B990 | DPL=3 | P | _KiCallbackReturn |
002C | IntG32 | 0008:8013BAA0 | DPL=3 | P | _KiSetLowWaitHighThread |
002D | IntG32 | 0008:8013C65C | DPL=3 | P | _KiDebugService |
002E | IntG32 | 0008:8013B440 | DPL=3 | P | _KiSystemService |
002F | IntG32 | 0008:8013E7D4 | DPL=0 | P | _KiTrap0F |
Figure 5 GenException.CPP
//========================================== // Matt Pietrek // Microsoft Systems Journal, October 1997 // FILE: GenException.CPP // To compile: CL GenException.CPP //========================================== #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <float.h> #include <assert.h> typedef void (* PFNGENERATEEXCEPTION)(void); void GenerateSTATUS_BREAKPOINT( void ) { __asm int 3 // A regular, old breakpoint instruction } void GenerateSTATUS_SINGLE_STEP( void ) { // This is easier than using the hardware // breakpoint register to create an int 1 __asm int 1 } void GenerateSTATUS_ACCESS_VIOLATION( void ) { // Create a page fault (exception 0xE) by reading // from memory above 2GB. int i = *(int *)0xFFFFFFF0; } void GenerateSTATUS_ILLEGAL_INSTRUCTION( void ) { __asm _emit 0x0F // Garbage instruction causes an exception 0xD __asm _emit 0xFF } void GenerateSTATUS_ARRAY_BOUNDS_EXCEEDED( void ) { DWORD arrayBounds[2] = { 10, 48 }; __asm mov eax, 12 __asm bound eax, arrayBounds // This BOUND instruction works __asm mov eax, 7 __asm bound eax, arrayBounds // This makes an exception 5 } void UnmaskFPExceptionBits( void ) { unsigned short cw; __asm fninit // Initialize the coprocessor __asm fstcw [cw] cw &= 0xFFE0; // Turn off the most of the exception bits (except the // the precision exception) __asm fldcw [cw] } void GenerateSTATUS_FLOAT_DIVIDE_BY_ZERO( void ) { double a = 0; a = 1 / a; __asm fwait; } void GenerateSTATUS_FLOAT_OVERFLOW( void ) { double a = DBL_MAX; a *= a; __asm fwait; } void GenerateSTATUS_FLOAT_STACK_CHECK( void ) { unsigned a; __asm fistp [a] __asm fwait; } void GenerateSTATUS_FLOAT_UNDERFLOW( void ) { double a = DBL_MIN; a /= 10; __asm fwait; } void GenerateSTATUS_INTEGER_DIVIDE_BY_ZERO( void ) { // Divide by zero to cause an exception 0 int i = 0; i = 2 / i; } void GenerateSTATUS_INTEGER_OVERFLOW( void ) { __asm mov eax, 07FFFFFFFh // Signed max value __asm add eax, 2 // result = 0x80000001 -> overflow! __asm into // Makes an exception 4 } void GenerateSTATUS_PRIVILEGED_INSTRUCTION( void ) { // The HLT instruction can only be executed at ring 0 __asm hlt } void GenerateSTATUS_STACK_OVERFLOW( void ) { DWORD myArray[512]; // Recurse "infinitely" to overflow the stack GenerateSTATUS_STACK_OVERFLOW(); } DWORD GetExceptionNumber( PFNGENERATEEXCEPTION pfn ) { DWORD exceptionCode = 0; __try { pfn(); } __except( exceptionCode = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER ) { } return exceptionCode; } #define SHOW_EXCEPTION( x ) \ dwExceptionNumber = GetExceptionNumber( Generate##x ); \ printf( "%X %s\n", dwExceptionNumber, #x ); \ assert( dwExceptionNumber == x ); int main(int argc, char *argv[]) { DWORD dwExceptionNumber; SHOW_EXCEPTION( STATUS_BREAKPOINT ) SHOW_EXCEPTION( STATUS_SINGLE_STEP ) SHOW_EXCEPTION( STATUS_ACCESS_VIOLATION ) SHOW_EXCEPTION( STATUS_ILLEGAL_INSTRUCTION ) SHOW_EXCEPTION( STATUS_ARRAY_BOUNDS_EXCEEDED ) UnmaskFPExceptionBits(); SHOW_EXCEPTION( STATUS_FLOAT_DIVIDE_BY_ZERO ) UnmaskFPExceptionBits(); SHOW_EXCEPTION( STATUS_FLOAT_OVERFLOW ) UnmaskFPExceptionBits(); SHOW_EXCEPTION( STATUS_FLOAT_STACK_CHECK ) UnmaskFPExceptionBits(); SHOW_EXCEPTION( STATUS_FLOAT_UNDERFLOW ) SHOW_EXCEPTION( STATUS_INTEGER_DIVIDE_BY_ZERO ) SHOW_EXCEPTION( STATUS_INTEGER_OVERFLOW ) SHOW_EXCEPTION( STATUS_PRIVILEGED_INSTRUCTION ) SHOW_EXCEPTION( STATUS_STACK_OVERFLOW ); return 0; }