This sample is enough simple to show there is a difference on the state of the fpu at the beginning of a program and after a finit.
First , make an executable as it is,The messagebox say you there is a precision fault.This is normal, the number exceeds the contents of an integer qword.
Second,delet the ; on the finit instruction,just after start.There is no messagebox shown.
Where is the problem ?.
Quote
; #########################################################################
.NOLIST
.386
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.const
FPU_Status_Word_IE equ 1 SHL 0 ;invalid-operation exception
FPU_Status_Word_DE equ 1 SHL 1 ;denormalized-operand exception
FPU_Status_Word_ZE equ 1 SHL 2 ;zero divide exception
FPU_Status_Word_OE equ 1 SHL 3 ;overflow exception
FPU_Status_Word_UE equ 1 SHL 4 ;underflow exception
FPU_Status_Word_PE equ 1 SHL 5 ;precision exception
FPU_Status_Word_SF equ 1 SHL 6 ;stack fault
FPU_Status_Word_ES equ 1 SHL 7 ;exception status
FPU_Status_Word_CO equ 1 SHL 8 ;condition code
FPU_Status_Word_C1 equ 1 SHL 9 ;condition code
FPU_Status_Word_C2 equ 1 SHL 10 ;condition code
FPU_Status_Word_TOP equ 111b SHL 11 ;top of stack pointer fpr0 = 000 fpr7 ==111
FPU_Status_Word_C3 equ 1 SHL 14 ;condition code
FPU_Status_Word_B equ 1 SHL 15 ;busy
FPU_Status_Word_comparison equ FPU_Status_Word_C3 OR FPU_Status_Word_C2 OR FPU_Status_Word_CO
NumberOfShift equ 2
.data
MyQw qword 1234567812345678h
another qword 000ffh
szPrecision db "Precision FPU_Status_Word_PE is on",0
szTitre db "FPU status word",0
.code
;@@@@@@@@@@@@@@@@@@@@@@@ entry point @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
start:
;finit
;fclex
mov eax,NumberOfShift
push eax
fild dword ptr [esp]
pop eax
fld1
fscale ;calcul the multiplicator for a right shift
fild qword ptr MyQw
fmul st(0),st(1) ;the result begin greater than the contents of a qword
mov eax,0
fstsw ax
and eax,FPU_Status_Word_PE ;defaut de precision
.if eax != 0
invoke MessageBox,NULL,addr szPrecision,addr szTitre,MB_OK
.endif
fistp qword ptr MyQw
fld MyQw
finit
invoke ExitProcess,0
;################################################################
end start
Difference is in the control word.Finit set to 1 Underflow Exception Mask
Quote
.data
contWord dw 27fh
finit ;4 UM Underflow Exception Mask
fldcw contWord ;same value as start of program
QuoteThe messagebox say you there is a precision fault.This is normal, the number exceeds the contents of an integer dword.
FALSE
This has nothing to do with a DWORD size. As indicated elsewhere, the FPU is provided to a program with the Precision Control set for double-precision, i.e. 64 bits with 53 bits for the mantissa. In that condition, if the result of an operation would contain more than 53 bits, the excess bits would be lost and the remaining 53 bits would be rounded according to the Rounding Control setting. The Precision Exception flag would then be raised.
In the case of your program, you are multiplying a 61-bit number by 4 resulting in a 63 bit number. The last 10 bits of the result would be dropped and the Precision Exception flag would be raised.
Quoteon the finit instruction,just after start.There is no messagebox shown.
Where is the problem ?.
As indicated elsewhere, the "finit" instruction sets the Precision Control for extended double-precision, i.e. 80 bits with 64 bits for the mantissa. The multiplication of a 61-bit number by 4 resulting in a 63 bit number does not exceed the allowed precision for the mantissa and therefore does not raise the Precision Exception flag.
.data
contWord dw 37Fh
.code
fldcw contWord ;same value as if you use finit
The 27h value you posted is WRONG. The correct value of the Control Word without the "finit" is
27Fh.
Ok,there is mistake in my post.
What is important is that the control word is not the same at the start of a program and after a finit.
To correct this.
Quote
start:
fstcw contWord
;.............
finit
fldcw contWord
Quotethe control word is not the same at the start of a program and after a finit
TRUEAt least under Windows, the "finit"
modifies the Precision Control bits of the
Control Word to inform the FPU to perform all operations with the maximum available precision instead of the lower precision initially provided under Windows.
It would be interesting to know if any of the other Operating Systems provide full FPU precision upon loading an application.