;This file was written by vkim
;vkim@aport2000.ru

;_____________________________________________________________________
; PrintNum, PrintDword, & _except_handler have been modified by Ewayne
; PrintDec, PrintHex, PrintBin, & PrintDHB have been added by Ewayne
;_____________________________________________________________________


;-----------------------------------------------------------------------------

DebugPrint proto :DWORD, :DWORD

DB_NUM  equ 1  ;Message is number
DB_TEXT equ 2  ;Message is string

;_______________________________________________________________
FillString macro Arr, Text
    push ecx
    xor ecx, ecx
    forc var, <&Text>
        mov Arr[ecx], '&var'
        inc ecx
    endm
    mov Arr[ecx], 0
    pop ecx
endm

;-----------------------------------------------------------------------------

;PrintString szString        ;
;PrintStringByAddr hString   ;--> This is a text by address stored in hString
;PrintText "This is a text"  ;--> This is a text ;Length of the text cannot be more then 256 chars
;PrintNum 100                ;--> 100
;PrintHex   eax              ;--> eax = 4d2h
;PrintDword eax              ;--> eax = 80

;_______________________________________________________________
PrintString macro Var
    local hMem, pMem, szDebugBuff
    pushad
    .data
    hMem dword 0
    pMem dword 0
    szDebugBuff byte 256 dup(0)
    .code
    invoke lstrlen, addr Var
    add eax, 10
    invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, eax
    mov hMem, eax
    invoke GlobalLock, hMem
    mov pMem, eax
    FillString szDebugBuff, &Var
    invoke lstrlen, addr szDebugBuff
    mov byte ptr szDebugBuff[eax], " "
    mov byte ptr szDebugBuff[eax+1], "="
    mov byte ptr szDebugBuff[eax+2], " "
    mov byte ptr szDebugBuff[eax+3], 0
    invoke lstrcpy, pMem, addr szDebugBuff
    invoke lstrcat, pMem, addr Var
    invoke DebugPrint, pMem, DB_TEXT
    invoke GlobalUnlock, hMem
    invoke GlobalFree, hMem
   PrintLine
    popad
endm

;_______________________________________________________________
PrintStringByAddr macro Var
    local szDebugBuff, hMem, pMem
    pushad
    push Var
    .data
    hMem dword 0
    pMem dword 0
    szDebugBuff byte 256 dup(0)
    .code
    invoke lstrlen, Var
    add eax, 10
    invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, eax
    mov hMem, eax
    invoke GlobalLock, hMem
    mov pMem, eax
    FillString szDebugBuff, &Var
    invoke lstrlen, addr szDebugBuff
    mov byte ptr szDebugBuff[eax], " "
    mov byte ptr szDebugBuff[eax+1], "="
    mov byte ptr szDebugBuff[eax+2], " "
    mov byte ptr szDebugBuff[eax+3], 0
    invoke lstrcpy, pMem, addr szDebugBuff
    pop eax
    invoke lstrcat, pMem, eax
    invoke DebugPrint, pMem, DB_TEXT
    invoke GlobalUnlock, hMem
    invoke GlobalFree, hMem
   PrintLine
    popad
endm

;_______________________________________________________________
PrintText macro Var
    local szDebugBuff
    pushad
    .data
    szDebugBuff byte 256 dup(0)
    .code
    FillString szDebugBuff, &Var
    invoke lstrlen, addr szDebugBuff
    mov edx, eax
    dec edx 
    mov eax, offset szDebugBuff
    inc eax
    invoke lstrcpyn, addr szDebugBuff, eax, edx
    invoke DebugPrint, addr szDebugBuff, DB_TEXT
   PrintLine
    popad
endm

;_______________________________________________________________
PrintNum macro Var
LOCAL    szDebugBuff
      pushad
.data
szDebugBuff db 256 dup(0)
.code
  FillString     szDebugBuff, &Var
      INVOKE     lstrlen, addr szDebugBuff
         mov     edx, eax
         mov     eax, offset szDebugBuff
         inc     edx
      INVOKE     lstrcpyn, addr szDebugBuff, eax, edx
      INVOKE     DebugPrint, addr szDebugBuff, DB_NUM
   PrintLine
       popad
