State of the fpu at the start of a program and finit

Started by ToutEnMasm, June 16, 2009, 01:12:51 PM

Previous topic - Next topic

ToutEnMasm

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

ToutEnMasm

#1
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                         

raymond

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.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ToutEnMasm


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   

raymond

Quotethe control word is not the same at the start of a program and after a finit

TRUE

At 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.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com