x86 Instruction Set Reference

FSTENV/FNSTENV

Store x87 FPU Environment

Opcode Mnemonic Description
9B D9 /6 FSTENV m14/28byte Store FPU environment to m14byte or m28byte after checking for pending unmasked floating-point exceptions. Then mask all floating-point exceptions.
D9 /6 FNSTENV* m14/28byte Store FPU environment to m14byte or m28byte without checking for pending unmasked floating-point exceptions. Then mask all floating-point exceptions. See the IA-32 Architecture Compatibility section below.
Description

Saves the current FPU operating environment at the memory location specified with the destination operand, and then masks all floating-point exceptions. The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the IA-32 Intel Architecture Software Developer's Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute (16- bit or 32-bit). In virtual-8086 mode, the real mode layouts are used.

The FSTENV instruction checks for and handles any pending unmasked floating-point exceptions before storing the FPU environment; the FNSTENV instruction does not. The saved image reflects the state of the FPU after all floating-point instructions preceding the FSTENV/FNSTENV instruction in the instruction stream have been executed.

These instructions are often used by exception handlers because they provide access to the FPU instruction and data pointers. The environment is typically saved in the stack. Masking all exceptions after saving the environment prevents floating-point exceptions from interrupting the exception handler.

The assembler issues two instructions for the FSTENV instruction (an FWAIT instruction followed by an FNSTENV instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions, the save EIP points to the instruction that caused the exception.

Operation
Destination.FPUControlWord = FPUControlWord;
Destination.FPUStatusWord = FPUStatusWord;
Destination.FPUTagWord = FPUTagWord;
Destination.FPUDataPointer = FPUDataPointer;
Destination.FPUInstructionPointer = FPUInstructionPointer;
Destination.FPULastInstructionOpcode = FPULastInstructionOpcode;
FPU flags affected

The C0, C1, C2, and C3 are undefined.

IA-32 Architecture Compatibility

When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual circumstances) for an FNSTENV instruction to be interrupted prior to being executed to handle a pending FPU exception. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the IA-32 Intel Architecture Software Developer's Manual, Volume 1, for a description of these circumstances. An FNSTENV instruction cannot be interrupted in this way on a Pentium 4, Intel Xeon, or P6 family processor.

Floating-Point Exceptions
None.
Protected Mode Exceptions
#GP(0)If the destination is located in a non-writable segment. If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a null segment selector.
#GP(0)If the destination is located in a non-writable segment. If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a null segment selector.
#SS(0)If a memory operand effective address is outside the SS segment limit.
#NMEM or TS in CR0 is set.
#PF(fault-code)If a page fault occurs.
Real-Address Mode Exceptions
#GPIf a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#GPIf a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SSIf a memory operand effective address is outside the SS segment limit.
Virtual-8086 Mode Exceptions
#GP(0)If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#GP(0)If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)If a memory operand effective address is outside the SS segment limit.
#NMEM or TS in CR0 is set.
#PF(fault-code)If a page fault occurs.