News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

FP Exceptions, FRSTOR

Started by vandelay, January 06, 2006, 08:07:46 PM

Previous topic - Next topic

vandelay

It looks like if an error occurs in an FP op, some bits in the FPSW are set, and then the next FP/MMX instruction triggers an exception. Is that correct?

So, if an FRSTOR puts some garbage into the FPSW and ES is set, the next FP/MMX instruction should trigger an FP exception, right?

MichaelW

If by "triggers an exception" you mean an exception that the system detects, this will not happen in the default "initialized" state because all of the interrupt masks in the control word are set to 1, causing the FPU to handle the exceptions internally. And AFAIK when an exception is triggered, it happens immediately after the exception is detected, not after the next MMX/FPU instruction. See Raymond Filiatreault's FPU tutorial for more information. This program demonstrates what happens by default, and what happens if the appropriate interrupt mask in the control word is cleared.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; All the FPU stuff is from Raymond Filiatreault's FPU tutorial:
;   masm32\tutorial\fputute
; All the SEH stuff is from the VKDEBUG debugging tool:
;   masm32\vkdebug
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\debug.inc
    includelib \masm32\lib\debug.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
        result  REAL8 0.0
        oldcw   dw 0
        buffer  db 17 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    ; Display status word as binary.
    fstsw ax
    invoke wrd2bin_ex, ax,ADDR buffer
    print ADDR buffer,13,10

    ;install new seh
    assume fs: nothing
    push offset SEHproc
    push fs:[0]
    mov fs:[0], esp

    inkey "Press any key to continue..."

    ; Divide by zero.
    fld   FP8(3.0)
    fld   FP8(0.0)
    fdiv
    fstp  result

    ; Display status word as binary (Z field is bit2).
    fstsw ax
    invoke wrd2bin_ex, ax,ADDR buffer
    print ADDR buffer,13,10

    ; Clear the exception bits of the status word.
    fclex

    ; Display status word as binary.
    fstsw ax
    invoke wrd2bin_ex, ax,ADDR buffer
    print ADDR buffer,13,10

    inkey "Press any key to continue..."

    ; Clear Zero Divide Mask to enable the FPU interrupt.
    fstcw oldcw
    fwait
    mov   ax,oldcw
    and   ax,NOT 4    ; clear ZM (bit2)
    push  eax
    fldcw [esp]
    pop   eax

    ; Divide by zero.
    fld   FP8(3.0)
    fld   FP8(0.0)
    fdiv
    fstp  result

ext:
    ;restore previous SEH
    mov eax, [esp]
    mov fs:[0], eax
    add esp, 8

    ; This could be used to restore the original control word.
    ;fldcw oldcw

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
SEHproc proc C pExcept: dword, pFrame: dword, pContext: dword, pDispatch: dword
    PrintException pExcept
    mov edx, pContext
    mov (CONTEXT ptr [edx]).regEip, offset ext
    mov eax, ExceptionContinueExecution
    ret
SEHproc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation