The FSTCW instruction checks for and handles pending unmasked floatingpoint exceptions before storing the control word; the FNSTCW instruction does not.
WAIT指令的作用如下
Causes the processor to check for and handle pending, unmasked, floating-point exceptions before proceeding. (FWAIT is an alternate mnemonic for WAIT.)
所以可以认为FSTCW = WAIT + FNSTCW
去掉WAIT指令,就没有check for and handle pending, unmasked, floating-point exceptions
“check for and handle pending, unmasked, floating-point exceptions”怎么理解?
是否是说浮点出了异常,并不会立刻反映到CPU上,而是有一个延时?然后wait的作用就是如果这个异常当时处于pending(挂起状态),并且是unmasked(未被屏蔽)的浮点异常,那么会等待这个异常被CPU接受后返回?如果不去wait,那么这个异常体现的时机会延后,而如果直接fldcw,这个异常可能会丢失呢?
The assembler automatically inserts a WAIT for this purpose before the following instructions: FCLEX, FINIT, FSAVE, FSTCW, FSTENV, FSTSW. You can omit the WAIT by writing FNCLEX, etc. My tests show that the WAIT is unneccessary in most cases because these instructions without WAIT will still generate an interrupt on exceptions except for FNCLEX and FNINIT on the 80387. (There is some inconsistency about whether the IRET from the interrupt points to the FN.. instruction or to the next instruction). Almost all other floating point instructions will also generate an interrupt if a previous floating point instruction has set an unmasked exception bit, so the exception is likely to be detected sooner or later anyway. You may insert a WAIT after the last floating point instruction in your program to be sure to catch all exceptions.
You may still need the WAIT if you want to know exactly where an exception occurred in order to be able to recover from the situation. Consider, for example, the code under b.3 above: If you want to be able to recover from an exception generated by the FLD here, then you need the WAIT because an interrupt after ADD ESP,8 would overwrite the value to load. FNOP may be faster than WAIT and serve the same purpose.