endm

;_______________________________________________________________
PrintDec macro Var
LOCAL    Base
      pushad
.data
Base       dd  10
.code
    PrintDHB     Var, Base
       popad
endm

;_______________________________________________________________
PrintHex macro Var
LOCAL    Base
      pushad
.data
Base       dd  16
.code
    PrintDHB     Var, Base
       popad
endm

;_______________________________________________________________
PrintBin macro Var
LOCAL    Base
      pushad
.data
Base       dd  2
.code
    PrintDHB     Var, Base
       popad
endm

;_______________________________________________________________
PrintDHB macro Var, Base
LOCAL    szDebugBuff, szDebugNum, LBuff
LOCAL    Save, sgn, SavNeg, Input, szFill
LOCAL    Display

      pushad
        push     Var

.data
szDebugBuff db  256 dup(0)
szDebugNum  db  20 dup(0)
LBuff       db  32 dup(0)
Save        dd  0
SavNeg      dd  0
sgn         dd  0
Input       dd  0
szFill      db  9  dup('0'), 0
Display     db  33 dup(' '), 0

.code
  FillString     szDebugBuff, &Var
      INVOKE     lstrlen, addr szDebugBuff
         mov     byte ptr szDebugBuff[eax], " "
         mov     byte ptr szDebugBuff[eax+1], "="
         mov     byte ptr szDebugBuff[eax+2], " "
         mov     byte ptr szDebugBuff[eax+3], 0
      .if Base == 16
         INVOKE     lstrcpy, addr Display, addr szFill
      .endif
         pop     Var
         mov     sgn, 0
         mov     eax, Var
         mov     Save, eax
         mov     Input, eax
         mov     SavNeg, eax
      .if sdword ptr eax < 0 && Base != 16            ; Check for negative number
            neg     eax                 ; and invert the value
            mov     sgn, 1
            mov     SavNeg, eax
      .endif

         mov     edi, offset Display
         xor     esi, esi
         mov     eax, Var ;Input           ; Input
      .while (eax)
            xor     edx, edx
            div     Base              ; Base 10, 16, 8, 2
         .if dl > 9h
               add     dl, 37h        ; Convert to hex ASCII
         .else
               add     dl, 30h        ; Convert to dec ASCII
         .endif
            mov     LBuff[esi], dl
            inc     esi
      .endw
         mov     ecx, esi
      .if sgn == 1
            mov     byte ptr[edi], 2dh
            inc     edi
      .endif
      .if Base == 16
            add     edi, 8
            sub     edi, ecx
      .endif
         inc     ecx
      .if ecx == 1 && Base == 10
            mov     LBuff[esi-1], 30h
            inc     ecx
            inc     edi
      .endif
      .while (ecx)
            mov     al, byte ptr LBuff[esi-1]
            mov     byte ptr[edi], al
            inc     edi
            dec     esi
            dec     ecx
      .endw
            mov     byte ptr[edi-1], 0

      INVOKE     lstrcat, addr szDebugBuff, addr Display
      INVOKE     DebugPrint, addr szDebugBuff, DB_TEXT
   PrintLine
       popad
endm

;_______________________________________________________________
PrintDword macro Var
LOCAL    szDebugBuff, szDebugNum, Loop3, LBuff
LOCAL    Base, Save, sgn, cnt, SavNeg, Input
LOCAL    Display, szDec, szHex, szAct, szHexa, szBin

      pushad
        push     Var

.data
szDebugBuff db  256 dup(0)
szDebugNum  db  20 dup(0)
LBuff       db  32 dup(0)
Base        dd  0
Save        dd  0
SavNeg      dd  0
sgn         dd  0
cnt         dd  0
Input       dd  0

Display     db  0dh,0ah
            db  'Dec.  '
szDec       db  11 dup(' ')
            db  0dh,0ah
            db  'Hex.  '
szHex       db  9  dup('0')
szAct       db  '  Actual Value '
szHexa      db  9  dup(' ')
            db  0dh,0ah
            db  'Bin.  '
szBin       db  32 dup(' '), 0

