FCOMP
Usage: FCOMP src Modifies flags: See table below
Compares contents of register ST(0) and 'src' and sets condition code flags C0, C2, and C3 in the FPU status with the results. The source operand can be a data register or a memory location. If no source operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is ignored, so that -0.0 is equal to to 0.
Floating-Point Compare
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOM compares ST0 with the given operand, and sets the FPU flags accordingly. ST0 is treated as the left-hand side of the comparison, so that the carry flag is set (for a `less-than' result) if ST0 is less than the given operand.
FCOMP does the same as FCOM, but pops the register stack afterwards. FCOMPP compares ST0 with ST1 and then pops the register stack twice.
FCOMI and FCOMIP work like the corresponding forms of FCOM and FCOMP, but write their results directly to the CPU flags register rather than the FPU status word, so they can be immediately followed by conditional jump or conditional move instructions.
The FCOM instructions differ from the FUCOM instructions only in the way they handle quiet NaNs: FUCOM will handle them silently and set the condition code flags to an 'unordered' result, whereas FCOM will generate an exception.
FPU Flags Affected
Table FCOM/FCOMP/FCOMPP Flag Results
Condition C3 C2 C0
ST(0) >SRC 0 0 0
ST(0) <SRC 0 0 1
ST(0) =SRC 1 0 0
Unordered* 1 1 1
EXAMPLE:
fcomp Label
FCOMIP
Usage: FCOMIP src Modifies flags: See table below.
Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results. The sign of zero is ignored for comparisons, so that -0.0 is equal to +0.0.
Floating-Point Compare
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOM compares ST0 with the given operand, and sets the FPU flags accordingly. ST0 is treated as the left-hand side of the comparison, so that the carry flag is set (for a 'less-than' result) if ST0 is less than the given operand.
FCOMP does the same as FCOM, but pops the register stack afterwards. FCOMPP compares ST0 with ST1 and then pops the register stack twice.
FCOMI and FCOMIP work like the corresponding forms of FCOM and FCOMP, but write their results directly to the CPU flags register rather than the FPU status word, so they can be immediately followed by conditional jump or conditional move instructions.
The FCOM instructions differ from the FUCOM instructions only in the way they handle quiet NaNs: FUCOM will handle them silently and set the condition code flags to an unordered' result, whereas FCOM will generate an exception.
FPU Flags Affected
C1 Set to 0 if stack underflow occurred; otherwise, set to 0.
C0, C2, C3 Not affected.
Table FCOMI/FCOMIP/ FUCOMI/FUCOMIP Results
Comparison Results ZF PF CF
ST0 >ST(i) 0 0 0
ST0 <ST(i) 0 0 1
ST0 = ST(i) 1 0 0
Unordered* 1 1 1
EXAMPLE:
fcomip st0
FCOMI
Usage: FCOMI src Modifies flags: See table below.
Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results. The sign of zero is ignored for comparisons, so that -0.0 is equal to +0.0.
Floating-Point Compare
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOM compares ST0 with the given operand, and sets the FPU flags accordingly. ST0 is treated as the left-hand side of the comparison, so that the carry flag is set (for a 'less-than' result) if ST0 is less than the given operand.
FCOMP does the same as FCOM, but pops the register stack afterwards. FCOMPP compares ST0 with ST1 and then pops the register stack twice.
FCOMI and FCOMIP work like the corresponding forms of FCOM and FCOMP, but write their results directly to the CPU flags register rather than the FPU status word, so they can be immediately followed by conditional jump or conditional move instructions.
The FCOM instructions differ from the FUCOM instructions only in the way they handle quiet NaNs: FUCOM will handle them silently and set the condition code flags to an 'unordered' result, whereas FCOM will generate an exception.
FPU Flags Affected
C1 Set to 0 if stack underflow occurred; otherwise, set to 0.
C0, C2, C3 Not affected.
Table FCOMI/FCOMIP/ FUCOMI/FUCOMIP Results
Comparison Results ZF PF CF
ST0 >ST(i) 0 0 0
ST0 <ST(i) 0 0 1
ST0 =ST(i) 1 0 0
Unordered* 1 1 1
EXAMPLE:
fcomi st3
FCOM
Usage: FCOM src Modifies flags:See table below.
Compares contents of register ST(0) and 'src' and sets condition code flags C0, C2, and C3 in the FPU status with the results. The 'src' operand can be a data register or a memory location. If no 'src' operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is ignored, so that -0.0 is equal to to 0.
Floating-Point Compare
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOM compares ST0 with the given operand, and sets the FPU flags accordingly. ST0 is treated as the left-hand side of the comparison, so that the carry flag is set (for a 'less-than' result) if ST0 is less than the given operand.
FCOM ST0 and FCOM ST0 ST0 are the same thing.
FCOMP does the same as FCOM, but pops the register stack afterwards. FCOMPP compares ST0 with ST1 and then pops the register stack twice.
FCOMI and FCOMIP work like the corresponding forms of FCOM and FCOMP, but write their results directly to the CPU flags register rather than the FPU status word, so they can be immediately followed by conditional jump or conditional move instructions.
The FCOM instructions differ from the FUCOM instructions only in the way they handle quiet NaNs: FUCOM will handle them silently and set the condition code flags to an 'unordered' result, whereas FCOM will generate an exception.
Floating-Point Exceptions
Table FCOM/FCOMP/FCOMPP Flag Results
Condition C3 C2 C0
ST(0) >SRC 0 0 0
ST(0) <SRC 0 0 1
ST(0) =SRC 1 0 0
Unordered* 1 1 1
EXAMPLE:
fcom Label
FCMOVcc
Usage: FCMOVcc dest , src Modifies flags: See Below
Tests the status flags in the EFLAGS register and moves the 'src' operand to the 'dest' operand if the given test condition is true.
Floating-Point Conditional Move
FCMOVB fpureg ; DA C0+r [P6,FPU]
FCMOVB ST0,fpureg ; DA C0+r [P6,FPU]
FCMOVE fpureg ; DA C8+r [P6,FPU]
FCMOVE ST0,fpureg ; DA C8+r [P6,FPU]
FCMOVBE fpureg ; DA D0+r [P6,FPU]
FCMOVBE ST0,fpureg ; DA D0+r [P6,FPU]
FCMOVU fpureg ; DA D8+r [P6,FPU]
FCMOVU ST0,fpureg ; DA D8+r [P6,FPU]
FCMOVNB fpureg ; DB C0+r [P6,FPU]
FCMOVNB ST0,fpureg ; DB C0+r [P6,FPU]
FCMOVNE fpureg ; DB C8+r [P6,FPU]
FCMOVNE ST0,fpureg ; DB C8+r [P6,FPU]
FCMOVNBE fpureg ; DB D0+r [P6,FPU]
FCMOVNBE ST0,fpureg ; DB D0+r [P6,FPU]
FCMOVNU fpureg ; DB D8+r [P6,FPU]
FCMOVNU ST0,fpureg ; DB D8+r [P6,FPU]
The FCMOV instructions perform conditional move operations: each of them moves the contents of the given register into ST0 if its condition is satisfied, and does nothing if not.
The conditions are not the same as the standard condition codes used with conditional jump instructions. The conditions B, BE, NB, NBE, E and NE are exactly as normal, but none of the other standard ones are supported. Instead, the condition U and its counterpart NU are provided; the U condition is satisfied if the last two floating-point numbers compared were, i.e. they were not equal but neither one could be said to be greater than the other, for example if they were NaNs. (The flag state which signals this is the setting of the parity flag: so the U condition is notionally equivalent to PE, and
NU is equivalent to PO.)
The FCMOV conditions test the main processor's status flags, not the FPU status flags, so using FCMOV directly after FCOM will not work. Instead, you should either use FCOMI which writes directly to the main CPU flags word, or use FSTSW to extract the FPU flags.
Although the FCMOV instructions are flagged P6 above, they may not be supported by all Pentium Pro processors; the CPUID instruction () will return a bit which indicates whether conditional moves are supported.
FPU Flags Affected C1 Set to 0 if stack underflow occurred. C0, C2, C3 Undefined.
FCMOVE Floating-point conditional move if equal
FCMOVNE Floating-point conditional move if not equal
FCMOVB Floating-point conditional move if below
FCMOVBE Floating-point conditional move if below or equal
FCMOVNB Floating-point conditional move if not below
FCMOVNBE Floating-point conditional move if not below or equal
FCMOVU Floating-point conditional move if unordered
FCMOVNU Floating-point conditional move if not unordered
EXAMPLE:
fcmovbe st0, st4
FCLEX /FNCLEX
Usage: FCLEX / FNCLEX Modifies flags: None
The FCLEX instruction checks for and handles any pending unmasked floating-point exceptions before clearing the exception flags; the FNCLEX instruction does not.
Clear Floating-Point Exceptions
FCLEX ; 9B DB E2 [8086,FPU]
FNCLEX ; DB E2 [8086,FPU]
FCLEX clears any floating-point exceptions which may be pending. FNCLEX does the same thing but doesn't wait for previous floating-point operations (including the pending exceptions) to finish first.
The assembler issues two instructions for the FCLEX instruction (an FWAIT instruction followed by an FNCLEX instruction), and the processor executes each of these instructions separately. If an exception is generated for either of these instructions,
the saved EIP points to the instruction that caused the exception.
EXAMPLE:
fclex
fnclex
FCHS
Usage: FCHS Modifies flags: None
Complements the sign bit of ST(0). Changes a positive value into a negative value of equal magnitude or vice versa.
Floating-Point Change Sign
FCHS ; D9 E0 [8086,FPU]
FCHS negates the number in ST0, by inverting the sign bit: negative numbers become positive, and vice versa.
EXAMPLE:
fchs
FBSTP
Usage: FBSTP dest Modifies flags: None
BCD Floating-Point Load and Store
FBLD mem80 ; DF /4 [8086,FPU]
FBSTP mem80 ; DF /6 [8086,FPU]
FBLD loads an 80-bit (ten-byte) packed Binary-Coded Decimal number from the given memory address, converts it to a real, and pushes it on the register stack.
FBSTP stores the value of ST0, in packed BCD, at the given address and then pops the register stack.
The 'dest' operand specifies the address where the first byte destination value is to be stored. The BCD value (including its sign bit) requires 10 bytes of space in memory.
Converts the value in the ST0 register to an 18-digit packed BCD integer, stores the result in the destination operand, and pops the register stack. If the source value is a non-integral value, it is rounded to an integer value, according to rounding mode specified by the RC field of the FPU control word. To pop the register stack, the processor marks the ST0 register as empty and increments the stack pointer (TOP) by 1.
EXAMPLE:
fbstp Label
FBLD
Usage: FBLD src Modifies flags: None
BCD Floating-Point Load and Store
FBLD mem80 ; DF /4 [8086,FPU]
FBSTP mem80 ; DF /6 [8086,FPU]
FBLD loads an 80-bit (ten-byte) packed Binary-Coded Decimal number from the given memory address, converts it to a real, and pushes it on the FPU register stack.
FBSTP stores the value of ST0, in packed BCD, at the given address and then pops the register stack.
The packed BCD digits are assumed to be in the range 0 through 9, does not check for invalid digits. Attempting to load an invalid encoding produces an undefined result.
EXAMPLE:
fbld Label
FADDP
Usage: FADDP Dest , Src Modifies flags: None
Adds the 'dest' and 'src' operands and stores the sum in the 'dest' operand.
Floating-Point Addition
FADD mem32 ; D8 /0 [8086,FPU]
FADD mem64 ; DC /0 [8086,FPU]
FADD fpureg ; D8 C0+r [8086,FPU]
FADD ST0,fpureg ; D8 C0+r [8086,FPU]
FADD TO fpureg ; DC C0+r [8086,FPU]
FADD fpureg,ST0 ; DC C0+r [8086,FPU]
FADDP fpureg ; DE C0+r [8086,FPU]
FADDP fpureg,ST0 ; DE C0+r [8086,FPU]
FADD, given one operand, adds the operand to ST0 and stores the result back in ST0. If the operand has the TO modifier, the result is stored in the register given rather than in ST0.
FADDP performs the same function as FADD TO, but pops the register stack after storing the result.
Source operands in memory can be in single-precision or double-precision floating-point format or in word or doubleword integer format. The 'dest' operand is always an FPU register; the 'src' operand can be a register or a memory location.
The given two-operand forms are synonyms for the one-operand forms.
The no-operand version of the instruction adds the contents of the ST(0) register to the ST(1) register. The one-operand version adds the contents of a memory location (either a floating-point or an integer value) to the contents of the ST(0) register. The two operand version, adds the contents of the ST(0) register to the ST(i) register or vice versa.
To add an integer value to ST0, use the FIADD instruction.
C1 Set to 0 if stack underflow occurred. C0, C2, C3 Undefined.
FADD/FADDP/FIADD-Add
Opcode Instruction Description
D8 /0 FADD m32fp Add m32fp to ST(0) and store result in ST(0).
DC /0 FADD m64fp Add m64fp to ST(0) and store result in ST(0).
D8 C0 +i FADD ST(0), ST(i) Add ST(0) to ST(i) and store result in ST(0).
DC C0 +i FADD ST(i), ST(0) Add ST(i) to ST(0) and store result in ST(i).
DE C0 +i FADDP ST(i), ST(0) Add ST(0) to ST(i), store result in ST(i), and pop the register stack.
DE C1 FADDP Add ST(0) to ST(1), store result in ST(1), and pop the register stack.
DA /0 FIADD m32int Add m32int to ST(0) and store result in ST(0).
DE /0 FIADD m16int Add m16int to ST(0) and store result in ST(0).
EXAMPLE:
faddp Label
faddp to Label
faddp st0 ;Doubles the value in ST0.