Contents
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.
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 |
| 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)