The Floating Point Unit (FPU)

From ASM Book

Jump to: navigation, search

The x87 coprocessor, or the floating-point unit (FPU), executes approximately 70 instructions. This chapter will describe the instruction set of the FPU up to the Pentium processor. It includes the data transfer, arithmetic, comparison, transcendental, and constant instructions. The FPU can be very useful for performing calculation and mathematics heavy applications such as 3D graphics and audio processing.

The FPU uses a different system for moving data around in the processor. Instead of using named registers, like the CPU, it uses a stack. The stack is refered to as ST(x) where x is a position on the stack. This causes a lot of confusion to newcomers because unlike programming on the main CPU, where eax is always eax, when you move data into a register on the FPU, everything below it moves down, and you need to keep track of your register stack at all times.

Throughout this article, ST(0) will be used to represent the top of the FPU stack, though many people refer to it as ST without a number.

The FPU also contains a status register, who's purpose is to hold status flags for operations like comparison, bit test operations, etc. The FSTSW instruction moves the status word register into the CPU, so you can use it for flow controll, exception detection, and response, and the like.

Contents

FPU Data Formats

The FPU uses 3 different types of data: signed integer, BCD, and floating point. The following table shows the various data types used by the FPU along with their sizes and approximate ranges.

Type Length Range
Type Length Range
Word Integer 16-bit -32,768 to 32,767
Short Integer 32-bit -2.14e9 to 2.14e9
Long Integer 64-bit -9.22e18 to 9.22e18
Single Real 32 bit 1.18e-38 to 3.40e38
Double Real 64 bit 2.23e-308 to 1.79e308
Extended Real 80 bit 3.37e-4932 to 1.18e4932
Packed BCD 80 bit -1e18 to 1e18

Signed Integers

Positive signed integers are stored in normal format, with the left-most sign bit set to 0. Negative numbers are stored in 2's-complement form, with the left-most sign bit equal to 1. Following shows how to define the various integer types, and what their binary representations are
;--------------------------+----------------------+
; Definition               |     Hexadecimal      |
;-------------------------------------------------+
var1   dw        24        ;     0024             |
var2   dw        -2        ;     FFFE             |
var3   dd        1234      ;     000004D2         |
var4   dd        -123      ;     FFFFFF85         |
var5   dq        9876      ;     0000000000002694 |
var6   dq        -321      ;     FFFFFFFFFFFFFEBF |
;+------------------------------------------------+

Binary-Coded Decimal (BCD)

BCD numbers are 10-bytes in size. Each number is stored as 18 digits, with 2 digits per byte. The highest order byte stores the sign of the number, with the highest order bit of this byte being the sign bit. Note that both positive and negative numbers are stored in true form, and not in complemented form.

+----------+-----+-----+-----+-----+-----+-----+-----+-----+----+----+----+----+----+----+----+----+----+----+
| Sign bit | D17 | D16 | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
+----------+-----+-----+-----+-----+-----+-----+-----+-----+----+----+----+----+----+----+----+----+----+----+
79                                                                                                           0

List of FPU Instructions

This list of instructions was compiled from Ray Filiatreault's online floating point tutorial.