.code
  FillString     szDebugBuff, &Var
      INVOKE     lstrlen, addr szDebugBuff
         mov     byte ptr szDebugBuff[eax], " "
         mov     byte ptr szDebugBuff[eax+1], "="
         mov     byte ptr szDebugBuff[eax+2], " "
         mov     byte ptr szDebugBuff[eax+3], 0

         pop     Var
         mov     sgn, 0
         mov     eax, Var
         mov     Save, eax
         mov     Input, eax
         mov     SavNeg, eax
      .if sdword ptr eax < 0 ;&& Base == 10            ; Check for negative number
            neg     eax                 ; and invert the value
            mov     sgn, 1
            mov     SavNeg, eax
      .endif

      .if sgn == 0
            mov     ecx, 14
            mov     edi, offset szAct
         .while (ecx)
               mov     byte ptr[edi], 20h
               inc     edi
               dec     ecx
         .endw
      .endif
         mov     cnt, 0
         mov     Base, 10
         mov     edi, offset szDec

Loop3:
         xor     esi, esi
         mov     eax, Var ;Input           ; Input
      .while (eax)
            xor     edx, edx
            div     Base              ; Base 10, 16, 8, 2
         .if dl > 9h
               add     dl, 37h        ; Convert to hex ASCII
         .else
               add     dl, 30h        ; Convert to dec ASCII
         .endif
            mov     LBuff[esi], dl
            inc     esi
      .endw
         mov     ecx, esi
      .if sgn == 1
            mov     byte ptr[edi], 2dh
            inc     edi
      .endif
      .if cnt == 1
            add     edi, 8
            sub     edi, ecx
      .endif
         inc     ecx
      .if ecx == 1 && Base == 10
            mov     LBuff[esi-1], 30h
            inc     ecx
            inc     edi
      .endif
      .while (ecx)
            mov     al, byte ptr LBuff[esi-1]
            mov     byte ptr[edi], al
            inc     edi
            dec     esi
            dec     ecx
      .endw
            mov     byte ptr[edi-1], 20h
            add     cnt, 1
      .if cnt == 1
            mov     eax, SavNeg
;            mov     Input, eax
            mov     Var, eax
            mov     edi, offset szHex
            mov     Base, 16
            jmp     Loop3
      .elseif cnt == 2
            mov     eax, SavNeg
;            mov     Input, eax
            mov     Var, eax
            mov     edi, offset szBin
            mov     Base, 2
            jmp     Loop3
      .elseif cnt == 3
            mov     byte ptr[edi-1], 0
      .endif
      .if cnt == 3 && sgn == 1
            and     sgn, 0
            mov     eax, Save
;            mov     Input, eax
            mov     Var, eax
            mov     edi, offset szHexa
            mov     Base, 16
            jmp     Loop3
      .endif

      INVOKE     lstrcat, addr szDebugBuff, addr Display
      INVOKE     DebugPrint, addr szDebugBuff, DB_TEXT
   PrintLine
       popad
endm

;_______________________________________________________________
PrintRegs macro
LOCAL    szDebugBuff, szDebugNum, LoopIt, LBuff
LOCAL    Base, Save, sgn, cnt, sw1
LOCAL    szREGS, szEAX, szEBX, szECX, szEDX, szESI, szEDI, szEBP, szESP, szFLG, szFLGB, RegArray, SavFlg
      pushad
      pushfd

.data
szDebugBuff db 256 dup(0)
szDebugNum  db 20 dup(0)
LBuff       db 32 dup(0)
Base        dd 0
Save        dd 0
sw1         dd 0
sgn         dd 0
cnt         dd 0

szREGS      db  '      - Hex. -    - Dec. -'
            db  0Dh,0Ah
szEAX       db  'EAX = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szEBX       db  'EBX = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szECX       db  'ECX = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szEDX       db  'EDX = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szESI       db  'ESI = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szEDI       db  'EDI = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szEBP       db  'EBP = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szESP       db  'ESP = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
szFLG       db  'FLG = '
            db  9 dup('0')
            db  13 dup(' ')
            db  0Dh,0Ah
            db  'EFLAG Bin. =   '
szFLGB      db  32 dup(' '), 0
RegArray    dd  9 dup(0)
SavFlg      dd  0

