946 lines
19 KiB
NASM
946 lines
19 KiB
NASM
|
; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
|
||
|
; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
|
||
|
; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
|
||
|
; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
|
||
|
; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
|
||
|
; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
|
||
|
; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
|
||
|
; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
|
||
|
; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
|
||
|
; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||
|
|
||
|
|
||
|
; DIV0.ASM - Provides routines to capture divide overflow exceptions.
|
||
|
; See DIV0.H for calling parameters.
|
||
|
|
||
|
.386
|
||
|
|
||
|
|
||
|
|
||
|
_DATA SEGMENT BYTE PUBLIC USE32 'DATA'
|
||
|
|
||
|
MAX_SIZE EQU 100
|
||
|
|
||
|
Old_Ex_Sel dw ? ; Old Selector
|
||
|
Old_Ex_Off dd ? ; Old offset
|
||
|
|
||
|
Already_Init dd 0 ; Equal to 1 when installed
|
||
|
|
||
|
DefaultMode dd 0 ; What to do when not in list.
|
||
|
|
||
|
; Callback List
|
||
|
CB_Size dw 0
|
||
|
CB_Source dd MAX_SIZE DUP (0)
|
||
|
CB_Dest dd MAX_SIZE DUP (0)
|
||
|
|
||
|
; Saturation List
|
||
|
SAT_Size dw 0
|
||
|
SAT_Source dd MAX_SIZE DUP (0)
|
||
|
|
||
|
|
||
|
PUBLIC _div0_num_handled_by_cblist
|
||
|
PUBLIC _div0_num_handled_by_satlist
|
||
|
PUBLIC _div0_num_saturated
|
||
|
|
||
|
_div0_num_handled_by_cblist dd 0
|
||
|
_div0_num_handled_by_satlist dd 0
|
||
|
_div0_num_saturated dd 0
|
||
|
|
||
|
_DATA ENDS
|
||
|
|
||
|
DGROUP GROUP _DATA
|
||
|
|
||
|
|
||
|
_TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
|
||
|
|
||
|
ASSUME DS:_DATA
|
||
|
ASSUME CS:_TEXT
|
||
|
|
||
|
DivideByZeroException:
|
||
|
|
||
|
PREFIX_ADRSIZ EQU 01100111b
|
||
|
PREFIX_OPSIZE EQU 01100110b
|
||
|
PREFIX_LOCK EQU 11110000b
|
||
|
PREFIX_CS EQU 00101110b
|
||
|
PREFIX_DS EQU 00111110b
|
||
|
PREFIX_ES EQU 00100110b
|
||
|
PREFIX_FS EQU 01100100b
|
||
|
PREFIX_GS EQU 01100101b
|
||
|
PREFIX_SS EQU 00110110b
|
||
|
OPCODE_NOP EQU 10010000b
|
||
|
|
||
|
|
||
|
OVERFLOW_8BIT_UNSIGNED EQU 0FFh
|
||
|
OVERFLOW_16BIT_UNSIGNED EQU 0FFFFh
|
||
|
OVERFLOW_32BIT_UNSIGNED EQU 0FFFFFFFFh
|
||
|
|
||
|
OVERFLOW_8BIT_NEGATIVE EQU -128
|
||
|
OVERFLOW_16BIT_NEGATIVE EQU -32768
|
||
|
OVERFLOW_32BIT_NEGATIVE EQU -2147483648
|
||
|
|
||
|
|
||
|
OVERFLOW_8BIT_POSITIVE EQU 127
|
||
|
OVERFLOW_16BIT_POSITIVE EQU 32767
|
||
|
OVERFLOW_32BIT_POSITIVE EQU 2147483647
|
||
|
|
||
|
|
||
|
|
||
|
SAVED_REGS EQU 32
|
||
|
SAVED_EAX EQU DWORD PTR SS:[ESP+0] ; 4
|
||
|
|
||
|
SAVED_AL EQU BYTE PTR SS:[ESP+0]
|
||
|
SAVED_AH EQU BYTE PTR SS:[ESP+1]
|
||
|
SAVED_AX EQU WORD PTR SS:[ESP+0]
|
||
|
|
||
|
SAVED_EBX EQU DWORD PTR SS:[ESP+4] ; 4
|
||
|
|
||
|
SAVED_BL EQU BYTE PTR SS:[ESP+4]
|
||
|
SAVED_BH EQU BYTE PTR SS:[ESP+5]
|
||
|
SAVED_BX EQU WORD PTR SS:[ESP+4]
|
||
|
|
||
|
SAVED_ECX EQU DWORD PTR SS:[ESP+8] ; 4
|
||
|
|
||
|
SAVED_CL EQU BYTE PTR SS:[ESP+8]
|
||
|
SAVED_CH EQU BYTE PTR SS:[ESP+9]
|
||
|
SAVED_CX EQU WORD PTR SS:[ESP+8]
|
||
|
|
||
|
SAVED_EDX EQU DWORD PTR SS:[ESP+12] ; 4
|
||
|
|
||
|
SAVED_DL EQU BYTE PTR SS:[ESP+12]
|
||
|
SAVED_DH EQU BYTE PTR SS:[ESP+13]
|
||
|
SAVED_DX EQU WORD PTR SS:[ESP+12]
|
||
|
|
||
|
SAVED_ESI EQU DWORD PTR SS:[ESP+16] ; 4
|
||
|
SAVED_SI EQU WORD PTR SS:[ESP+16]
|
||
|
|
||
|
SAVED_EDI EQU DWORD PTR SS:[ESP+20] ; 4
|
||
|
SAVED_DI EQU WORD PTR SS:[ESP+20]
|
||
|
|
||
|
SAVED_ES EQU WORD PTR SS:[ESP+24] ; 4
|
||
|
|
||
|
SAVED_DS EQU WORD PTR SS:[ESP+28] ; 4
|
||
|
|
||
|
BAD_EIP EQU DWORD PTR SS:[ESP+0Ch+SAVED_REGS]
|
||
|
BAD_CS EQU WORD PTR SS:[ESP+10h+SAVED_REGS]
|
||
|
SAVED_ESP EQU DWORD PTR SS:[ESP+18h+SAVED_REGS]
|
||
|
SAVED_SP EQU WORD PTR SS:[ESP+18h+SAVED_REGS]
|
||
|
SAVED_SS EQU WORD PTR SS:[ESP+1Ch+SAVED_REGS]
|
||
|
|
||
|
;int 3 ; Bypass by typing: /eip++
|
||
|
|
||
|
push ds
|
||
|
push es
|
||
|
push edi
|
||
|
push esi
|
||
|
push edx
|
||
|
push ecx
|
||
|
push ebx
|
||
|
push eax
|
||
|
|
||
|
mov ax, DGROUP
|
||
|
mov ds, ax
|
||
|
|
||
|
mov eax, BAD_EIP
|
||
|
|
||
|
xor ecx, ecx
|
||
|
|
||
|
NextCB:
|
||
|
cmp cx, CB_Size
|
||
|
je CheckSatList
|
||
|
cmp CB_Source[ecx*4], eax
|
||
|
jne NotIt
|
||
|
; Found the right Call Back item
|
||
|
inc _div0_num_handled_by_cblist
|
||
|
mov ecx, CB_Dest[ecx*4]
|
||
|
mov BAD_EIP, ecx
|
||
|
jmp NormalReturn
|
||
|
NotIt:
|
||
|
inc cx
|
||
|
jmp NextCB
|
||
|
|
||
|
|
||
|
|
||
|
CheckSatList:
|
||
|
xor ecx, ecx
|
||
|
NextSAT:
|
||
|
cmp cx, SAT_Size
|
||
|
je UseDefaultAction
|
||
|
cmp SAT_Source[ecx*4], eax
|
||
|
jne NotIt1
|
||
|
; Found the right Saturation item
|
||
|
inc _div0_num_handled_by_satlist
|
||
|
|
||
|
jmp SaturateIt
|
||
|
NotIt1:
|
||
|
inc cx
|
||
|
jmp NextCB
|
||
|
|
||
|
|
||
|
|
||
|
UseDefaultAction:
|
||
|
cmp DefaultMode, 1
|
||
|
je DefaultSaturate
|
||
|
|
||
|
;====== Return Error Code. =============
|
||
|
;int 3 ; Pop into debugger if active
|
||
|
call div0_close_
|
||
|
jmp NormalReturn
|
||
|
|
||
|
DefaultSaturate:
|
||
|
; This is hit when mode=DM_SATURATE and the instruction
|
||
|
; isn't in any callback or saturate lists. For your handy debugging
|
||
|
; information, the instruction that caused this exception is at
|
||
|
; BX:EAX.
|
||
|
inc _div0_num_saturated
|
||
|
|
||
|
mov eax, BAD_EIP
|
||
|
mov bx, BAD_CS
|
||
|
int 3
|
||
|
|
||
|
SaturateIt:
|
||
|
|
||
|
xor ebx, ebx
|
||
|
xor ecx, ecx
|
||
|
xor esi, esi
|
||
|
xor edi, edi
|
||
|
|
||
|
mov es, SAVED_DS
|
||
|
|
||
|
mov eax, BAD_EIP
|
||
|
|
||
|
; EAX = Pointer to Div instruction
|
||
|
; BH = temp byte holder
|
||
|
; BL = temp byte holder
|
||
|
; CH = Bits 0=8bit, 1=16bit, 2=32bit, 3=DIV
|
||
|
; CL = Temp bit shifter
|
||
|
; EDX = temp 32-bit holder
|
||
|
|
||
|
|
||
|
PrefixCheck:
|
||
|
mov bl, BYTE PTR CS:[eax]
|
||
|
cmp bl, PREFIX_OPSIZE
|
||
|
je OperandSize
|
||
|
cmp bl, PREFIX_ADRSIZ
|
||
|
je OverPrefix
|
||
|
cmp bl, PREFIX_LOCK
|
||
|
je OverPrefix
|
||
|
cmp bl, PREFIX_CS
|
||
|
je PrefixCS
|
||
|
cmp bl, PREFIX_DS
|
||
|
je PrefixDS
|
||
|
cmp bl, PREFIX_ES
|
||
|
je PrefixES
|
||
|
cmp bl, PREFIX_FS
|
||
|
je PrefixFS
|
||
|
cmp bl, PREFIX_GS
|
||
|
je PrefixGS
|
||
|
cmp bl, PREFIX_SS
|
||
|
je PrefixSS
|
||
|
jmp DoneWithPrefixes
|
||
|
|
||
|
OverPrefix:
|
||
|
inc eax
|
||
|
jmp PrefixCheck
|
||
|
|
||
|
PrefixCS:
|
||
|
mov es, BAD_CS
|
||
|
jmp OverPrefix
|
||
|
|
||
|
PrefixDS:
|
||
|
push ds
|
||
|
pop es
|
||
|
jmp OverPrefix
|
||
|
|
||
|
PrefixES:
|
||
|
mov es, SAVED_ES
|
||
|
|
||
|
PrefixFS:
|
||
|
push fs
|
||
|
pop es
|
||
|
jmp OverPrefix
|
||
|
|
||
|
PrefixGS:
|
||
|
push gs
|
||
|
pop es
|
||
|
jmp OverPrefix
|
||
|
|
||
|
PrefixSS:
|
||
|
mov es, SAVED_SS
|
||
|
jmp OverPrefix
|
||
|
|
||
|
OperandSize:
|
||
|
or ch, 10b ; Flag 16-bit
|
||
|
jmp OverPrefix
|
||
|
|
||
|
DoneWithPrefixes:
|
||
|
|
||
|
; Check for the divide opcode.
|
||
|
cmp bl, 0F7h
|
||
|
je OP32OR16BIT
|
||
|
|
||
|
cmp bl, 0F6h
|
||
|
je OP8BIT
|
||
|
|
||
|
; Something is wrong!!!!! This should never be reached!!!
|
||
|
pop eax
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
|
||
|
int 3
|
||
|
retf
|
||
|
|
||
|
|
||
|
OP32OR16BIT:
|
||
|
test ch, 10b
|
||
|
jnz OP16BIT
|
||
|
|
||
|
OP32BIT:
|
||
|
or ch, 100b ; Flag 32-bit
|
||
|
jmp GotOpSize
|
||
|
|
||
|
OP8BIT:
|
||
|
or ch, 1b ; Flag 8-bit
|
||
|
jmp GotOpSize
|
||
|
|
||
|
OP16BIT:
|
||
|
|
||
|
|
||
|
GotOpSize:
|
||
|
inc eax ; We should be pointing to the mod,111,r/m byte
|
||
|
mov bl, BYTE PTR CS:[eax]
|
||
|
inc eax
|
||
|
|
||
|
mov bh, bl
|
||
|
shr bh, 6 ; BH = mod bits
|
||
|
|
||
|
test bl, 001000b
|
||
|
; 110 = Div
|
||
|
; 111 = iDiv
|
||
|
jz IsDIV
|
||
|
; This is a signed division
|
||
|
or ch, 1000b ; Flag Signed
|
||
|
IsDIV:
|
||
|
and bl, 111b ; BL = r/m bits
|
||
|
|
||
|
cmp bh, 11b
|
||
|
je MOD_11
|
||
|
|
||
|
|
||
|
DoRMbits:
|
||
|
|
||
|
cmp bl, 000b
|
||
|
je RM_000
|
||
|
cmp bl, 001b
|
||
|
je RM_001
|
||
|
cmp bl, 010b
|
||
|
je RM_010
|
||
|
cmp bl, 011b
|
||
|
je RM_011
|
||
|
cmp bl, 100b
|
||
|
je RM_100
|
||
|
cmp bl, 101b
|
||
|
je RM_101
|
||
|
cmp bl, 110b
|
||
|
je RM_110
|
||
|
jmp RM_111
|
||
|
|
||
|
RM_000:
|
||
|
add esi, SAVED_EAX
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_001:
|
||
|
add esi, SAVED_ECX
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_010:
|
||
|
add esi, SAVED_EDX
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_011:
|
||
|
add esi, SAVED_EBX
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_100:
|
||
|
jmp RM_SIB
|
||
|
|
||
|
|
||
|
RM_101:
|
||
|
cmp bh, 00b
|
||
|
je DSdisp32
|
||
|
|
||
|
add esi, ebp
|
||
|
mov es, SAVED_SS
|
||
|
jmp doneRM
|
||
|
|
||
|
DSdisp32:
|
||
|
mov bh, 10b
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_110:
|
||
|
add esi, SAVED_ESI
|
||
|
jmp doneRM
|
||
|
|
||
|
RM_111:
|
||
|
add esi, SAVED_EDI
|
||
|
jmp doneRM
|
||
|
|
||
|
|
||
|
RM_SIB:
|
||
|
mov bl, BYTE PTR CS:[eax] ; BL = s-i-b byte
|
||
|
|
||
|
mov cl, bl
|
||
|
shl cl, 6
|
||
|
|
||
|
shl bl, 3
|
||
|
and bl, 111b
|
||
|
|
||
|
cmp bl, 000b
|
||
|
je INDEX_EAX
|
||
|
cmp bl, 001b
|
||
|
je INDEX_ECX
|
||
|
cmp bl, 010b
|
||
|
je INDEX_EDX
|
||
|
cmp bl, 011b
|
||
|
je INDEX_EBX
|
||
|
cmp bl, 100b
|
||
|
je doneSIB1
|
||
|
cmp bl, 101b
|
||
|
je INDEX_EBP
|
||
|
cmp bl, 110b
|
||
|
je INDEX_ESI
|
||
|
jmp INDEX_EDI
|
||
|
|
||
|
|
||
|
INDEX_EAX:
|
||
|
mov edx, SAVED_EAX
|
||
|
jmp doneSIB
|
||
|
INDEX_ECX:
|
||
|
mov edx, SAVED_ECX
|
||
|
jmp doneSIB
|
||
|
INDEX_EDX:
|
||
|
mov edx, SAVED_EDX
|
||
|
jmp doneSIB
|
||
|
INDEX_EBX:
|
||
|
mov edx, SAVED_EBX
|
||
|
jmp doneSIB
|
||
|
INDEX_EBP:
|
||
|
mov edx, ebp
|
||
|
jmp doneSIB
|
||
|
INDEX_ESI:
|
||
|
mov edx, SAVED_ESI
|
||
|
jmp doneSIB
|
||
|
INDEX_EDI:
|
||
|
mov edx, SAVED_EDI
|
||
|
jmp doneSIB
|
||
|
|
||
|
doneSIB:
|
||
|
shl edx, cl
|
||
|
add esi, edx
|
||
|
|
||
|
|
||
|
doneSIB1:
|
||
|
mov bl, BYTE PTR CS:[eax] ; BL = s-i-b byte
|
||
|
inc eax
|
||
|
|
||
|
mov bh, bl
|
||
|
shl bh, 6
|
||
|
and bl, 111b
|
||
|
jmp DoRMbits
|
||
|
|
||
|
|
||
|
doneRM: ;BH = mod
|
||
|
|
||
|
cmp bh, 00b
|
||
|
je MOD_00
|
||
|
cmp bh, 01b
|
||
|
je MOD_01
|
||
|
cmp bh, 10b
|
||
|
je MOD_10
|
||
|
jmp MOD_11
|
||
|
|
||
|
|
||
|
MOD_00: ; No displacement
|
||
|
jmp doneMOD
|
||
|
|
||
|
MOD_01: ; disp8
|
||
|
movsx edx, BYTE PTR CS:[eax]
|
||
|
add eax, 1
|
||
|
add esi, edx
|
||
|
jmp doneMOD
|
||
|
|
||
|
MOD_10:
|
||
|
mov edx, DWORD PTR CS:[eax]
|
||
|
add eax, 4
|
||
|
add esi, edx
|
||
|
jmp doneMOD
|
||
|
|
||
|
MOD_11: cmp bl, 000b
|
||
|
je REG_000
|
||
|
cmp bl, 001b
|
||
|
je REG_001
|
||
|
cmp bl, 010b
|
||
|
je REG_010
|
||
|
cmp bl, 011b
|
||
|
je REG_011
|
||
|
cmp bl, 100b
|
||
|
je REG_100
|
||
|
cmp bl, 101b
|
||
|
je REG_101
|
||
|
cmp bl, 110b
|
||
|
je REG_110
|
||
|
jmp REG_111
|
||
|
|
||
|
|
||
|
REG_000:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_AL
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_AX
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_EAX
|
||
|
jmp GotValue
|
||
|
|
||
|
REG_001:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_CL
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_CX
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_ECX
|
||
|
jmp GotValue
|
||
|
REG_010:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_DL
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_DX
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_EDX
|
||
|
jmp GotValue
|
||
|
REG_011:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_BL
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_BX
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_EDX
|
||
|
jmp GotValue
|
||
|
REG_100:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_AH
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_SP
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_ESP
|
||
|
jmp GotValue
|
||
|
REG_101:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_CH
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, bp
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, ebp
|
||
|
jmp GotValue
|
||
|
REG_110:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_DH
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_SI
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_ESI
|
||
|
jmp GotValue
|
||
|
REG_111:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_BH
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, SAVED_DI
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, SAVED_EDI
|
||
|
jmp GotValue
|
||
|
|
||
|
|
||
|
doneMOD:
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, BYTE PTR ES:[esi]
|
||
|
@@: test ch, 10b ; Check if 16-bit
|
||
|
jz @f ; Skip if not
|
||
|
movsx edx, WORD PTR ES:[esi]
|
||
|
@@: test ch, 100b ; Check if 32-bit
|
||
|
jz GotValue ; skip if not
|
||
|
mov edx, DWORD PTR ES:[esi]
|
||
|
|
||
|
GotValue:
|
||
|
; EAX = Pointer to instruction right after DIV
|
||
|
; CH = Bits 0=8bit, 1=16bit, 2=32bit, 3=DIV
|
||
|
; EDX = 32-bit sign extended divisor (source operand)
|
||
|
|
||
|
mov BAD_EIP, eax ; Point EIP to next instruction
|
||
|
|
||
|
|
||
|
; if size=8 then AL=1..., AH=1...
|
||
|
; if size=16 then AX=1..., DX=1...
|
||
|
; if size=32 then EAX=1..., EDX=1...
|
||
|
;
|
||
|
; resultsign = - (Assume negative or unsigned)
|
||
|
;
|
||
|
; If signed then
|
||
|
; if size=8 then resultsign = sign(ah:al) * sign(edx)
|
||
|
; if size=16 then resultsign = sign(dx:ax) * sign(edx)
|
||
|
; if size=32 then resultsign = sign(dx:ax) * sign(edx)
|
||
|
;
|
||
|
; if resultsign == + then
|
||
|
; if size=8 then AL = 01...
|
||
|
; if size=16 then AX = 01...
|
||
|
; if size=32 then EAX = 01...
|
||
|
;
|
||
|
|
||
|
test ch, 1000b
|
||
|
jz UnSigned
|
||
|
|
||
|
shr edx, 31
|
||
|
|
||
|
; Signed return
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jnz Get8Sign
|
||
|
test ch, 10b ; Check if 16-bit
|
||
|
jnz Get16Sign
|
||
|
jmp Get32Sign ; Else is 32-bit
|
||
|
|
||
|
Get8Sign:
|
||
|
mov ah, SAVED_AH
|
||
|
shr ah, 7 ; AH = sign of divisor
|
||
|
xor ah, dl
|
||
|
jnz Neg8Return
|
||
|
jmp Pos8Return
|
||
|
|
||
|
Get16Sign:
|
||
|
mov ah, SAVED_DH
|
||
|
shr ah, 7 ; AH = sign of divisor
|
||
|
xor ah, dl
|
||
|
jnz Neg16Return
|
||
|
jmp Pos16Return
|
||
|
|
||
|
Get32Sign:
|
||
|
mov eax, SAVED_EDX
|
||
|
shr eax, 31 ; AL = sign of divisor
|
||
|
xor al, dl
|
||
|
jnz Neg32Return
|
||
|
jmp Pos32Return
|
||
|
|
||
|
UnSigned: ; We need to find the sign
|
||
|
; Unsigned div return
|
||
|
test ch, 1b ; Check if 8-bit
|
||
|
jnz Unsigned8Return
|
||
|
test ch, 10b ; Check if 16-bit
|
||
|
jnz Unsigned16Return
|
||
|
jmp Unsigned32Return ; Else is 32-bit
|
||
|
|
||
|
|
||
|
NormalReturn:
|
||
|
pop eax
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
|
||
|
Neg8Return:
|
||
|
pop eax
|
||
|
mov al, OVERFLOW_8BIT_NEGATIVE
|
||
|
mov ah, 0 ; Remainder = 0
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Neg16Return:
|
||
|
pop eax
|
||
|
mov ax, OVERFLOW_16BIT_NEGATIVE
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov dx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Neg32Return:
|
||
|
pop eax
|
||
|
mov eax, OVERFLOW_32BIT_NEGATIVE
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov edx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
|
||
|
Pos8Return:
|
||
|
pop eax
|
||
|
mov al, OVERFLOW_8BIT_POSITIVE
|
||
|
mov ah, 0 ; Remainder = 0
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Pos16Return:
|
||
|
pop eax
|
||
|
mov ax, OVERFLOW_16BIT_POSITIVE
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov dx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Pos32Return:
|
||
|
pop eax
|
||
|
mov eax, OVERFLOW_32BIT_POSITIVE
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov edx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Unsigned8Return:
|
||
|
pop eax
|
||
|
mov al, OVERFLOW_8BIT_UNSIGNED
|
||
|
mov ah, 0 ; Remainder = 0
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Unsigned16Return:
|
||
|
pop eax
|
||
|
mov ax, OVERFLOW_16BIT_UNSIGNED
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov dx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
Unsigned32Return:
|
||
|
pop eax
|
||
|
mov eax, OVERFLOW_32BIT_UNSIGNED
|
||
|
pop ebx
|
||
|
pop ecx
|
||
|
pop edx
|
||
|
mov edx, 0 ; Remainder = 0
|
||
|
pop esi
|
||
|
pop edi
|
||
|
pop es
|
||
|
pop ds
|
||
|
retf
|
||
|
|
||
|
|
||
|
PUBLIC div0_close_
|
||
|
|
||
|
div0_close_:
|
||
|
push eax
|
||
|
push ecx
|
||
|
push edx
|
||
|
|
||
|
mov Already_Init, 0
|
||
|
|
||
|
mov eax, 0203h
|
||
|
mov bl, 0
|
||
|
mov cx, Old_Ex_Sel
|
||
|
mov edx, Old_Ex_Off
|
||
|
int 31h
|
||
|
|
||
|
pop edx
|
||
|
pop ecx
|
||
|
pop eax
|
||
|
|
||
|
ret
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
PUBLIC div0_set_saturate_
|
||
|
|
||
|
div0_set_saturate_:
|
||
|
; EAX = div_addr
|
||
|
|
||
|
push ecx
|
||
|
|
||
|
xor ecx, ecx
|
||
|
mov cx, SAT_Size
|
||
|
inc cx
|
||
|
cmp cx, MAX_SIZE
|
||
|
jae TooMany1
|
||
|
mov SAT_Size, cx
|
||
|
|
||
|
dec ecx
|
||
|
mov SAT_Source[ecx*4], eax
|
||
|
|
||
|
mov eax, 1
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
TooMany1:
|
||
|
mov eax, 0
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
|
||
|
PUBLIC div0_set_handler_
|
||
|
|
||
|
div0_set_handler_:
|
||
|
; EAX = div_addr
|
||
|
; EDX = handler_addr
|
||
|
push ecx
|
||
|
|
||
|
xor ecx, ecx
|
||
|
mov cx, CB_Size
|
||
|
inc cx
|
||
|
cmp cx, MAX_SIZE
|
||
|
jae TooMany
|
||
|
mov CB_Size, cx
|
||
|
|
||
|
dec ecx
|
||
|
mov CB_Source[ecx*4], eax
|
||
|
mov CB_Dest[ecx*4], edx
|
||
|
|
||
|
mov eax, 1
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
TooMany:
|
||
|
mov eax, 0
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
|
||
|
|
||
|
PUBLIC div0_set_mode_
|
||
|
|
||
|
div0_set_mode_:
|
||
|
and eax, 1
|
||
|
mov DefaultMode, eax
|
||
|
ret
|
||
|
|
||
|
|
||
|
PUBLIC div0_init_
|
||
|
|
||
|
div0_init_:
|
||
|
push ds
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edx
|
||
|
|
||
|
cmp Already_Init, 1
|
||
|
je AlreadyInstalled
|
||
|
|
||
|
mov Already_Init, 1
|
||
|
|
||
|
mov _div0_num_handled_by_cblist, 0
|
||
|
mov _div0_num_handled_by_satlist, 0
|
||
|
mov _div0_num_saturated, 0
|
||
|
|
||
|
and eax, 1
|
||
|
mov DefaultMode, eax
|
||
|
|
||
|
mov SAT_Size, 0
|
||
|
mov CB_Size, 0
|
||
|
|
||
|
mov eax, 0202h
|
||
|
mov bl, 0
|
||
|
int 31h
|
||
|
jc ToBadSoSadItFailed
|
||
|
mov Old_Ex_Sel,cx
|
||
|
mov Old_Ex_Off,edx
|
||
|
|
||
|
mov eax, 0203h
|
||
|
mov bl, 0
|
||
|
mov cx, cs
|
||
|
mov edx, offset DivideByZeroException
|
||
|
int 31h
|
||
|
jc ToBadSoSadItFailed
|
||
|
|
||
|
AlreadyInstalled:
|
||
|
mov eax, 1
|
||
|
pop edx
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
pop ds
|
||
|
ret
|
||
|
|
||
|
ToBadSoSadItFailed:
|
||
|
mov eax, 0
|
||
|
pop edx
|
||
|
pop ebx
|
||
|
pop ds
|
||
|
ret
|
||
|
|
||
|
_TEXT ENDS
|
||
|
|
||
|
|
||
|
END
|
||
|
|
||
|
|