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.