Professional Documents
Culture Documents
8087 Coprocessor
8087 Coprocessor
Overview:
Many microcomputer programs, such as those used for scientific research, engineering, business, and
graphics, need to make mathematical calculations such as computing the square root of a number, the
tangent of a number, or the log of a number.
Another common need is to do arithmetic operations on very large and very small numbers. There are
several ways to do all this.
One way is to write number-crunching part of the program in a high-level language such as FORTRAN,
compile this part of the code, and link in I/O modules written in assembly language. The difficulty with
this approach is that programs written in high level languages tend to run considerably slower than the
programs written in assembly language.
Second way is to write an assembly language program which uses the normal instruction set of the
processor to do the arithmetic functions. Reference books which contain the algorithms for these are
readily available. But it is often time consuming to get from the algorithm to a working assembly
language program.
Third way is to buy a library of floating point arithmetic object modules from the manufacturer of the
microprocessor we working with or from an independent software house. Then in program, just declare
a procedure needed from the library as external, call the procedure as required, and link the library
object code files for the procedure to the object code for the program. This spare the labor of writing all
the procedure.
In an application we need a calculation to be done as quickly as possible, however all previous
approaches have problems.
The architecture and instruction set of the general purpose microprocessor such as 8086 are not
designed to do complex mathematical operations efficiently. Therefore , even highly optimized number
crunching programs run slowly on the general purpose machines.
To solve this problem, special processors with architectures and instruction sets optimized for numbercrunching is developed. Eg: Intel 8087 math processor.
THE 8087 NUMERIC DATA PROCESSOR:
It is specially designed to perform arithmetic operations efficiently, used in parallel with the main
processor in a system rather than serving as a main processor itself. Therefore it is called as a
coprocessor.
The major principle here is the main processor such as 8086 handles the general program execution and
the 8087 coprocessor handles specialized math computations. An 8087 instructions may perform given
mathematical computation 100 times faster than the equivalent sequence of 8086 instructions.
The 8087 is an actual processor with its own specialized instruction set. It can operate on data of the
integer, decimal, and real types with lengths ranging from 2 to 10 bytes.
The instruction set not only includes various forms of addition, subtraction, multiplication, and division,
but also provides many useful functions, such as taking the square root, exponentiation, taking the
tangent and so on.
Eg: the 8087 can multiply two 64-bit real numbers in about 27 us (for 8086, 2 ms) and calculate a square
root in about 36 us (for 8086, 20ms).
The 8087 provides simple and effective way to enhance the performance of an 8086/8088 based system,
particularly when an application is primarily computational in nature.
The NDP cannot fetch its own instructions and therefore must operate with either an 8086/8088, which
acts as the host in a coprocessor configuration. The interfacing between the host and the NDP simply
requires connections between the corresponding pins of the two processors.
Instructions of 8087 are written in a program as needed with the 8086/8088. When the program is
assembled, the opcodes for 8087 instructions are put in memory right along with the codes for
8086/8088 instructions.
As the 8086/8088 fetches instruction bytes from memory and puts them in its queue, the 8087 also reads
these instruction bytes and puts them in its internal queue. The 8087 decodes each instruction that comes
into its queue.
When 8087 decodes an instruction from its queue and finds that it is an 8086 instruction, the 8087
simply treats the instruction as an NOP. Similarly when an 8086/8088 decodes an instruction from its
queue and finds that it is an 8087 instruction, the 8086 treats the instruction as NOP or in some cases
reads a data word from memory for the 8087.
Each processor decodes all the instructions in the fetched instruction byte stream but executes only its
own instruction. How do the two processors recognize the 8087 instruction is, all the 8087 instruction
codes have 11011 as the most significant bits of their first code byte.
8087 Data Types:
The 8087 can operate on memory operands of seven different data types: word integer, short integer,
long integer, packed BCD, short real, long real, temporary real. In memory, the least significant byte of
a number is always stored in the lowest address.
The number of bytes, format, and approximate range for each of these data types are shown below.
Data Types:
Bytes:
Word Integer
Short Integer
Long Integer
Packed BCD
10
Short Real
Long Real
Temporary
Real
Approximate
Range (decimal):
-32,768 to
32,767
-2 x 109 to
2 x 109
-9 x 1018 to
9 x 1018
-1018 + 1 to
1018 -1
1 x 10-38 to
3 x 1038
10-308 to 10308
-4932
10
10
to
4932
10
Format:
S
Magnitude
15
0
S
Magnitude
32
S
Magnitude
63
S
0
D17 D16
79 78
72
71
S
E
F
31 30
23 22
S
E
F
63 62
52 51
S
E
79 78
64 63
0
0
D1 D0
0
0
0
F
0
Because 1 is always present before the fraction, it implied and is not physically stored.
0
Sign
Biased Exponent
=4136000h
Fraction
For short real data type, the valid range of the biased exponent is 0 < E < 255, then the numbers can be
represented are from 2-126 to 2128, approximately 1 x 10-38 to 3 x 1038.
A biased exponent of all 1s is reserved to represent infinity or not a number (NAN), a biased
exponent of all 0s is used to represent +0 (all 0s with a + sign), -0 (all 0s with - sign) or a denormal.
A denormal is a result that causes an underflow and has leading 0s in the mantissa even after exponent
is adjusted to its smallest possible value.
NANs and denormal are normally used to represent overflows and underflows respectively, although
they may be used for other purposes.
Long real:
The long real format has 11 exponent bits and 52 mantissa bits. Again the first nonzero bit in the
mantissa is implied and not stored. The range of representable nonzero quantities is approximately
10-308 to 10308.
The offset added to each exponent is 1023 or 3FFh, the most significant bit is sign bit. This format is
often called as double precision representation, it is basically same as short real format except that it
allows greater range and accuracy.
Temporary real:
The 8087 internally stores all numbers in temporary real format which uses 15 bits for the exponent and
64 bits for mantissa. The offset added to each exponent is 3FFFh, the most significant bit is sign bit.
Unlike in short real and long real formats, the most significant bit in the mantissa is actually stored.
Because of the extended precision (19 to 20 decimal digits), integer and packed BCD operands can be
operated on internally using floating point arithmetic and still yield exact results.
A primary reason for using the temporary real format for internal data storage is to reduce the chances
for overflows and underflows during a series of calculations which produces a final result that is within
the required range.
Eg: D = (A*B)/C where A, B, C, and D are in the short real format. The multiplication may yield a
result which is too large to be represented in the short real format, but the final result after the division
by C, may be still within the valid range.
The 15 bit exponent of the temporary real format extends the range of valid to approximately 104932,
so for most applications the user need not to worry about overflows and underflows in the intermediate
calculations.
Storing Floating Point Data in Memory:
Floating point numbers are stored with the assembler using DD directive for single precision, DQ for
double precision, and DT for extended temporary precision.
The Microsoft macro assembler contains an error that doesnt allow a plus sign to be used with positive
floating-point numbers. A +92.45 must be defined as 92.45 for the assembler to function correctly.
This error has been corrected in version 6.11 of MASM if the REAL4, REAL8, or REAL10 directives
are used in place of DD, DQ, and DT to specify floating point data.
Examples:
0000 C377999A
0004 C0000000
0008 486F4200
000C 4059100000000000
0014 3F543BF727136A40
001C 400487F34D6A161E4F76
DATA7 DD -247.6
DATA8 DD 2.0
DATA9 REAL4
-247.6
DATAA DQ 100.25
DATAB REAL8
0.001235
DATAB REAL10
33.9876
;single-precision
;single-precision
;single-precision
;double-precision
;double-precision
;double-precision
8087 ARCHITECTURE:
The monitor and control logic maintains a 6-bye instruction queue (only 4-bytes are used if operated in
conjunction with the 8088) and tracks the instruction execution sequence of the host.
If the instruction currently being executed by the host is an ESC instruction, the 8087 decodes the
external opcode to perform the specified operation, and also captures the operand and operand address.
The instruction other than ESC instruction is simply ignored by the 8087. The 8087 works internally
with all numbers in the 80-bit temporary real format. To hold numbers being worked, the 8087 has a
register stack of eight 80-bit data registers labeled (0) to (7).
These registers are used as a last-in-first stack. The 8087 has 3 bit stack pointer to holds the number of
register that is the current top-of-stack (TOS).
5V
Vcc
Tag registers
0
TAG (0)
TAG (1)
TAG (2)
TAG (3)
TAG (4)
TAG (5)
TAG (6)
TAG (7)
CLK
INT
AD15 AD0
Floating point
arithmetic module
A19/S6A16/S3
BHE/S7
BUSY
C2 C1 C0 IR X P
Status Register
X IC
RC
PC
IEM X PM UM
Control Register
11 LSBs of op code
16 LSB's of operand address
READY
RESET
ST
0
I
X: Reserved
S 2 - S 0
QS1 - QS0
R Q/G T0
R Q/G T1
15
B C3
4 LSBs of
operand
address
OM ZM DM IM
Instruction
Pointer
Operand
Pointer
Vss
When it is initialized, the 3 bit stack pointer (the ST bits which are bits 13, 12, and 11 of the status
register) is loaded with 000, so register 0 is then the TOS. When it reads first number that it is going to
work on from memory, it converts it to 80 bit temporary real format if necessary. Then it decrements the
stack pointer to 111 and writes the temporary real representation of the number in register number
111(7).
An operand may be popped from this stack or pushed onto it. A push operation first decrements ST by 1
and then loads the operand into the new top of the stack element, and a pop operation retrieves the top of
the stack and then increments ST by 1.
The stack as being wrapped around in a circle so that if we decrement 000 we get 111, and also if we
push more than 8 numbers on the stack, they wrap around and write over previous numbers.
In the 8087 instructions the register that is currently the TOS is referred to as ST(0), or simply ST. The
register just below this in the stack is referred to as ST(1).
Eg: if ST contains a 3, then ST(0) points to register 3 and ST(2) represents register 5, ST(6) represents
register 1.
Register
Number:
000
001
010
011
100
101
110
111
Register 0
Register 1
Register 2
Register 3
Register 4
Register 5
Register 6
Register 7
ST(5)
ST(6)
ST(7)
ST(0)
ST(1)
ST(2)
ST(3)
ST(4)
STATUS REGISTER:
It is 16 bits wide reflects the overall operation of the coprocessor. It reports various errors, stores the
condition code for certain instructions, specifies which register is the TOS, and indicates busy status.
The status register is accessed by executing the instruction FSTSW, which copies the content of status
into a word of memory. The instruction FSTSW AX copies status register directly into the
microprocessors AX register.
The format of the status register is given below.
15 14
B
C3
13 12 11 10
ST
C2 C1 C0 ES X PE UE OE ZE DE IE
B: The busy bit indicates that the coprocessor is busy in executing a task. The busy is tested by
examining the status register or by using the FWAIT instruction. Newer coprocessors automatically
synchronize with the microprocessor, so the busy flag need not be tested before performing additional
coprocessor tasks.
C0 C3: The condition code bits indicate conditions about the coprocessor. These bits have different
meanings for different instructions. These bits are set by compare and examine instructions.
ST: The top-of-stack bit indicates the current register addressed as top of the stack (ST). This is
normally ST(0).
ES: The error summary bit is set if any unmasked error bit (PE, UE, OE, ZE, DE, or IE) is set. In 8087
error summary also caused a coprocessor interrupt.
X: Reserved
PE: The precision error indicates that the result or operands exceeds the selected precision.
UE: An underflow error indicates a nonzero result that is too small to represent with the current
precision selected by the control word.
OE: An overflow error indicates a result that is too large to be represented. If this error is masked, the
coprocessor generates infinity for an overflow error.
ZE: A zero error indicates the divisor was zero while dividend is noninfinity or nonzero number.
DE: A denormalized error indicates that at least one of the operands is denormalized.
IE: An invalid error indicates a stack overflow or underflow, indeterminate form (00, +infinity, infinity) or the use of a NAN as an operand. This flag indicates errors such as those produced by taking
the square root of a negative number, and so on.
After the 8087 is reset or initialized, all status bits except the condition code are cleared. There are two
ways to test the bits of the status register once they are moved to AX register with the FSTSW AX
instruction.
1. Use the TEST instruction to test the individual bits of the status register.
2. Use the SAHF instruction to transfer the leftmost 8 bits of the status register into the
microprocessors flag register.
CONTROL REGISTER:
The format of the control register is given below.
15
14
13
12
11
10
9
8
X
X
X
IC
RC
PC
7
IEM
6
X
5
PM
4
UM
3
OM
2
ZM
1
DM
0
IM
The 8087 recognizes six error types, each type may be individually masked from causing an interrupt by
setting the corresponding mask bits to 1 in the control register.
It also selects precision, rounding control, and infinity control. The FLDCW instruction is used to load a
value into the control register.
The mask bits are denoted IM (invalid operation), DM (denormalized operand), ZM (divide by zero),
OM (overflow), UM (underflow), and PM (precision error).
If masked, the error will not cause an interrupt but 8087 will perform a standard response and proceed
with next instruction in sequence.
In particular for precision error the standard response is to return the rounded result. It should be
masked for floating point arithmetic because for most applications precision error will occur most of the
time. Precision error are of consequence only in special situations.
An interrupt request, including error-related requests also depends on the interrupt enable mask bit
(IEM) in the control register.
When this bit is set to 1, all interrupts are disabled except when the CPU is executing a WAIT
instruction. If IEM is 0, an unmasked error can cause an interrupt to be sent to the CPU so that the error
can be handled by an error-handling-interrupt routine.
In the error-handling routine, the current instruction pointer and operand pointer, which are stored in
8087, can be examined by the 8086/8088 by first putting them into memory. This can be handled by
using the appropriate 8087 instruction.
The contents of these pointers identify the instruction and operand addresses when the error occurred.
And only 11 bits of the instruction code are kept in the instruction pointer register because the most
significant 5 bits are always 11011, the op-code of an ESC instruction.
The remaining bits provide flexibility in controlling precision (PC), rounding (RC), and infinity
representations (IC). They are defined as follows.
PC bits: 00
01
10
11
PC bits: 00
01
10
11
PC bits: 0
1
During reset or initialization of the 8087, it sets PC bits to 11, RC bits to 00, IC bit to 0, IEM bit to 0,
and all error mask bits to 1.
TAG REGISTER:
It holds the status of the contents of the data registers. Each data register is associated with two tag bits,
which indicate whether its contents are valid (00), zero (01), a special value ie NAN, infinity, or
demormal (10), or empty (11).
INSTRUCTION SET:
The 8087 has 68 instructions, which can be divided into six groups according to their functions. They
are: data transfer, arithmetic, comparison, transcendental, constant, and processor control groups.
The 8087 and host CPU share the same instruction stream, the ASM-86 assembler allows the user to
write programs in a super set instruction set which consists of the 8086s and 8087s instructions.
For each 8087 instruction, the assembler generates two machine instructions, a WAIT instruction
followed by an ESC instruction whose external indicates the 8087s instruction.
Eg: FST SHORT_REAL
Assume that SHORT_REAL is defined using DD directive. This instruction converts the contents of the
top of the ST stack to short real format and stores the result into SHORT_REAL, will be assembled as.
1 1 0 1 1 0 0 1
0 0 0 1 0 1 1 0
MOD
R/M
Op code for
ESC
External op code for performing the load
short real to memory operand
Low-order disp
The WAIT instruction preceding the ESC instruction causes the 8086/8088 to enter a wait state until its
TEST pin becomes active, and is necessary to prevent the ESC instruction from being decoded before
the 8087 completes its current operation.
If the TEST pin is already active or when it becomes active, the ESC instruction will be decoded by the
8087 and both the 8086 and 8087 will proceed in parallel.
An WAIT instruction must be explicitly included whenever the CPU wants to access a memory operand
involved in the previous 8087s instruction.
Eg: In the following sequence the CPU must wait until the 8087 has returned its result to
SHORT_REAL before it can execute the CMP instruction
FST SHORT_REAL
8086s instructions which do not
use SHORT_REAL
WAIT
CMP BYTE PTR SHORT_REAL+3, 0
JG POSITIVE REAL
..
..
All the 8087 mnemonics start with an F, which stand for floating point, the form in which the 8087
works with numbers internally and distinguishes the 8087 instructions from 8086 instructions.
Many of the assembler instructions allow the user to specify operands in more than one way, either
explicitly or implicitly.
Eg: FADD //source/destination, source represents that the instruction can be written in three different
ways.
1. Both the source and destination operands are implicit (this is indicated by having between the first
two slashes), the instruction can be written as simply FADD. In this case, when the 8087 executes
the instruction, it will automatically add the number at the top of the stack ST, to the number in the
next location under it in the stack ST(1). The 8087 stack will be incremented by 1, so the register
containing the result will be ST.
2. The source operand is specified and the destination operand is implicit ie FADD source. The source
can be one of the stack element or memory location.
Eg: FADD ST(2) ;will add the number from two locations below ST to the number in ST and leave
the result in ST, so ST is the implicit destination.
FADD CORRECTION_FACTOR ;will add a real number from the memory location named
CORRECTION_FACTOR to the number in ST and leave the result in ST.
The assembler will be able to determine whether the number in memory is a short-real, long-real, or
temporary-real by the way CORRECTION_FACTOR was declared. Short-real is declared with DD
directive, long-real with DQ directive, temporary-real with DT directive.
3. Both the source and destination operands are specified by the user ie FADD destination, source. The
source can be one of the stack elements or a number from memory location and destination has to
be one of the stack elements.
Eg: FADD ST(2), ST(1) ;will add the number one location down from ST to the number two
locations down from ST and leave the result in ST(2).
FADD ST(3), CORRECTION_FACTOR ;will a real number from the memory location named
CORRECTION_FACTOR to the contents of ST(3) and leave the result in ST(3).
A memory operand may be addressed by any one of the 8086s data addressing modes. The data type of
the memory operand may be word integer, short integer, long integer, packed BCD, short real, long real,
or temporary real.
If 8087 detects an error condition, usually called an exception, while it is executing an instruction, it will
set the appropriate bit in its status register. After the instruction finishes executing, the status register
contents can be transferred to memory with another 8087 instruction. Then you can check status bits
using 8086 instructions and decide what action to take if an error has occurred.
If you send the 8087 a control word which unmasks the exception interrupts, the 8087 will also send out
a hardware interrupt signal when an error occurs. This signal can be used to send the 8086 directly to an
exception handling procedure.
DATA TRANSFER INSTRCTIONS:
There are three basic data transfers: floating-point, integer, and BCD. The only time that data ever
appear in the signed integer or BCD form is in memory. Inside the coprocessor, data are always stored
as 80-bit extended-precision floating-point numbers.
A memory operand whose type is word integer, short integer, long integer, short real, long real,
temporary real, or packed BCD can be converted to temporary real and then pushed onto the register
stack, or a register can be pushed onto the stack.
Conversely, the contents of the top stack element can be converted from temporary real to the
destinations data format, and then stored in memory.
Also, instructions are available for popping the contents of a register from the stack and exchanging the
contents of a register with the top of the stack. The tag register is updated following each data transfer
instruction.
Load integer
Load BCD
FILD SRC
(SRC:
Word integer, short integer, long integer
memory operand)
FBLD SRC
(SRC: Packed decimal memory operand)
Errors: I
Store real
FST DST
Convert (ST) to the destinations real format,
(DST: ST(i) or memory operand of short and store the result into DST.
real or long real)
Errors: I, O, U, P
FIST DST
(DST: Word integer, short integer, long
integer memory operand)
Store BCD
and pop
FBSTP DST
(DST: Packed decimal memory operand)
Store real
and pop
FSTP DST
Convert (ST) to the destinations real format,
(DST: ST(i) or memory operand of short and store the result into DST, and increment
real, long real, or temporary real type)
ST. Errors: I, O, U, P
Store integer
FXCH //DST
(DST: ST(i), if not specified, ST(1) is
assumed)
FLD ST(3)
;Copies ST(3) to ST.
FLD LONG_REAL[BX] ;Number from memory copied to ST.
FST ST(2)
;Copy ST to ST(2)
FST SHORT_REAL[BX]
;Copy ST to memory location at SHORT_REAL.
FST ST(2)
;Copy ST to ST(2), and increment stack pointer.
FST SHORT_REAL[BX]
;Copy ST to memory location at SHORT_REAL, and increment stack
pointer.
Example: FBSTP TAX ;Converts the contents of ST to packed BCD and sent memory location named
TAX, the TAX was declared using DT directive.
ARITHMETIC INSTRUCTIONS:
The 8087 has variety of instructions for performing arithmetic operations addition, subtraction,
multiplication, and division. Results are always stored on the top of the register stack or in a specified
register, and one of the source operands must be the top of the stack.
For real arithmetic instructions, the other operand may be located in a specified register or in memory.
Special forms are provided to pop the stack after the arithmetic operation is completed.
The data is internally represented in the temporary real format, the arithmetic involving operands of
other types can be accomplished by first loading the operands into the appropriate registers using data
transfer instructions, and then performing the real arithmetic operation.
However, arithmetic instructions are provided that will accept memory operands of short real, long real,
word integer, or short integer, and automatically convert these operands to temporary real before
performing their operations.
In addition to the basic arithmetic operations, the 8087 provides instructions to calculate the square root,
adjust scale values using the power of 2, perform modulo division, round real values to integer values,
extract the exponent and fraction, take the absolute value, and change the sign.
These instructions operate on the top one or two stack elements, and the result is left on the top of the
stack.
Arithmetic Instructions:
Name:
Add real
and pop
Add integer
FIADD SRC
(SRC: word integer, or short integer
memory operand)
Subtract real
Subtract real
and pop
Subtract real
Reversed
Subtract real
reversed and pop
Subtract integer
FISUB SRC
Add real
Errors: I, D, O, U, P
Subtract integer
Reversed
FISUBR SRC
(SRC: word integer, or short integer
memory operand)
Multiply real
Multiply real
and pop
FIMUL SRC
(SRC: word integer, or short integer
memory operand)
Divide real
Divide real
and pop
Divide real
Reversed
Divide real
reversed and pop
FIDIV SRC
(SRC: word integer, or short integer
memory operand)
Divide integer
reversed
FIDIVR SRC
(SRC: word integer, or short integer
memory operand)
Absolute value
FABS
(No operands)
(ST) |(ST)|
Errors: I
Change sign
FCHS
(No operands)
(ST) -(ST)
Errors: I
Partial remainder
FPREM
(No operands)
Round to integer
FRNDINT
(No operands)
Multiply integer
Divide integer
Scale
FSCALE
(No operands)
(ST) (ST) * 2n
Where n is the integral part of (ST(1))
Errors: I, O, U
Square root
FSQRT
(No operands)
(ST) ()
Errors: I, D, P
FXTRACT
(No operands)
Extract exponent
and fraction
Note: If DST is not specified, ST is assumed and SRC must be a memory operand of the short real or long real
type. If both are specified, they must be ST, ST(i) or ST(i), ST. When neither is given, then ST(1), ST is
assumed and after the arithmetic operation is performed, the stack is popped and the result is left at the
new top of the stack.
Addition Instructions:
FADD //SRC/DST, SRC: Add real. (DST) (DST) + (SRC)
Add real from specified source to real at specified destination. Source can be stack element or memory location.
Destination must be a stack element. If both source and destination is not specified, then ST is added to ST(1)
and stack pointer is incremented so that the result of addition is at ST. Exceptions: I, D, O, U, P.
Example: FADD ST(3), ST
FADD ST, ST(4)
FADD INTEREST
FADD
FADDP DST, SRC: Add real and pop, DST:ST(i), SRC:ST, (ST(i)) (ST(i)) + (ST), Increment ST.
Add ST to specified stack element and increment stack pointer by 1. Exceptions: I, D, O, U, P.
Example: FADDP ST(1)
FIADD DST, SRC: Add integer, SRC: word integer or short integer from memory, (ST) (ST) + (SRC)
Add integer from memory to ST, result in ST. Exceptions: I, D, O, P.
Example: FIADD CARS_SOLD ;Integer number from memory + ST
Subtraction Instructions:
FSUB //SRC/DST, SRC: Subtract real (destination - source), (DST) (DST) - (SRC)
Subtract the real number at the specified source from the real number at the specified destination and put the
result in the specified destination. Exceptions: I, D, O, U, P.
Example: FSUB ST(2), ST
FSUB CHARGE
FSUB
FSUBP DST, SRC: Subtract real and pop, DST:ST(i), SRC:ST, (ST(i)) (ST(i)) - (ST), Increment ST.
Subtracts ST from specified stack element and put the result in specified stack element, then increment stack
pointer by 1. Exceptions: I, D, O, U, P.
Example: FSUBP ST(1)
FISUB SRC: Subtract integer, SRC: word integer or short integer from memory, (ST) (ST) - (SRC)
Integer from memory subtracted from ST, result in ST. Exceptions: I, D, O, P.
Example: FISUB CARS_SOLD
Reversed Subtraction:
FSUBR //SRC/DST, SRC
FSUBRP DST, SRC
FISUBR SRC
These instructions operate same as described previously, except that these subtracts the contents of specified
destination from source and put the difference in specified destination.
Multiplication Instructions:
FMUL //SRC/DST, SRC: Multiply real, (DST) (DST) * (SRC)
Multiply real number from source by real number from destination and put the result in specified stack element.
Exceptions: I, D, O, U, P.
FMULP //SRC/DST, SRC: Multiply real and pop, (DST) (DST) * (SRC), Increment ST.
Multiply real number from source by real number from specified destination and put the result in specified stack
element, and increment stack pointer by 1. With no specified operands FMULP multiplies ST(1) by ST and
pops stack to leave result at ST. Exceptions: I, D, O, U, P.
FIMUL source: Multiply Integer
Multiply integer from memory times ST and put result in ST. Exceptions: I, D, O, P.
Example:
Division Instructions:
FDIV //source/destination, source: Divide real
Divide destination real, by source by real, result goes in destination. Exceptions: I, D, Z, O, U, P.
FDIVP destination, source: Divide real and pop
Divide destination real, by source by real, result goes in destination, increment stack pointer by 1 after division.
Exceptions: I, Z, D, O, U, P.
FIDIV source: Divide integer
Divide ST by integer from memory, result in ST. Exceptions: I, Z, D, O, U, P.
Reversed Division:
FDIVR //source/destination, source
FDIVRP destination, source
FIDIVR source
These instructions are identical in format to the FDIV, FDIVP, and FIDIV instructions, except they divide the
source operand by the destination operand and put the result in destination.
Other arithmetic operations:
FABS: Absolute value, No operands, (ST) |(ST)|
Number in ST is replaced by its absolute value. Instruction simply makes sign positive. Exception: I
FCHS: Change sign, No operands, (ST) -(ST)
Complements the sign of the number in ST. Exception: I
FPREM: Partial remainder, No operands, (ST) (ST) mod (ST(1))
The contents of ST(1) are subtracted from the contents of ST over and over again until the contents of ST are
smaller than the contents of ST(1). FPREM can be used to reduce a large angle to less than so that the 8087
trig functions can be used on it. Exceptions: I, D, U.
FRNDINT: Round to integer, No operands, (ST) integer ST
Round number in ST to an integer. The round-control (RC) bits in the control word determine how the number
will be rounded. If the RC bits are set for down or chop, a number such as 205.73 will be rounded to 205. If the
RC bits are set for up or nearest, 205.73 will be rounded to 206. Exceptions: I, P.
FXTRACT: Separates the exponent and the significand parts of a temporary real number in ST. After the
instruction executes, ST contains a temporary-real representation of the significand of the number and ST(1)
contains a temporary-real representation of the exponent of the number. These two could then be written out to
memory locations. Exception: I
FABS: Number in ST is replaced by its absolute value. Instruction simply makes sign positive. Exception: I.
FCHS: Complements the sign of the number in ST. Exception: I.
COMPARE INSTRUCTIONS:
The compare instructions compare the top of the register stack with the source operand, which may be in
other register or in memory, and set the condition code accordingly.
The top stack element may also be compared to 0, or examined to determine its tag, sign, or
normalization.
Condition code settings can be examined by the 8086 or 8088 by storing the status register of the 8087
in memory using a proper 8087 processor control instruction.
Compare Instructions:
Name:
Compare real
Compare real
and pop
FCOMP //SRC
(SRC: ST(i), or memory operand of the
short real or long real type. If not
specified, ST(1) is assumed)
Compare real
and pop twice
FCOMPP
(No operands)
Compare integer
FICOM SRC
(SRC: word integer or short integer
memory operand)
Compare integer
and pop
FICOMP SRC
(SRC: word integer or short integer
memory operand)
FTST
(No operands)
Examine top of
stack
FXAM
(No operands)
Note 1:
Order
(ST) > (SRC)
(ST) < (SRC)
(ST) = (SRC)
Not comparable
C3 C0
0
0
0
1
1
0
1
1
Note 2:
Order
(ST) > 0.0
(ST) < 0.0
(ST) = 0.0
Not comparable
C3 C0
0
0
0
1
1
0
1
1
Note 3:
(ST)
C3 C2 C1 C0
+Unnormal
0
0
0
0
+NAN
0
0
0
1
-Unnormal
0
0
1
0
-NAN
0
0
1
1
+Normal
0
1
0
0
+
0
1
0
1
-Normal
0
1
1
0
-
0
1
1
1
+0
1
0
0
0
Empty
1
0
0
1
-0
1
0
1
0
Empty
1
0
1
1
+Denormal
1
1
0
0
Empty
1
1
0
1
-Denormal
1
1
1
0
Empty
1
1
1
1
The compare instructions with COM in their mnemonic compare contents of ST with contents of
specified or default source. The source may be another stack element or real number in memory. These
compare instructions set the condition code bits C3, C2, and C0 of the status word.
FCOM // source: Compares ST with real number in another stack element or memory. Exceptions: I, D.
Example: FCOM
FCOM ST(3)
FCOM Minimum
FCOMP // source: Identical to FCOM except that the stack pointer is incremented by 1 after the compare
operation. Old ST(1) becomes new ST.
FCOMPP: Compares ST with ST(1) and increment stack pointer by 2 after compare. This puts the new ST
above the two numbers compared. Exception: I, D.
FICOM source: Compares ST to a short or long integer from memory. Exceptions: I, D.
FICOMP source: Identical to FICOM except stack pointer is incremented by 1 after compare.
FTST: Compares ST with 0 and sets the condition code bits. Exceptions: I, D.
FXAM: Tests ST to see if it is 0, infinity, unnormalized, or empty.
TRANSCENDENTAL INSTRUCTIONS:
The transcendental instructions calculate tan (0 < < /4), tan1 (Y/X) (0 < Y < X < ), 2X 1 (0 X
0.5), Y*log
, and Y*log (
+ 1). All transcendental instructions use ST or ST(1) as their operands,
and the results are stored back on the stack.
Other common trigonometric, inverse trigonometric, hyperbolic, inverse hyperbolic, logarithemic, and
exponential functions can be derived from these five functions through mathematical identities. For
example, calculation of the natural log of X is equivalent to (
)log .
As an example involving the trigonometric functions, consider the partial tangent instruction, FPTAN,
which computes the tan , where in radians is the (ST) and is between 0 and /4. The result is a ratio
Y/X, with Y replacing and X being pushed onto the stack. The sine function is related to the tangent
function as follows:
Sin =
Tan = (!" )
Mnemonic:
F2XM1
(No operands)
Partial arc
Tangent
FPATAN
(No operands)
Partial tangent
FPTAN
(No operands)
Calculate
Y*log
FYL2X
(No operands)
Calculate
Y*log [
+ 1]
FYL2XP1
(No operands)
FPTAN: Computes the values for a ratio of Y/X for an angle in ST. The angle must be expressed in radians,
and the angle must be in the range of 0 < angle < /4.
NOTE: FPTAN does not work correctly for angles of exactly 0 and /4. You can convert an angle from degrees
to radians by dividing it by 57.295779. An angle greater than /4 can be brought into range with the 8087
FPREM instruction. The Y value replaces the angle on the stack, and the X value is pushed on the stack to
become the new ST. The values for X and Y are created separately so you can use them to calculate other trig
functions for the given angle. Exceptions: I, P.
FPATAN: Computes the angle whose tangent is Y/X. The X value must be ST, and the Y value must be in
ST(1). Also, X and Y must satisfy the inequality 0 < Y < X < . The resulting angle expressed in radians
replaces Y in the stack. After the operation the stack pointer is incremented so the result is then ST. Exceptions:
I, D.
F2XM1: Computes the function Y = 2X 1 for an X value in ST. The result Y replaces X in ST. X must be in
the range 0 X 0.5. To produce 2X, you can simply add 1 to the result from this instruction. Using some
common equalities, you can produce values often needed in engineering and scientific calculations.
Examples:
10X = 2X(LOG 10)
eX = 2X(LOG -)
YX = 2X(LOG .)
FYL2X: Calculates Y times the LOG to the base 2 of X or Y (LOG
). X must be in the range of 0 < X <
and Y must be in the range - < Y < +. X must initially be I ST and Y must be in ST(1). The result replaces Y
and then the stack is popped so that the result is then at ST. This instruction can be used to compute the log of a
number in any base, n, using the identity LOG
= LOG 2(LOG
). For a given n, LOG 2 is a constant which
can be easily calculated and used as the Y value for the instruction. Exceptions: P.
FYL2XP1: Computes the function Y times the LOG to the base 2 of (X+1) or Y (LOG (
+ 1)). This
instruction is almost identical to FYL2X except that it gives more accurate results when computing the LOG of
a number very close to 1.
INSTRUCTIONS WHICH LOAD CONSTANTS:
The following instructions simply push the indicated constant onto the stack. Having these commonly
used constants available reduces programming effort.
They are used to +0.0, +1.0, , log 10, log -, log/ 2, or log 2 onto the register stack. These constants
are stored in temporary real format and have accuracy of up to approximately 19 decimal digits.
Name:
Mnemonic:
FLDZ
(No operands)
Description:
Decrement ST
Error: I
(ST) 0.0
Load one
FLD1
(No operands)
Decrement ST
(ST) 1.0
Error: I
Load
FLDPI
(No operands)
Decrement ST
(ST)
Error: I
Load zero
Load log -
FLDL2E
(No operands)
Decrement ST
(ST) log -
Error: I
Load log 10
FLDL2T
(No operands)
Decrement ST
(ST) log 10
Error: I
Load log/ 2
FLDLG2
(No operands)
Decrement ST
(ST) log/ 2
Error: I
Load log 2
FLDLN2
(No operands)
Decrement ST
(ST) log 2
Error: I
Mnemonic:
FINIT/FNINIT
(No operands)
Description:
Reset the 8087. Set control word to 03FF and set tag
register to empty. Clear all error, busy, and interrupt
flags. Reset ST to 0.
Disable interrupts
FDISI/FNDISI
(No operands)
Enable interrupts
FENI/FNENI
(No operands)
FCLEX/FNCLEX
(No operands)
Increment stack
pointer
FINCSTP
(No operands)
ST ST+1
(It does not set the tag of the previous
top of stack register to empty)
Decrement stack
pointer
FDECSTP
(No operands)
ST ST-1
FSTSW/FNSTSW DST
(DST: 2-byte memory
operand)
FLDCW SRC
(SRC: 2-byte memory
operand)
Store environment
FSTENV/FNSTENV DST
(DST: 14-byte memory
operand)
Load environment
FLDENV SRC
(SRC: 14-byte memory
operand)
FINIT/FNINT: Initializes 8087. Disables interrupt output, sets stack pointer to register 7, sets default status.
FDISI/FNDISI: Disables the 8087 interrupt output pin so that it cannot cause an interrupt when an exception
(error) occurs.
FENI/FNENI: Enables 8087 interrupt output so it can cause an interrupt when an exception occurs.
FLDCW source: Loads a status word from a named memory location into the 8087 status register. This
instruction should be preceded by the FCLEX instruction to prevent a possible exception response if an
exception bit in the status word is set.
FSTCW/FNSTCW destination: Copies the 8087 control word to a named memory location where you can
determine its current value with 8086 instruction.
FSTSW/FNSTSW destination: Copies the 8087 status word to a named memory location. You can check
various status bits with 8086 instructions and base further action on the state of these bits.
FCLEX/FNCLEX: Clears all the 8087 exception flag bits in the status register. Unasserts BUSY and INT
outputs.
FSAVE/FNSAVE destination: Copies the 8087 control word, status word, pointers, and entire register stack to
a named, 94byte area of memory. After copying all this, the FSAVE/FNSAVE instruction initializes the 8087
as if the FINIT/FNINIT instruction had been executed.
FRSTOR source: Copies a 94byte named area of memory into 8087 control register, status register, pointer
registers, and stack registers.
FSTENV/FNSTENV destination: Copies the 8087 control register, status register, tag words, and exception
pointers to a named series of memory locations. This instruction does not copy the 8087 register stack to
memory as the FSAVE/FNSAVE instruction does.
FLDENV source: Loads the 8087 control register, status register, tag word, and exception pointers from a
named area in memory.
FINCSTP: Increments the 8087 stack pointer by 1. If the stack pointer contains 111 and it is incremented, it
will point to 000.
FDECSTP: Decrements the 8087 stack pointer by 1. If the stack pointer contains 000 and it is decremented, it
will point to 111.
FFREE destination: Changes the tag for the specified destination register to empty.
FNOP: Performs no operation. Actually copies ST to ST.
FWAIT: This instruction is actually an 8086 instruction which makes the 8086 wait until it receives a notbusy
signal from the 8087 to its TEST pin. This is done to sure that neither the 8086 nor the 8087 starts the next
instruction before the preceding 8087 instruction is completed.
11) Write a program to obtain the hypotenuse of a right angles triangle given its sides A & B using 8087
interfaced to 8086.
(Dec 2009) (08 Marks)
Solution:
.MODEL SMALL
DATA
SEGMENT
SIDE_A
DD
SIDE_B
DD
HYPOTENUSE
DD
CONTROL_WORD
DW
STATUS_WORD
DW
DATA
ENDS
CODE
START:
STOP:
CODE
WORD
3.0
4.0
0
PUBLIC
0
0
SEGMENT WORD
PUBLIC
ASSUME CS:CODE, DS:DATA
MOV AX, DATA
MOV DS, AX
FINIT
MOV CONTROL_WORD, 03FFh
FLDCW CONTROL_WORD
FLD SIDE_A
FMUL ST, ST(0)
FLD SIDE_B
FMUL ST, ST(0)
FADD ST, ST(1)
FSQRT
FSTSW STATUS_WORD
MOV AX, STATUS_WORD
AND AL, 0BFh
JNZ STOP
FSTP HYPOTENUSE
NOP
ENDS
END START
2.0
4.0
1.0
0.0
-9.0
?
?
.CODE
.STARTUP
FLDZ
FST R1
FSTP R2
FLD TWO
FMUL A1
FLD FOUR
FMUL A1
FMUL C1
FLD B1
FMUL B1
FSUBR
FTST
FSTSW AX
SAHF
JZ
ROOTS1
FSQRT
FSTSW AX
TEST AX,1
JZ
ROOTS1
FCOMPP
JMP ROOTS2
ROOTS1:
FLD B1
FSUB ST, ST(1)
FDIV ST, ST(2)
FSTP R1
FLD B1
FADD
FDIVR
FSTP R2
ROOTS2:
.EXIT
END
14) Represent 178.625 using 80 bit temporary real format for expressing the answer. (June 2011) (04 Marks)
Ans: In binary 178.625=10110010.101
Normalized binary number= 1.0110010101x2^7
For short real format: E=127+7=134=86h, S=0, F=0110010101
The number= 0 10000110 01100101010000000000000=4332A000h
For long real format: E=3FFh+7h=406h, S=0, F=0110010101
The number= 0 10000000110 01100101010000.0=4066540000000000h
For temporary real format: E=3FFFh+7h=4006h, S=0, F=0110010101
The number= 0 100000000000110 1011001010100000000.0=4006B2A0000000000000h