AP-578
2/21/97 12:57 PM 24329102.DOC
INTEL CONFIDENTIAL
(until publication date)
handler to be re-entrant, another technique may
also be used. In this technique, the exception flags
are not cleared in the "prologue" and the body of
the handler must not contain any FP instructions
that cannot complete execution when there is a
pending FP exception. (The “No-Wait” instructions
are discussed in Section 6.3.7 of the Pentium
Processor Family Developer’s Manual, Volume 3).
Note that the handler must still clear the exception
flag(s) before executing the IRET. If the exception
handler uses neither of these techniques the
system will be caught in an endless loop of nested
FP exceptions, and hang.
The body of the exception handler examines the
diagnostic information and makes a response that
is necessarily application-dependent. This response
may range from halting execution, to 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 normal 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
and ASM486 coding of three skeleton exception
handlers, 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 handling
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 tradeoff 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
interrupt request. (See the Pentium
Processor
Family Developer’s Manual, Volume 3, Section
6.2.1.6 for a complete description of the FPU save
image.)
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 exception).
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 1 and Example 2 assume that the
exception handler itself will not cause an unmasked
exception. Where this is a possibility, the general
approach shown in 3 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 1. Full-State Exception Handler
SAVE_ALL PROC
;
; SAVE REGISTERS, ALLOCATE STACK SPACE FOR FPU STATE IMAGE
PUSH EBP
.
.
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
;
; APPLICATION-DEPENDENT EXCEPTION HANDLING CODE GOES HERE
;
; CLEAR EXCEPTION FLAGS IN STATUS WORD (WHICH IS IN MEMORY)