111 lines
4 KiB
NASM
111 lines
4 KiB
NASM
|
|
||
|
.xlist
|
||
|
include cruntime.inc
|
||
|
include elem87.inc
|
||
|
.list
|
||
|
|
||
|
.data
|
||
|
|
||
|
_exception struc ; struct _exception {
|
||
|
typ dd ? ; int type; /* exception type - see below */
|
||
|
nam dd ? ; char *name; /* name of function where error occured */
|
||
|
arg1 dq ? ; double arg1; /* first argument to function */
|
||
|
arg2 dq ? ; double arg2; /* second argument (if any) to function */
|
||
|
retval dq ? ; double retval; /* value to be returned by function */
|
||
|
_exception ends ; }
|
||
|
|
||
|
Except_struct_size equ ((size _exception) + ISIZE - 1) and (not (ISIZE-1))
|
||
|
|
||
|
Except_struct equ [ebp-Except_struct_size]
|
||
|
|
||
|
CODESEG
|
||
|
|
||
|
extrn _87except:proc
|
||
|
|
||
|
;***********************************************************
|
||
|
;
|
||
|
; _startTwoArgErrorHandling
|
||
|
;
|
||
|
;***********************************************************
|
||
|
; Purpose: call to 87except() function, and restore CW
|
||
|
;
|
||
|
; at this point we have on stack: ret_addr(4), cw(4), ret_addr(4), arg1(8bytes)
|
||
|
; ecx points to function name
|
||
|
; edx function id (for example OP_LOG)
|
||
|
; eax error type (for example SING)
|
||
|
;
|
||
|
; Note:
|
||
|
; we could use this procedure instead of _startOneArgErrorHandling,
|
||
|
; but not always we can assume that there is something on stack below param1
|
||
|
;
|
||
|
|
||
|
_startTwoArgErrorHandling proc \
|
||
|
savCW:dword, \ ; don't change it !!!
|
||
|
ret_addr:dword, \
|
||
|
param1:qword,
|
||
|
param2:qword
|
||
|
|
||
|
local arg_to_except87:_exception
|
||
|
|
||
|
; store second argument to _exception structure
|
||
|
mov [arg_to_except87.typ],eax ; type of error
|
||
|
mov eax,dword ptr [param2] ; load arg2
|
||
|
mov dword ptr [arg_to_except87.arg2],eax
|
||
|
mov eax,dword ptr [param2+4]
|
||
|
mov dword ptr [arg_to_except87.arg2+4],eax
|
||
|
jmp _ContinueErrorHandling
|
||
|
_startTwoArgErrorHandling endp
|
||
|
|
||
|
|
||
|
;***********************************************************
|
||
|
;
|
||
|
; _startOneArgErrorHandling
|
||
|
;
|
||
|
;***********************************************************
|
||
|
; Purpose: call to 87except() function, and restore CW
|
||
|
;
|
||
|
; at this point we have on stack: ret_addr(4), cw(4), ret_addr(4), arg1(8bytes)
|
||
|
; ecx points to function name
|
||
|
; edx function id (for example OP_LOG)
|
||
|
; eax error type (for example SING)
|
||
|
;
|
||
|
|
||
|
_startOneArgErrorHandling proc \
|
||
|
savCW:dword, \ ; don't change it !!!
|
||
|
ret_addr:dword, \
|
||
|
param1:qword
|
||
|
|
||
|
local arg_to_except87:_exception
|
||
|
|
||
|
; prepare _exception structure
|
||
|
mov [arg_to_except87.typ],eax ; type of error
|
||
|
_ContinueErrorHandling label proc
|
||
|
fstp [arg_to_except87.retval] ; store return value
|
||
|
mov [arg_to_except87.nam],ecx ; pointer to function name
|
||
|
mov eax,dword ptr [param1] ; load arg1
|
||
|
mov ecx,dword ptr [param1+4]
|
||
|
mov dword ptr [arg_to_except87.arg1],eax
|
||
|
mov dword ptr [arg_to_except87.arg1+4],ecx
|
||
|
|
||
|
; push on stack args for _87except()
|
||
|
lea eax,[savCW] ; load control word
|
||
|
lea ecx,arg_to_except87
|
||
|
push eax ; &(CW)
|
||
|
push ecx ; &(_exception structure)
|
||
|
push edx ; function number
|
||
|
call _87except
|
||
|
add esp,12 ; clear arguments if _cdecl
|
||
|
fld [arg_to_except87.retval] ; this assumes that user
|
||
|
; does not want to return a
|
||
|
; signaling NaN
|
||
|
; Now it's time to restore saved CW
|
||
|
cmp word ptr[savCW],default_CW
|
||
|
je CW_is_restored ; it's usualy taken
|
||
|
fldcw word ptr[savCW]
|
||
|
CW_is_restored:
|
||
|
ret ; _cdecl return
|
||
|
|
||
|
_startOneArgErrorHandling endp
|
||
|
end
|
||
|
|