News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Overflow problem

Started by Joao Batista, November 27, 2012, 03:17:26 AM

Previous topic - Next topic

dedndave

ok - but read the rest of that post   :P

Joao Batista

Hi, i still can't make this work :S

can you just give me a super simple example.. using dq, of how to check for add overflow on the fpu and jump to another tag?

i tried everything u told me to :S

i must be doing somehing wrong :S

tried this
FLD cte1
FLD cte2

FADD
fstsw WORD PTR fpu_status
    test fpu_status, FEX_OVERFLOW
    jz OVER


tried this

FLD cte0
FLD cte6


FCOMI ST,ST(0)
fwait
Jc OVER


and so on.. :S

dedndave

in your program, you may want to do an FINIT and set the precision
under windows, when a program is loaded, i think it is initialized and set to double precision (8 byte)
FINIT sets it to extended real (10 byte)
that is just something to note - may not be your problem
once you have that set up.....

    fld     cte1
    fld     cte2
    fadd
    fstsw   ax
    test    al,FEX_OVERFLOW
    jnz     OverFlow_Occured


use something like 1.78E308 for both cte1 and cte2 - that should cause an overflow

Joao Batista

Quote from: dedndave on November 28, 2012, 11:25:49 AM
in your program, you may want to do an FINIT and set the precision
under windows, when a program is loaded, i think it is initialized and set to double precision (8 byte)
FINIT sets it to extended real (10 byte)
that is just something to note - may not be your problem
once you have that set up.....

    fld     cte1
    fld     cte2
    fadd
    fstsw   ax
    test    al,FEX_OVERFLOW
    jnz     OverFlow_Occured


use 1.78E308 for both cte1 and cte2 - that should cause an overflow

just tried this and doesnt work :S

And just when you just told me that, i was trying to do what ray's tutorial says..

cte0 dq 1.39769e+308
cte6 dq 1.79769e+308
.code
start:

FLD cte0
FLD cte6
FADD
fstsw ax
fwait
sahf
JC OVER


this seems perfect.. but doesn't work :S

fld loads cte0 and 6 in st
then i add them
fstsw ax is supposed to store the flags on ax register
fwait .. wait while fpu is busy
sahf is supposed to "pass" fpu flags to cpu..
JC OVER is supposed to jump if the carry flag is up

