We start refresh our memory about very basic math, and
discussion of optimal use of it in both FPU and integer machine arithmetics.
For those who new in either FPU or machine math here are very simple
advises how to start with FPU.
It is very premitive topic and meant to encorage you to start with FPU right
now.
1. Use debugger for your first exersizes.
- There is absolutly no nessesity to write full programms with user input and
output to train yourself in FPU.
Your template for any FPU exersize may look like this:
.386
.model flat,stdcall
option casemap:none
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
includelib kernel32.lib
;here is your data
.data
.data?
;here is your FPU code
.code
start:
.....
call ExitProcess ;include it at the end - it needed by most of debuggers
;without the call they cannot correctly load programms
end start.
--------------------
Compile your prog and load it into debug
I highly recommend to make fast loading into debuggers from your shell
(If I'm right Steve asmshell allows to do it very easy for example - there is
possibility to add to menu loading made programm into any programm tool)

Why debugger?
In debugger you can see all values, all changes in every step of calculation -
it already show you all values in FPU registers and it's already in decimal format
(at least TD32 do it)

I use TD32 to check something fast, and you can you Ollydbg wich is free and
show FPU,MMX,3Dnow registers.

Writing full programms to check some simple calc algo just slow down your learning
process giving nothing additional on FPU topics in return.
With debugger you can easilly write and check hundreds of code pieces.
-------------------------------------------------------
FPU use two types of data:
integer: the same as you use with add mul etc.
IEEE: to make your init data to be in the format just declare it
x real4 10.27 ;IEEE 4 bytes
y real8 1000.0 ;IEEE 8 bytes
z real10 0.17 ;IEEE 10 bytes
a real8 ?
-------------------------------------------------------

All mnemonins start with f
if one of operand is integer type the letter "i" is right after f

Example
fld x ;load into register ST(0) IEEE format data
.data
y dd 54
.code
fild y ;load integer into ST(0) the same as fld but with i after f
fadd a ;add to ST(0) memory value in IEEE format
fiadd b ;add to ST(0) memory value in integer format
fistp c ;convert IEEE format value in ST(0) to integer and pop it into c
fstp d ;pop IEEE format value into d in IEEE format
----------------------------------------------------------
Loading is always loading into ST(0) fld (for float),fild(integer)
----------------------------------------------------------
Basic arithmetics works always with ST(0) as one operand
and ST(?) or memory as other.
fadd fsub
fiadd fisub

fmul fdiv
fimul fidiv

fi may be only if one of operands is in memory and it is integer.
Result may be written in one of operand as long as it is ST(?) register.
In memory you can load result only by fst fstp after it has been strored in ST(0)

That's enough - be brave - write simple code, load into debug and step,
change operands, change commands and you'll see that it is very easy.

The most part you need to train yourself is arranging loading, calculations and
poping so that in the end you have an empty stack.

If anybody thinks that all I said is absolute bullshit and you can get the beginners
started much better - please, don't hesitate to teach them to start faster.

The sad news is that I know here are a lot of people that using assembly already for several months and yet afraid of FPU.
We need to change it ;)
Posted on 2002-02-08 16:39:45 by The Svin
how i do a 32Bits division using fpu instuctions? btw.... i wanna the cosient value if possible ("x.123" i wanna 123 to).

cyaz

jean / coder7345
Posted on 2002-02-08 18:43:29 by coder
What exactly do you mean by 32bits division. If you mean you have two 32 bit integer and want to divide them with fpu instuctions then follow The Svins advice above and use the integer FPU instructions;

fild Value1
fidiv Value2
fistp Result

Or if by 32 bit you mean real4 numbers then the same code as above but without the "i"'s will do that.

Regarding the second part, the short answer is that you can't use constants with the FPU. There are some ways around this, bitRAKEs fpc macro is probably the best, but ignore things like this until you're more experienced, they'll only confuse you.