.code
pop     SavFlg
         mov     RegArray, eax
         mov     RegArray+4, ebx
         mov     RegArray+8, ecx
         mov     RegArray+12, edx
         mov     RegArray+16, esi
         mov     RegArray+20, edi
         mov     RegArray+24, ebp
         mov     RegArray+28, esp
;      pushfd
;         pop     RegArray+32
mov     eax, SavFlg
mov     RegArray+32, eax
         xor     ebx, ebx
         mov     cnt, 0
         mov     sw1, 1
         mov     Base, 16
         mov     edi, offset szEAX+6
         mov     Save, edi
         mov     eax, RegArray[ebx]   ; Input

LoopIt:
         xor     esi, esi
      .while (eax)
            xor     edx, edx
            div     Base              ; Base 10, 16, 8, 2
         .if dl > 9h
               add     dl, 37h        ; Convert to hex ASCII
         .else
               add     dl, 30h        ; Convert to dec ASCII
         .endif
            mov     LBuff[esi], dl
            inc     esi
      .endw
         mov     ecx, esi
      .if sw1 == 1
            add     edi, 8
            sub     edi, ecx
            and     sw1, 0
      .else
            add     ebx, 4
      .endif
         inc     ecx
      .if ecx == 1 && Base == 10
            mov     LBuff[esi-1], 30h
;            mov     LBuff[esi-2], 30h
            inc     ecx
            inc     edi
      .endif
      .while (ecx)
            mov     al, byte ptr LBuff[esi-1]
            mov     byte ptr[edi], al
            inc     edi
            dec     esi
            dec     ecx
      .endw
            mov     byte ptr[edi-1], 20h
            mov     eax, RegArray[ebx]           ; Input
            add     cnt, 1
      .if Base == 10
            mov     sw1, 1
            add     Save, 18
            mov     Base, 16
      .else
            add     Save, 12
            mov     Base, 10
      .endif
      .if cnt < 18
            mov     edi, Save
            jmp     LoopIt
      .elseif cnt == 18
;            mov     eax, RegArray+32
;         pushfd
;            pop     eax
mov     eax, SavFlg
            mov     edi, offset szFLGB
            mov     Base, 2
            jmp     LoopIt   
      .endif
         mov     byte ptr[edi], 0
      INVOKE     lstrcat, addr szDebugBuff, addr szREGS
      INVOKE     DebugPrint, addr szDebugBuff, DB_TEXT
   PrintLine

       popad
endm

;_______________________________________________________________
PrintLine macro
    local szDebugBuff
    pushad
    .data
    szDebugBuff byte 256 dup(0)
    .code
    FillString szDebugBuff, <------------------------------------>
    invoke DebugPrint, addr szDebugBuff, DB_TEXT
    popad
endm

;_______________________________________________________________
PrintError macro
    local szDebugBuff
    pushad
    invoke GetLastError
    .data
    szDebugBuff byte 256 dup(0)
    .code
    invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM, 0, eax, 0, addr szDebugBuff, 256, 0
    invoke DebugPrint, addr szDebugBuff, DB_TEXT
   PrintLine
    popad
endm

