Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Recover from trap-on-division-by-zero works on X32, crashes on X64

0 views
Skip to first unread message

Ira Baxter

unread,
Mar 3, 2007, 12:36:03 PM3/3/07
to
I have an 32-bit application that has run fine for a decade on 32 bit
Windows systems.
In includes a bit of assembler code that traps division-by-zero exceptions,
and passes control back to a well-known place in the application by
adjusting the PC in the Windows context block provided by the Win32 API
and passing control back to Windows with "WindowsContinueExecution"
This code has been very reliable and satisfying when it is needed.
It is appended at the end of the message.

When I move this application to X64 systems, it does *everything* right
except for the divison by zero trap handling. It appears to get to
the trap handler and report the error, and then XP reports
execution of an illegal instruction.

My understanding is that the 64 bit implementions of Windows all
run the Win32 API (and that seems to be case except for this).
Is this a bug? Or have I been living with a not-quite-right handler
all these years? Suggestions welcome.

-- Ira Baxter

============================================================================
===

TopLevelEHFilter: ; THIS IS SET AS THE WINDOWS EXCEPTION HANDLER
push ebp
mov ebp,esp
push esi ; some of these registers need not
be saved
push ebx
; check what kind of exception
mov eax, 8[ebp] ; ReportRecord
mov eax, dword ptr[eax] ; 1st field of ReportRecord is
_ExceptNumber
cmp eax, _EXCEPTION_INTEGER_DIVIDE_BY_ZERO
je div_by_zero_exception
cmp eax, _EXCEPTION_FLOAT_DIVIDE_BY_ZERO
je float_div_by_zero_exception
<irrelevant code>

float_div_by_zero_exception:
mov ebx, [ebp+10h] ; ebx = context record
mov Context.FltStatusWord[ebx],CLEAR_FLOAT_EXCEPTIONS ; clear
any floating point exceptions
mov Context.FltTagWord[ebx],-1 ; Marks all registers as empty
div_by_zero_exception:
mov ebx, [ebp+10h] ; ebx = context record
mov edx, Context.Reip[ebx]
LOOKUP_EH_FROM_TABLE
mov Context.Reip[ebx],eax ; new exception handling
location
mov ecx, Context.Rebx[ebx]
pop ebx ; interrupt return
pop esi
mov eax, ExceptionContinueExecution ; signal "return to caller"
(we've revised the PC to go to Exception handler)
leave
ret

0 new messages