Toby Opferman
http://www.opferman.net
programming@opferman.net
387 FPU Tutorial
Anyone who programs in assembly knows that the CPU is an
integer machine. It can only deal with Non-Floating point numbers.
Many of the older machines emulate floating point which is slow.
Why emulate Floating Point numbers now or why use fixed point math
and such when the FPU is SOOOO much faster. The FPU can even do
integer operatoins much faster than the CPU now. The FPU is so easy to
use as well as you will see.
The FPU is a stack based processor. It does operatoins on
stack elements. These Elements are labeled ST(0)-ST(7). Each location
is 80 bits. In Turbo Debugger, to view the stack go to:
VIEW -> NUMERIC PROCESSOR
It show the IEEE Hex Format of the Number in 80 bits (10 Bytes) and will also
show the decimal number to the side (I.E. 45.393 or whatever). To declare
a float number in your program do the following (I use TASM 5.0):
FloatNumber2 dd 393.33 ; 4 Byte Float
FloatNumber3 dt 393.393993 ; 10 Byte Float
The Assembler will automatically put them in IEEE Float Format.
If the number is a whole number and you want it a float, just make sure
you do 135.0
Before you begin using the FPU, in your program you must put
.387
at top or somewhere when you are going to use FPU. That is
the directive to make the assembler assemble for the FPU (If
your assembler supports it).
To use the FPU in it's simpliest form, quick calculations
All the FPU instructoins require that 1 of the operands must be the stack.
If no operands are suppilied, the default is
ST = ST(1) op ST
FADD = FADD ST(1), ST
You can pair ST with any of the registers
FADD ST,ST(n)
FADD ST(n),ST
You can also do registers or Variables.
FADD FloatVar
FADD TBYTE PTR [SI] ; Ten Bytes
FADD DWORD PTR [DI] ; Four Bytes
The Integer instructions have an I after the F.
Example:
FILD Integer
FIADD Integer2
FISTP Integer
That is Integer = Integer + Integer2
This is the easiest way to use the FPU.
PUSH The Value
OPERATION With A Value
POP The Value
It's also easy to change a Float to an Integer:
Float dt 343.33 ; 10 Byte Float
Integer dd 0 ; 4 Byte Integer
FLD Float ; Load Float
FISTP Integer ; Pop Float
It's That Easy!
Here is a list of the instructoins for the FPU:
Experament with them as u need.
FBLD Loads BCD Number
FBSTP Stores And Pops a BCD Number
FILD Loads An Integer
FIST Stores an Integer
FISTP Stores an Integer and Pops The Stack
FLD Loads A Float
FSTP Stores a Float and Pops the Stack
FST Stores A Float
FXCH Exchanges two stack elements
FABS Computes Absoulte Value
FADD Adds 2 Floats
FIADD Adds 2 Integers
FADDP Adds real Numbers and Pops the stack
FCHS Change Sign of Number
FDIV Divides 2 Floats
FIDIV Divides 2 Integers
FDIVP Divides 2 Floats and Pops the stack
FDIVR Divides 2 Floats but Reverses the dividend and divisor
FIDIVR Same as above with Integers
FDIVRP Divide real numbers, reverse order and pop stack
FMUL Multiply 2 Floats
FIMUL Multiply 2 Integers
FMULP Multiply 2 Floats and Pop Stack
FPREM Computes Partial Remainder
FPREM1 Computes Partial Remainder using IEEE Format
FRNDINT Rounds the Operand to an Integer
FSCALE Scales by a power of 2
FSUB Subtracts real numbers
FISUB subtracts integers
FSUBP Subtracts real numbers & pops stack
FSUBR Subtracts real number in reverse order
FISUBR Subtracts integers in revers order
FSUBRP Subtracts real numbers in revese order and pops the stack
FSQRT Computes the square root
FXTRACT Extracts the exponents and significand from real number
All Angles in Radians!!
F2XM1 Computes the value 2x-1
FCOS Computes the Cosine
FPATAN Computes partial arctangent
FPTAN Computes partial tangent
FSIN Computes Sine
FSINCOS Computes Sine and Cosine
FYL2X Compues the expression y*log2(x)
FYL2XP1 Computes the expressoin y*log2(x+1)
Constants Loading onto stack
FLD1 Loads a 1.0
FLDL2E Loads Log2(e)
FLDL2T loads Log2(10)
FLDLG2 Loads Log10(2)
FLDPI Loads PI
FLDZ Loads 0
FCOM Compares real numbers
FCOMP Compares real numbers & pops the stack
FCOMPP Compares real numbers & pops the stack twice
FICOM Compares integers
FICOMP Compares integers and pops the stack
FTST Compares top of stack to 0
FUCOM Performs an Unordered compare
FUCOMP Performs an Unordered compare and pops the stack
FUCOMPP Performs an unordered compare and pops the stack 2x
FXAM Set condition bits for value at top of stack
FCLEX Clears all unmasked floating point exceptoins
FNCLEX Clears all exceptions
FDECSTP Decrements the stack pointer
FFREE Clears a stack element, making it seem as if it was poped
FINCSTP Incremtns the stack pointer
FINIT Initalizes 387 and checks for exceptions
FNINIT Initalizes 387 w/o checking for exceptions
FLDCW Loads the Control word
FLDENV Loads the 387 Enviroment
FNOP Equivlent to NOP
FRSTOR Restores the state of the 387 with a given memory area
FSAVE Saves the state of the 387 to memory and checks for
excpetions
FNSAVE Saves the state of the 387 to memory w/o checking
for exceptions
FSTCW Stores the control word and checks for exceptions
FNSTCW Stores the Control word w/o checking for excpetoins
FSTENV Stores the enviroment and checks for exceptoins
FNSTENV Stores the enviroment w/o checking for exceptions
FSTSW Stores the status word and checks for exceptions
FNSTSW Stores the status word w/o checking for excpetoins
FSTSW AX Stores the status word into AX and checks for excpetoins
FNSTSW AX Stores the status word int AX w/o checking for excpetoins
WAIT Suspends the CPU until the 387 is finished with operatoin.
(Thanx to "Black Art of 3D Programming" for suppling the list)
That's all there is to it. I'm not going to go into the complexities of the
FPU, this was just a general overview so you can easily use the FPU in
your asm programs with ease as if you were using C.