MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite
Quote from: raymond on May 24, 2012, 01:02:24 AM
From the description of the Status Word,QuoteBits 6-0 are flags raised by the FPU whenever it detects an exception. Those exception flags are cumulative in the sense that, once set (bit=1), they are not reset (bit=0) by the result of a subsequent instruction which, by itself, would not have raised that flag. Those flags can only be reset by either initializing the FPU (FINIT instruction) or by explicitly clearing those flags (FCLEX instruction).
include \masm32\include\masm32rt.inc
Near64 = 10000011b
.code
start: finit
push Near64*256
fldcw [esp] ; clear exception masks
pop eax
fldpi
fldz
fdiv ; 3.1415/0 -> should trigger exception
inkey "ok"
exit
end start
QuoteI had some old style PCs about 8 years ago that did not have the FPU interrupt correctly connected to the proper BIOS' interrupt handler that would do a BSOD. In the fast modern PCs, there is a completely different firmware software solution to catching the FPU exceptions which is controlled by a bit in CPU register CR0
Quote
WhatCaseIsIt proc
fxam ;examine it
fstsw ax ;copy the content of the Status Word to AX
fwait ;insure the last instruction is completed
sahf ;copy the C3/C2/C0 condition codes to the ZF/PF/CF flags
jz C3is1 ;either Zero, Empty or Denormalized if C3=1
jpe C2is1 ;either normal or infinity if C3=0 and C2=1
jc isNAN
;
fn MessageBox, hDlg, "Dont know", "WhatCaseIsIt", MB_OK
ret
; code for the case of a NAN, no need to check the sign
isNAN:
fn MessageBox, hDlg, "NAN", "WhatCaseIsIt", MB_OK
ret
; would be Infinity if C3=0, C2=1 and C0=1
C2is1:
jc isINFINITY ;would be Infinity if C3=0, C2=1 and C0=1
;this leaves the case for a Normal finite number
test ah,2 ;test for the sign which is in bit1 of AH
jnz negNORMAL
;code for the case of a positive Normal finite number
fn MessageBox, hDlg, "positive Normal finite number", "WhatCaseIsIt", MB_OK
ret
; code for the case of a negative Normal finite number
negNORMAL:
fn MessageBox, hDlg, "negative Normal finite number", "WhatCaseIsIt", MB_OK
ret
isINFINITY:
test ah,2 ;test for the sign which is in bit1 of AH
jnz negINFINITY
; code for the case of a positive Infinity
fn MessageBox, hDlg, "positive Infinity", "WhatCaseIsIt", MB_OK
ret
negINFINITY:
;code for the case of a negative Infinity
fn MessageBox, hDlg, "negative Infinity", "WhatCaseIsIt", MB_OK
ret
; ------------------
; Stop HERE with ret
; ------------------
C3is1:
jc isEMPTY ;would be Empty if C3=1 and C0=1
jpe isDENORMAL ;would be a Denormalized number if C3=1, C0=0 and C2=1
;this leaves the case for a Zero value
;code for the case of a Zero value, no need to check sign
fn MessageBox, hDlg, "Zero value", "WhatCaseIsIt", MB_OK
ret
isEMPTY:
;code for the case of an Empty register
;which does not apply in this example because
;ST(0) was loaded with a value from memory
fn MessageBox, hDlg, "Empty register", "WhatCaseIsIt", MB_OK
ret
isDENORMAL:
test ah,2 ;test for the sign which is in bit1 of AH
jnz negDENORMAL
;code for the case of a positive Denormalized number
fn MessageBox, hDlg, "positive Denormalized number", "WhatCaseIsIt", MB_OK
ret
negDENORMAL:
;code for the case of a negative Denormalized number
fn MessageBox, hDlg, "negative Denormalized number", "WhatCaseIsIt", MB_OK
ret
WhatCaseIsIt endp
QuoteIt is not ambiguous ONLY because the calculator follows this rule:
Even that is ambiguous unless you use brackets. For example, 4^3^2 could be interpreted
as either (4^3)^2=46 or 4^(3^2)=49
QuoteYes it is the same you told us in the previous post:
you would get overflow but not necessarily an invalid operation at that point
QuoteIf i get the overflow first it does not go to this case
You may get an invalid operation if you try to reuse the INFINITY value with other
FPU instructions.
Quote
If you rely on the Fpulib to perform all your floating point computations...
Quote
there is a function (FpuExam) to test if a parameter is effectively INFINITY
if you have any doubt before proceeding with further computations.
Quotereal1^real2^real3^...^realN
QuoteTry to explain how do you write a procedure to compute
Just curious
QuoteIn this particular case the factors are
X=3 and Y=11623334155587.786
Quote
Which means that if you check for an invalid operation at the end of a series
of FPU instructions, that flag could have been raised by any of those
previous instructions and not necessarily by the last one.
Quote
A result of infinity would cause an Overflow exception but not always
raise the Invalid Operation flag.
Quote
fstsw ax ;retrieve exception flags from FPU
fwait
shr al,1 ;test for invalid operation
jc short _erro
;
; Ok, Go on
; ---------
...
clc
ret
;---------------
_erro: test ax, 0000100b
jnz _overflow
mov _ErrorZ, 1
stc
ret
_overflow: mov _ErrorZ, 2
stc
ret
Quote
dest0:
fxch ;set up FPU registers for next operation
fyl2x ;->log2(Src1)*exponent
;the FPU can compute the antilog only with the mantissa
;the characteristic of the logarithm must thus be removed
fld st(0) ;copy the logarithm
frndint ;keep only the characteristic
fsub st(1),st ;keeps only the mantissa
fxch ;get the mantissa on top
f2xm1 ;->2^(mantissa)-1
fld1
fadd ;add 1 back
;the number must now be readjusted for the characteristic of the logarithm
fscale ;scale it with the characteristic
fstsw ax ;retrieve exception flags from FPU
fwait
shr al,1 ;test for invalid operation
jc srcerr ;clean-up and return error