;_______________________________________________________________
; pExcept must be a pointer to EXCEPTION_RECORD structure
PrintException macro pExcept:req
    local Info
    .data
    Info byte 35 dup(0)
    .code
    pushad
    mov eax, pExcept
    mov eax, (EXCEPTION_RECORD ptr [eax]).ExceptionCode
    .if ax == EXCEPTION_ACCESS_VIOLATION
        FillString Info, <EXCEPTION_ACCESS_VIOLATION>
    .elseif ax == EXCEPTION_ARRAY_BOUNDS_EXCEEDED
        FillString Info, <EXCEPTION_ARRAY_BOUNDS_EXCEEDED>
    .elseif ax == EXCEPTION_BREAKPOINT
        FillString Info, <EXCEPTION_BREAKPOINT> 
    .elseif ax == EXCEPTION_DATATYPE_MISALIGNMENT
        FillString Info, <EXCEPTION_DATATYPE_MISALIGNMENT>
    .elseif ax == EXCEPTION_FLT_DENORMAL_OPERAND
        FillString Info, <EXCEPTION_FLT_DENORMAL_OPERAND>
    .elseif ax == EXCEPTION_FLT_DIVIDE_BY_ZERO
        FillString Info, <EXCEPTION_FLT_DIVIDE_BY_ZERO>     
    .elseif ax == EXCEPTION_FLT_INEXACT_RESULT
        FillString Info, <EXCEPTION_FLT_INEXACT_RESULT>
    .elseif ax == EXCEPTION_FLT_INVALID_OPERATION
        FillString Info, <EXCEPTION_FLT_INVALID_OPERATION>  
    .elseif ax == EXCEPTION_FLT_OVERFLOW
        FillString Info, <EXCEPTION_FLT_OVERFLOW>
    .elseif ax == EXCEPTION_FLT_STACK_CHECK
        FillString Info, <EXCEPTION_FLT_STACK_CHECK>
    .elseif ax == EXCEPTION_FLT_UNDERFLOW
        FillString Info, <EXCEPTION_FLT_UNDERFLOW>      
    .elseif ax == EXCEPTION_ILLEGAL_INSTRUCTION
        FillString Info, <EXCEPTION_ILLEGAL_INSTRUCTION>
    .elseif ax == EXCEPTION_IN_PAGE_ERROR
        FillString Info, <EXCEPTION_IN_PAGE_ERROR>
    .elseif ax == EXCEPTION_INT_DIVIDE_BY_ZERO
        FillString Info, <EXCEPTION_INT_DIVIDE_BY_ZERO>
    .elseif ax == EXCEPTION_INT_OVERFLOW
        FillString Info, <EXCEPTION_INVALID_DISPOSITION>
    ;.elseif ax == EXCEPTION_NONCONTINUABLE_EXCEPTION
    ;   FillString Info, <EXCEPTION_PRIV_INSTRUCTION>
    .elseif ax == EXCEPTION_SINGLE_STEP
        FillString Info, <EXCEPTION_SINGLE_STEP>
    ;.elseif ax == EXCEPTION_STACK_OVERFLOW
    ;   FillString Info, <EXCEPTION_STACK_OVERFLOW>
    .endif
    invoke DebugPrint, addr Info, DB_TEXT
   PrintLine
    popad
endm

;=============================================================================
;Spy dwVar
;   mov dwVar, 2
;   add dwVar, 3
;   shl dwVar, 1
;StopSpy
;=============================================================================
;_______________________________________________________________
Spy macro Var: REQ
    ifndef __dwVar
        .data
        __dwVar dword 0
        __iTrap dword 0
        .code
    endif
    .if __iTrap == 0 
;        PrintText "************************************"
        push eax
        ;install new SEH
        assume fs: nothing
        mov __dwVar, offset Var
        push offset _except_handler
        push fs:[0]
        mov fs:[0], esp
        inc __iTrap
        ;set TF
        pushf
        pop ax
        or ax, 100h
        push ax
        popf
        nop 
    .endif
endm

StopSpy macro
    mov __iTrap, 0 
    mov eax, [esp] ;restore previous SEH
    mov fs:[0], eax
    add esp, 8
    pop eax ;restore eax
;    PrintText "************************************"
endm

;==============================================================================
DumpMem MACRO lpStart:REQ, lnData:req
LOCAL    @pmem
LOCAL    szDebugBuff
LOCAL    LoopIt

; DbgDump debug macro. Dumps memory. Usage:
;
; USAGE->   DbgDump [startaddress], [length]
;
; My USAGE  DumpMem offset MyString, 128
;            -or-
;           lea eax,MyString
;           DumpMem eax, 48
;            -or-
;           DumpMem 400000,256
; Any mem locations, registers or 
; immediate values may be used as parameters.
;
; Written by Thomas Bleeker [exagone].
; http://exagone.cjb.net
; Modified by Ewayne Wagner & Gary [gscundiff)].

.data?
@pmem       dd  ?
szDebugBuff db 256 dup(?)

