E-17
GUIDELINES FOR WRITING FPU EXCEPTIONS HANDLERS
displaying a message, to attempting to repair the problem and proceed with normal execution.
The epilogue essentially reverses the actions of the prologue, restoring the processor so that nor-
mal execution can be resumed. The epilogue must not load an unmasked exception flag into the
FPU or another exception will be requested immediately.
The following code examples show the ASM386/486 coding of three skeleton exception han-
dlers, with the save spaces given as correct for 32-bit protected mode. They show how prologues
and epilogues can be written for various situations, but the application dependent exception han-
dling body is just indicated by comments showing where it should be placed.
The first two are very similar; their only substantial difference is their choice of instructions to
save and restore the FPU. The trade-off here is between the increased diagnostic information
provided by FNSAVE and the faster execution of FNSTENV. (Also, after saving the original
contents, FNSAVE re-initializes the FPU, while FNSTENV only masks all FPU exceptions.)
For applications that are sensitive to interrupt latency or that do not need to examine register
contents, FNSTENV reduces the duration of the critical region, during which the processor
does not recognize another interruptrequest. (Refer to Section 7, Floating-Point Unit in Chap-
ter 7, Floating-Point Unit, for a complete description of the FPU save image.) If the processor
supports Streaming SIMD Extensions and the operating system supports it, the FXSAVE in-
struction should be used instead of FNSAVE. If the FXSAVE instruction is used, the save area
should be increased to 512 bytes and aligned to 16 bytes to save the entire state. These steps will
ensure that the complete context is saved.
After the exception handler body, the epilogues prepare the processor to resume execution from
the point of interruption (i.e., the instruction following the one that generated the unmasked ex-
ception). Notice that the exception flags in the memory image that is loaded into the FPU are
cleared to zero prior to reloading (in fact, in these examples, the entire status word image is
cleared).
Example E-3 and Example E-4 assume that the exception handler itself will not cause an un-
masked exception. Where this is a possibility, the general approach shown in Example E-5 can
be employed. The basic technique is to save the full FPU state and then to load a new control
word in the prologue. Note that considerable care should be taken when designing an exception
handler of this type to prevent the handler from being reentered endlessly.
Example E-3. Full-State Exception Handler
SAVE_ALLPROC
;
; SAVE REGISTERS, ALLOCATE STACK SPACE FOR FPU STATE IMAGE
PUSHEBP
.
.
MOV EBP, ESP
SUB ESP, 108 ; ALLOCATES 108 BYTES (32-bit PROTECTED MODE SIZE)
;SAVE FULL FPU STATE, RESTORE INTERRUPT ENABLE FLAG (IF)
FNSAVE[EBP-108]
PUSH [EBP + OFFSET_TO_EFLAGS] ; COPY OLD EFLAGS TO STACK TOP
POPFD; RESTORE IF TO VALUE BEFORE FPU EXCEPTION