F2XM1     2 to the X power minus 1
FABS      Absolute value of ST(0)
FADD      Add two floating point values
FADDP     Add two floating point values and pop ST(0)
FBLD      Load BCD data from memory
FBSTP     Store BCD data to memory
FCHS      Change the sign of ST(0)
FCLEX     Clear exceptions
FCMOVcc*  Conditional move based on CPU flags
FCOM      Compare ST(0) to a floating point value
FCOMI     Compare ST(0) to ST(i) and set CPU flags
FCOMIP    Compare ST(0) to ST(i) and set CPU flags and pop ST(0)
FCOMP     Compare ST(0) to a floating point value and pop ST(0)
FCOMPP    Compare ST(0) to ST(1) and pop both registers
FCOS      Cosine of the angle value in ST(0)
FDECSTP   Decrease stack pointer
FDIV      Divide two floating point values
FDIVP     Divide two floating point values and pop ST(0)
FDIVR     Divide in reverse two floating point values
FDIVRP    Divide in reverse two floating point values and pop ST(0)
FFREE     Free a data register
FIADD     Add an Integer located in memory to ST(0)
FICOM     Compare ST(0) to an integer value
FICOMP    Compare ST(0) to an integer value and pop ST(0)
FIDIV     Divide ST(0) by an Integer located in memory
FIDIVR    Divide an Integer located in memory by ST(0)
FILD      Load integer from memory
FIMUL     Multiply ST(0) by an Integer located in memory
FINCSTP   Increase stack pointer
FINIT     Initialize the FPU
FIST      Store integer to memory
FISTP     Store integer to memory and pop ST(0)
FISUB     Subtract an Integer located in memory from ST(0)
FISUBR    Subtract ST(0) from an Integer located in memory
FLD       Load real number
FLD1      Load the value of 1
FLDCW     Load control word
FLDENV    LoaD environment
FLDL2E    Load the log base 2 of e (Napierian constant)
FLDL2T    Load the log base 2 of Ten
FLDLG2    Load the log base 10 of 2 (common log of 2)
FLDLN2    Load the log base e of 2 (natural log of 2)
FLDPI     Load the value of PI
FLDZ      Load the value of Zero
FMUL      Multiply two floating point values
FMULP     Multiply two floating point values and pop ST(0)
FNCLEX    Clear exceptions (no wait)
FNINIT    Initialize the FPU (no wait)
FNOP      No operation
FNSAVE    Save state of FPU (no wait)
FNSTCW    Store control word (no wait)
FNSTENV   Store environment (no wait)
FNSTSW    Store status word (no wait)
FPATAN    Partial arctangent of the ratio ST(1)/ST(0)
FPREM     Partial remainder
FPREM1    Partial remainder 1
FPTAN     Partial tangent of the angle value in ST(0)
FRNDINT   Round ST(0) to an integer
FRSTOR    Restore all registers
FSAVE     Save state of FPU
FSCALE    Scale ST(0) by ST(1)
FSIN      Sine of the angle value in ST(0)
FSINCOS   Sine and cosine of the angle value in ST(0)
FSQRT     Square root of ST(0)
FST       Store real number
FSTCW     Store control word
FSTENV    Store environment
FSTP      Store real number and pop ST(0)
FSTSW     Store status word
FSUB      Subtract two floating point values
FSUBP     Subtract two floating point values and pop ST(0)
FSUBR     Subtract in reverse two floating point values
FSUBRP    Subtract in reverse two floating point values and Pop ST(0)
FTST      Test ST(0) by comparing it to +0.0
FUCOM     Unordered Compare ST(0) to a floating point value
FUCOMI    Unordered Compare ST(0) to ST(i) and set CPU flags
FUCOMIP   Unordered Compare ST(0) to ST(i) and set CPU flags and pop ST(0)
FUCOMP    Unordered Compare ST(0) to a floating point value and pop ST(0)
FUCOMPP   Unordered Compare ST(0) to ST(1) and pop both registers
FWAIT     Wait while FPU is busy
FXAM      Examine the content of ST(0)
FXCH      Exchange the top data register with another data register
FXTRACT   Extract exponent and significand
FYL2X     Y*Log2X
FYL2XP1   Y*Log2(X+1)

* cc refers to any of these variations
FCMOVB       Move if below (CF=1)
FCMOVE       Move if equal (ZF=1)
FCMOVBE      Move if below or equal (CF=1 or ZF=1)
FCMOVU       Move if unordered (PF=1)
FCMOVNB      Move if not below (CF=0)
FCMOVNE      Move if not equal (ZF=0)
FCMOVNBE     Move if not below or equal (CF=0 and ZF=0)
FCMOVNU      Move if not unordered (PF=0)
Personal tools