.code
      pushad
        push    lpStart
        push    lnData

  FillString     szDebugBuff, &lpStart
      INVOKE     lstrlen, addr szDebugBuff
         mov     byte ptr szDebugBuff[eax], " "
         mov     byte ptr szDebugBuff[eax+1], "="
         mov     byte ptr szDebugBuff[eax+2], " "
         mov     byte ptr szDebugBuff[eax+3], 0
      INVOKE     DebugPrint, addr szDebugBuff, DB_TEXT

      invoke  GlobalAlloc, GMEM_FIXED, 80
         mov     @pmem, eax

         pop     ebx ;lnData
         pop     esi ;lpStart

      .while  ebx
            mov     edi, @pmem

         pushad
            xor     eax, eax
            xor     ecx, ecx
            mov     [edi+8], al         ; put terminator at correct length
            mov     cl, 7               ; length of hexstring - 1

LoopIt:
            mov     eax, esi            ; we're going to work on AL
            and     al, 00001111b       ; mask out high nibble
            cmp     al, 10
            sbb     al, 69h
            das
            mov     [edi + ecx], al     ; store the asciihex(AL) in the string
            shr     esi, 4              ; next nibble
            dec     ecx                 ; decrease counter (one byte less than dec cl :-)
            jns     LoopIt              ; do some more
          popad

            mov     word ptr [edi+8],  ' :'
            add     edi, 10
                                      
           push    esi
           push    ebx
; dump hex values:
            xor     ecx, ecx
         .while (ecx < 16)
            .if !ebx
                  mov     dword ptr [edi], '00' ;'  '
                  add     edi, 2

               .if ecx == 1 || ecx == 3 || ecx == 5 || ecx == 7 ||\
                   ecx == 9 || ecx == 11 || ecx == 13 || ecx == 15
                     mov     byte ptr [edi], ' '
                     inc     edi
               .endif

            .else
                  dec     ebx
                  xor     eax, eax
                                              
                  mov     al, [esi]
                  inc     esi

                  ror     ax, 4
                  shr     ah, 4
                  add     ax, 3030h
                  cmp     ah, 39h
                  jbe     @F
                  add     ah, 'A'-3Ah
@@:
                  cmp     al, 39h
                  jbe     @F
                  add     al, 'A'-3Ah
@@:   
                  mov     word ptr [edi], ax
               .if ecx == 1 || ecx == 3 || ecx == 5 ||\
                   ecx == 9 || ecx == 11 || ecx == 13 || ecx == 15
                     mov     byte ptr [edi+2], ' '
                     add     edi, 3
               .elseif ecx == 7
                        mov     word ptr [edi+2], '  '
                        add     edi, 4
               .else
                     add     edi, 2
               .endif
            .endif
               inc     ecx
         .endw

            pop     ebx
            pop     esi
            mov     word ptr [edi], '  '
            add     edi, 1
                                      
; dump text output:
            xor     ecx, ecx
         .while (ecx < 16)
               mov     al, [esi]
            .if !ebx
                  mov  al, '.'
            .else
                  dec  ebx
                  inc  esi
                  cmp  al, 20h
                  jae  @F
                  mov  al, '.'
@@:
            .endif
               mov  [edi], al
               inc  edi
               inc  ecx
         .endw
            mov     byte ptr [edi],0
            mov     edi, @pmem
         invoke     DebugPrint, edi, DB_TEXT
      .endw

      invoke     GlobalFree, @pmem
   PrintLine
                                  
      popad
ENDM
;==============================================================================

.code
_except_handler proc C uses edx pExcept:DWORD, pFrame, pContext, pDispatch
    local SpyVar:DWORD

    ifndef __iTrap
        .data
        __iTrap dd  0
        __dwVar dd  0
        Base    dd  10
        .code
    endif
    .if __iTrap > 0 
        mov edx, pContext
        assume edx: ptr CONTEXT
        .if __iTrap > 1
            pushfd
            pop eax
            or ax, 100h
            push eax
            pop [edx].regFlag ;set TF
            mov eax, __dwVar
            push dword ptr [eax]
            pop SpyVar
            PrintDHB SpyVar, Base
        .elseif __iTrap == 1
            pushfd
            pop eax
            or ax, 100h
            push eax
            pop [edx].regFlag ;set TF
        .endif
        inc __iTrap
        assume edx: nothing
    .endif
    mov eax, ExceptionContinueExecution
    ret
_except_handler endp

;==============================================================================