:( what's wrong??

dedndave

hmmmmm
the FPU is using REAL10 format, internally - which it always does except for integer and bcd values
perhaps you won't get an overflow until you try to store it into a REAL8 - lol

another way to try it would be to go ahead and do an FINIT
that sets it to REAL10 precision
then test to see if you can cause an overflow using REAL10's
the max value is about 1.19E4932
so, you can add 1.0E4932 to itself to get an overflow

dedndave

as you can see, most of us have never tried to overflow the FPU   :lol:
we generally have our hands full testing for equality or "near-equality"

Joao Batista

Yeah is not that we are trying to make it overflow.. i have to test if our code works XD

like this!!

.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include    \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
include    \masm32\include\debug.inc
includelib \masm32\lib\debug.lib

FEX_OVERFLOW equ 8

.data
nombre db "Compilador",0
DIV0 db "Termino",0
EOVER db "Error: Overflow en la suma",0
cte0 dq 1.78E308
cte6 dq 1.78E308
.code
start:
FINIT
FWAIT
FLD cte0
FLD cte6
FADD
fstsw ax
fwait
sahf
JC OVER
JMP EDIV0

invoke ExitProcess,0
EDIV0:
invoke MessageBox, NULL, addr DIV0, addr nombre, MB_OK
JMP ABORT
OVER:
invoke MessageBox, NULL, addr EOVER, addr nombre, MB_OK
JMP ABORT
ABORT:
invoke ExitProcess,1
end start


This doesn't work! and we don't know why!! :P

Thing is, my profesor will test our code with a 1.78E308 + 1.78E308 value and our program should show a message saying hey.. fpu overflowed .. :(

qWord

As dave said, the OF exception occurs when you store the value. A simple approach would be to test the result for NaN after it has been stored in memory (requires that the input values are valid):
mov eax,DWORD ptr r8Var[4]
and eax,7FF00000h
xor eax,7FF00000h
jz @error


EDIT: code changed
MREAL macros - when you need floating point arithmetic while assembling!

Joao Batista

O.o i didn't understand a single word of that code lol

where do i add it on my code? hahaha

Quote from: qWord on November 28, 2012, 11:45:52 AM
As dave said, the OF exception occurs when you store the value. A simple approach would be to test the result for NaN after it has been stored in memory (requires that the input values are valid):
and DWORD ptr r8Var[4],7FF00000h
xor DWORD ptr r8Var[4],7FF00000h
jz @error


qWord

.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include    \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
include    \masm32\include\debug.inc
includelib \masm32\lib\debug.lib

FEX_OVERFLOW equ 8

.data
nombre db "Compilador",0
DIV0 db "Termino",0
EOVER db "Error: Overflow en la suma",0
cte0 dq 1.78E308
cte6 dq 0
result dq ?
.code
start:
FINIT
FWAIT
FLD cte0
FLD cte6
FADDp
fstp result
mov eax,DWORD ptr result[4]
and eax,7FF00000h
xor eax,7FF00000h
jz OVER
JMP EDIV0

invoke ExitProcess,0
EDIV0:
invoke MessageBox, NULL, addr DIV0, addr nombre, MB_OK
JMP ABORT
OVER:
invoke MessageBox, NULL, addr EOVER, addr nombre, MB_OK
JMP ABORT
ABORT:
invoke ExitProcess,1
end start

As said, this method makes only sense if the input values are validated (and not NaN themself)
MREAL macros - when you need floating point arithmetic while assembling!

qWord

BTW, what you can also do is to unmask the wished exceptions and then enclose you calculation by corresponding exception handler (SEH).
MREAL macros - when you need floating point arithmetic while assembling!

Joao Batista

Quote from: qWord on November 28, 2012, 11:54:26 AM
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include    \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
include    \masm32\include\debug.inc
includelib \masm32\lib\debug.lib

FEX_OVERFLOW equ 8

.data
nombre db "Compilador",0
DIV0 db "Termino",0
EOVER db "Error: Overflow en la suma",0
cte0 dq 1.78E308
cte6 dq 0
result dq ?
.code
start:
FINIT
FWAIT
FLD cte0
FLD cte6
FADDp
fstp result
mov eax,DWORD ptr result[4]
and eax,7FF00000h
xor eax,7FF00000h
jz OVER
JMP EDIV0

invoke ExitProcess,0
EDIV0:
invoke MessageBox, NULL, addr DIV0, addr nombre, MB_OK
JMP ABORT
OVER:
invoke MessageBox, NULL, addr EOVER, addr nombre, MB_OK
JMP ABORT
ABORT:
invoke ExitProcess,1
end start

As said, this method makes only sense if the input values are validated (and not NaN themself)

so basically.. u have to store the value to make the overflow? O.o

btw.. that worked with a FADD instead of a FADDP .. :D

So. thank you very very much!!!

jj2007

Quote from: Joao Batista on November 28, 2012, 12:01:40 PM
btw.. that worked with a FADD instead of a FADDP .. :D

Yes it does but it leaves a value in the FPU. Do that 8 times, e.g. in a loop, and the FPU chokes. And you have a bug that can be chased only with Olly...

FORTRANS

Quote from: jj2007 on November 28, 2012, 05:20:41 PM
Quote from: Joao Batista on November 28, 2012, 12:01:40 PM
btw.. that worked with a FADD instead of a FADDP .. :D

Yes it does but it leaves a value in the FPU. Do that 8 times, e.g. in a loop, and the FPU chokes. And you have a bug that can be chased only with Olly...

Hi,

   Yes, but using FADD with no operands is a special case.
It defaults to adding ST and ST(1) and then popping.  ST
is ST(0) as well.  It's a MASM (and other assemblers) thing.



0005  9B DC C1         FADD    ST(1),ST
0008  9B DE C1         FADDP   ST(1),ST
000B  9B DE C1         FADD



Regards,

Steve N.

jj2007

Quote from: FORTRANS on November 30, 2012, 04:05:59 AM
using FADD with no operands .. defaults to adding ST and ST(1) and then popping.

Interesting, thanks Steve :t