• 沒有找到結果。

Miscellaneous instructions

The 80x87 FPU includes several additional instructions which control the FPU, syn-chronize operations, and let you test or set various status bits. These instructions include finit/fninit, fdisi/fndisi, feni/fneni, fldcw, fstcw/fnstcw, fclex/fnclex, fsave/fnsave, frstor, frstpm, fstsw/fnstsw, fstenv/fnstenv, fldenv, fincstp, fdecstp, fwait, fnop, and ffree. The fdisi/fndisi, feni/fneni, and frstpm are active only on FPUs earlier than the 80387, so we will not consider them here.

Many of these instructions have two forms. The first form is Fxxxx and the second form is FNxxxx. The version without the “N” emits an fwait instruction prior to opcode (which is standard for most coprocessor instructions). The version with the “N” does not emit the fwait opcode (“N” stands for no wait).

14.4.10.1 The FINIT and FNINIT Instructions

The finit instruction intializes the FPU for proper operation. Your applications should execute this instruction before executing any other FPU instructions. This instruction

ini-1

– 2

--- 2

 

 

 – 

 

st 0 ( ) 1 2 --- 2

 

 

 – 

 

< <

tus register to zero (see “The FPU Status Register” on page 785) and the tag word to 0FFFFh. The other registers are unaffected.

14.4.10.2 The FWAIT Instruction

The fwait instruction pauses the system until any currently executing FPU instruction completes. This is required because the FPU on the 80486sx and earlier CPU/FPU combi-nations can execute instructions in parallel with the CPU. Therefore, any FPU instruction which reads or writes memory could suffer from a data hazard if the main CPU accesses that same memory location before the FPU reads or writes that location. The fwait instruc-tion lets you synchronize the operainstruc-tion of the FPU by waiting until the compleinstruc-tion of the current FPU instruction. This resolves the data hazard by, effectively, inserting an explict

“stall” into the execution stream.

14.4.10.3 The FLDCW and FSTCW Instructions

The fldcw and fstcw instructions require a single 16 bit memory operand:

fldcw mem_16 fstcw mem_16

These two instructions load the control register (see “The FPU Control Register” on page 782) from a memory location (fldcw) or store the control word to a 16 bit memory location (fstcw).

When using the fldcw instruction to turn on one of the exceptions, if the corresponding exception flag is set when you enable that exception, the FPU will generate an immediate interrupt before the CPU executes the next instruction. Therefore, you should use the fclex instruction to clear any pending interrupts before changing the FPU exception enable bits.

14.4.10.4 The FCLEX and FNCLEX Instructions

The fclex and fnclex instructions clear all exception bits the stack fault bit, and the busy flag in the FPU status register (see “The FPU Status Register” on page 785).

14.4.10.5 The FLDENV, FSTENV, and FNSTENV Instructions

fstenv mem_14b fnstenv mem_14b fldenv mem_14b

The fstenv/fnstenv instructions store a 14-byte FPU environment record to the memory operand specified. When operating in real mode (the only mode this text considers), the environment record takes the form appearing in Figure 14.11.

You must execute the fstenv and fnstenv instructions with the CPU interrupts disabled.

Furthermore, you should always ensure that the FPU is not busy before executing this instruction. This is easily accomplished by using the following code:

pushf ;Preserve I flag.

cli ;Disable interrupts.

fstenv mem_14b ;Implicit wait for not busy.

fwait ;Wait for operation to finish.

popf ;Restore I flag.

The fldenv instruction loads the FPU environment from the specified memory oper-and. Note that this instruction lets you load the the status word. There is no explicit

14.4.10.6 The FSAVE, FNSAVE, and FRSTOR Instructions

fsave mem_94b fnsave mem_94b frstor mem_94b

These instructions save and restore the state of the FPU. This includes saving all the internal control, status, and data registers. The destination location for fsave/fnsave (source location for frstor) must be 94 bytes long. The first 14 bytes correspond to the environment record the fldenv and fstenv instructions use; the remaining 80 bytes hold the data from the FPU register stack written out as st(0) through st(7). Frstor reloads the environment record and floating point registers from the specified memory operand.

The fsave/fnsave and frstor instructions are mainly intended for task switching. You can also use fsave/fnsave and frstor as a “push all” and “pop all” sequence to preserve the state of the FPU.

Like the fstenv and fldenv instructions, interrupts should be disabled while saving or restoring the FPU state. Otherwise another interrupt service routine could manipulate the FPU registers and invalidate the operation of the fsave/fnsave or frestore operation. The fol-lowing code properly protects the environment data while saving and restore the FPU sta-tus:

; Preserve the FPU state, assume di points at the environment

; record in memory.

pushf cli

fsave [si]

fwait popf

. . .

pushf cli

frstor [si]

fwait popf

Figure 14.11 FPU Environment Record (16 Bit Real Mode)

Data Ptr Bits 16-19 Unused Bits (set to zero) Data Ptr (Bits 0-15)

Instr Ptr Bits 16-19 0 Instruction opcode (11 bits) Instr Ptr (Bits 0-15)

Tag Word Status Word Control Word

Offset 12 10 8 6 4 2 0

14.4.10.7 The FSTSW and FNSTSW Instructions

fstsw ax fnstsw ax fstsw mem_16 fnstsw mem_16

These instructions store the FPU status register (see “The FPU Status Register” on page 785) into a 16 bit memory location or the ax register. These instructions are unusual in the sense that they can copy an FPU value into one of the 80x86 general purpose regis-ters. Of course, the whole purpose behind allowing the transfer of the status register into ax is to allow the CPU to easily test the condition code register with the sahf instruction.

14.4.10.8 The FINCSTP and FDECSTP Instructions

The fincstp and fdecstp instructions do not take any operands. They simply increment and decrement the stack pointer bits (mod 8) in the FPU status register. These two instruc-tions clear the C1 flag, but do not otherwise affect the condition code bits in the FPU status register.

14.4.10.9 The FNOP Instruction

The fnop instruction is simply an alias for fst st, st(0). It performs no other operation on the FPU.

14.4.10.10The FFREE Instruction

ffree st(i)

This instruction modifies the tag bits for register i in the tags register to mark the spec-ified register as emtpy. The value is unaffected by this instruction, but the FPU will no longer be able to access that data (without resetting the appropriate tag bits).

相關文件