The Svins advice is the best, play around with the FPU and you'll learn more than you'll learn from reading text after text. :alright:
Posted on 2002-02-08 19:09:13 by Eóin
Hi there!
thanks for the reply, and sorry for the delay. I was searching for something on the board about fpu and ...hey i posted on this thread :)

Now i understand the basics of fpu, i made a spelling mistake on the post. I said " wanna the cosient value " , was i wanna the rest of the division hehe. I may figure out how to solve that problem later (check if division has rest eg: 3/2 has, 2/2 not).

my first fpucode :alright:


Alfa dd 45.0f ;just to test
Resultado dd 0
px dd 76 ;just to test
py dd 58 ;just to test

Rotate2DPoint:
;x1 = px * cos(Alfa) - py * sin(Alfa)
;y1 = px * sen(Alfa) + py * cos(Alfa)
FINIT
FLD dword [Alfa]
FCOS
FIMUL dword [px] ;Parte 1 feita..
FLD dword [Alfa]
FSIN
FIMUL dword [py] ;Parte 2 feita...
FSUBP st1, st
FISTP dword [Resultado] ;subtrair os 2 | pop o ST1 para resultado em int
mov eax, dword [Resultado]
ret

Its not finished as u can see, but no problem.. :)

I've a question, i can use eax or a 32bits register with fpu instructions ?
I'm thinking in put the px in eax, and py in ebx, i've to move them to some var in mem, soo i can use them with fpu ?

cya
Posted on 2002-08-24 01:23:13 by coder
you can't use interger registers (eax,ebx,ecx,edx ect.) with the FPU. to move data between the two you must use memory....
Posted on 2002-08-24 10:56:09 by MArtial_Code
but i can use for example, fld dword ?
Posted on 2002-08-24 11:16:54 by coder
fld dword is a memory operand.

Regards,

hutch@movsd.com
Posted on 2002-08-24 21:42:05 by hutch--
You also could use the FCOMI instruction to modify the EFLAGS register directly but u need a >= PPro CPU.
Posted on 2002-08-28 20:12:50 by x86asm

Hi there!
thanks for the reply, and sorry for the delay. I was searching for something on the board about fpu and ...hey i posted on this thread :)

Now i understand the basics of fpu, i made a spelling mistake on the post. I said " wanna the cosient value " , was i wanna the rest of the division hehe. I may figure out how to solve that problem later (check if division has rest eg: 3/2 has, 2/2 not).

my first fpucode :alright:


Alfa dd 45.0f ;just to test
Resultado dd 0
px dd 76 ;just to test
py dd 58 ;just to test

Rotate2DPoint:
;x1 = px * cos(Alfa) - py * sin(Alfa)
;y1 = px * sen(Alfa) + py * cos(Alfa)
FINIT
FLD dword [Alfa]
FCOS
FIMUL dword [px] ;Parte 1 feita..
FLD dword [Alfa]
FSIN
FIMUL dword [py] ;Parte 2 feita...
FSUBP st1, st
FISTP dword [Resultado] ;subtrair os 2 | pop o ST1 para resultado em int
mov eax, dword [Resultado]
ret

Its not finished as u can see, but no problem.. :)

I've a question, i can use eax or a 32bits register with fpu instructions ?
I'm thinking in put the px in eax, and py in ebx, i've to move them to some var in mem, soo i can use them with fpu ?

cya


I dont think you have to use the FINIT instruction in ur code, on most processors it flushes the queue and you dont want that to happen.
Posted on 2002-08-28 20:26:32 by x86asm
FINIT is not necessary in Win32, but it is in DOS because it doesn't even know what an FPU is and thus, its not initalized.
Posted on 2002-08-28 22:46:35 by comrade
One thing one should remember about the fpu unit and this is in the intel manuals. The fpu unit only provides for a subset of the real number system and therefore has limitations. If your looking for extreme accuracy don't rely on the fpu. Make your own algorithm.

:alright:
Posted on 2002-08-28 22:55:40 by IwasTitan
thanks for the replies :alright:
ok, soo i'll not use FINIT on this "algo" .. :)

cya
Posted on 2002-08-29 10:10:11 by coder