8087 instruction set and examples

advertisement
8087 instruction set and
examples
About the 8087
• In the old days, you had to buy a -87 chip
for numerical co-processing and hand
install it. (Back in the 8086, 286,386 days).
• With the 486 processor and later, the -87
coprocessor is integrated.
About the 8087
• The 8087 uses a “stack” or chain of 8
registers to use for internal storage and
data manipulation, as well as status and
control words to set rounding control and
indicate the results of operations.
• It has its own instruction set, instructions
are recognizable because of the F- in
front. (Like FIADD, FCOM, etc)
About the 8087
• FWAIT… checks a control line to see if the
87 is still active.
• programmers used to have to use an
FWAIT before and after a set of
instructions for the -87 to make sure -86 or
-87 storage operations had been
completed. (Basically, to handle
synchronization).
• FWAIT should not be necessary.
About the 8087: data transfer
•
•
•
•
Data transfer:
Instruction
result
FLD source
load a real into st(0)
FST dest
store real at dest (86
mem)
• FSTP dest
store/pop st(0)
• FXCH {st(i)}
exchange two regs
(St(0), St(1)) or St(0) and the operand
About the 8087: data transfer
•
•
•
•
•
FILD source
FIST dest
FISTP dest
FBLD source
FBSTP dest
int load
int store
int store/pop
bcd load (tbyte source)
bcd store tbyte dest
About the 8087: arithmetic
• FADD source
add a real (mem)
to st(0)
• FADD {St(1),ST}
• FADD st(i),st … or FADD ST,ST(i)
• FADDP St(i),ST
add st to st(i) and
pop st(0)
• FIADD {st,} source
int add to st
About the 8087: arithmetic
• FSUB for real subtract has same formats as
FADD
• FISUB {st,} intmem for int sub
• ALSO:
• FSUBR {st(1),st}
• FSUBR {st,} rmem
• FSUBRP st(i),st
• Etc and …
• FISUBR {st,} intmem
• Reverse subtract: subtract dest from source
About the 8087: arithmetic
• FMUL and FIMUL have same formats
available
• FDIV and FIDIV have same formats
• Also available
• FDIVR, FDIVRP and FIDIVR
About the 8087: arithmetic
•
•
•
•
•
Miscellaneous
FSQRT {st}
FABS {st}
FCHS {ST}… change sign
FLDZ {st}… load a zero
Control word
• The control word is a 16 bit word that works like a flag
register on the 86 processor. It keeps information about
zerodivide in bit 2 for example. Bits 3 and 4 are overflow
and underflow respectively.
• Precision control is set in bits 8 and 9 and rounding is set
in bits 10 and 11.
• Rounding control bit settings are:
• 00 round to nearest/even
• O1 round down
• 10 round up
• 11 chop/truncate
Status word
• Status word is also a 16 bit word value.
• condition bits are named c3, c2,c1 and c0.
Their position in the status word, though
is:
• C3 is bit 14
• C2,c1,c0 are bits 10,9,8 respectively.
• If you are curious, the eight possible bit
settings in bits (11,12,13) indicate which
register in the chain is currently st(0)
Temp real (80 bits)
• Temp real has an f-p format. Bits 0..63 are
the significand in hidden bit format. Bits
64 to 78 are the biased exponent, bit 79 is
the sign.
• You shouldn’t need to worry about these
values on the stack.
Packed bcd (80 bits)
•
•
•
•
•
•
•
A packed bcd is a tbyte.
Bit 79 is the sign.
Bits 72 through 78 are not used.
Bits 0,1,2,3 store the 0 th (lsd) decimal digit.
Bits 4,5,6,7 store the 1st.
The 17th (msd) digit is in bits 68,69,70,71.
You’ll need to pad with zeros if there are fewer
than 18 digits.
Int values
• 87 processor recognizes word, dword and
qword signed int types, in the same
manner as the 86 processor.
The stack
• Pushing and popping on the stack change the
register who is currently the top.
• Pushing more than 8 times will push the last
piece of data out and put St(0) at the most
recently pushed item.
• It is the programmer’s responsibility to count
stack push/pop operations.
• Whoever is on top of the stack, is referenced by
St or ST(0). St(1) is next. And so on to St(7).
Int transfer
• FILD: load int. Type (word, dword, etc) is
whatever the operand type is. St(0) is this new
value. St(1) points to the previous value on top.
• FIST: copy St(0) value to memory, converting to
a signed int (following rounding control settings
in the control word)
• FISTP: same as above, but pop the stack as
well.
BCD
• FBLD load a bcd (tbyte) onto the stack
• FBSTP store a tbyte bcd value into the
memory operand, popping the stack as
you go.
Example:
FBLD myval
FBSTP myval
Exchanging/swapping on the stack
• FXCHG dest
Swap stack top with operand.
Example
FXCHG St(3)
; swaps St(0) value with St(3) value
Int arithmetic
•
•
•
•
•
•
FIADD, FIADD: add
FISUB, FISUBR, : sub, or sub reversed.
FIMUL
FIDIV, FIDIVR
Other:
FPREM, FRNDINT – partial remainder, round to
int
• FLDZ push a zero onto the stack.
• FLD1 push a 1
FPREM
• Takes implicit operands st,st(1)
• Does repeated subtract… leaves
st>0,(possibly st==st(1)) or st==0.
• May need to repeat it, because it only
reduces st by exp(2,64)
• If st>st(1) it needs to be repeated.
• FPREM sets bit C2 of the status word if it
needs to be repeated, clears this bit if it
completes operation.
operands
• Stack operands may be implicitly
referenced.
• FIADD, FISUB, FIDIV, FIDIVR, FIMUL and
FISUBR have only one form (example
using add instruction):
FIADD {ST,} intmem
• St(0) is implied dest for all of these.
comparison
•
•
•
•
FCOM ;no operands compares st,st(1)
FCOM St(i); one operand compares st with st(i)
FCOMP (compare and pop) is the same.
FCOMPP - only allows implicit operands St,st(1)
(compare then pop twice)
• FTST – compares St with 0.
• These all use condition codes described above
and make the settings in the next slide.
Condition codes
•
•
•
•
•
C3
0
0
1
1
c0
0
1
0
1
st>source
st<source
st==source
not comparable
Getting status and control words
• FSTSW intmem ; copy status word to 16
bit mem location for examination.
• FLDCW intmem; load control word (to set
rounding, for example, from 16bit int mem)
• FSTCW intmem; copy control word to int
mem
Some -87 examples
16-bit vs 32-bit?
• Almost all the examples here were done in
32 bit.
• But the coprocessor works in 16 bit as
well.
excerpt from a 16-bit program & ouptut
value word 1234
.code
main PROC
mov ax,@data
mov ds,ax
mov ax, value
call writedec
fild value
fiadd value
fistp value
mov ax,value
call crlf
call writedec
C:\MASM615>coprocessor
1234
2468
C:\MASM615>
adding up an array (example from notes)
include irvine16.inc
.data
array dword 12, 33, 44,55,77,88,99,101,202,9999,111
sum dword ?
.code
main proc
mov ax,@data
mov ds,ax
xor bx,bx
fldz
fist sum
mov eax,sum;;;
call writeint;print zero
call crlf
mov cx,10
top:
mov eax,array[bx];;get value
call writeint;;;print it
call crlf
fiadd array[bx];;;;add to st(0)
add bx,4
loop top
fistp sum;;;;when done pop to dword int
mov eax,sum
call writeInt;;;;print it
mov ax,4c00h
int 21h
main endp
end main
adding up an array (example from notes)
Getting sqrt
call readint
fstcw control;;;store current control word
or control,0800h;set bit 11 clear bit 10 to round up
fldcw control;;load new control word
mov num,eax
fild num
fsqrt
fistp sqr
fwait
mov edx, offset prompt2
call writestring
mov eax,sqr
call writeint
Rounding set to round up
• c:\Masm615>primes
• enter an integer125
• sqrt of integer+12
Add code to check for prime and print
divisors for composites
mov eax,num
call crlf
mov ebx,2;;;first divisor
top:
xor edx,edx
push eax
div ebx;;divide
mov divi,ebx
cmp edx,0
je notprime
inc ebx
cmp ebx,sqr
jg prime
pop eax
jmp top
notprime:
call writedec
call crlf
mov eax,divi
call writedec
call crlf
mov edx,offset f
call writestring
prime:
mov edx,offset t
call writestring
Output from primes
enter an integer1337711
18841
71
not a prime
c:\Masm615>primes
enter an integer17171731
746597
23
not a prime
c:\Masm615>primes
enter an integer313713
104571
3
not a prime
c:\Masm615>primes
enter an integer313717
prime
c:\Masm615>
factorials
call readint
mov num,eax
call crlf
fld1 ;;load a 1 for subtacting and comparing..this will be st(2)
fld1 ;;prod value initialized in st(1)
fild num;;;multiplier... need to count down and multiply st by st(1)
theloop:
ftst ;;is st==0?
fstsw status
and status, 4100h;check bits c3 and c0...c3=0 c0=1 means st<source
cmp status,4000h;;st==source
jz done
fmul st(1),st ;;leave prod in st(1)
fsub st,st(2)
jmp theloop
done:
fistp dummy
fistp answer
mov edx,offset p2
call writestring
call crlf
fwait
mov eax,answer
call writedec
factorials
c:\Masm615>factorials
enter an integer6
factorial is
720
c:\Masm615>factorials
enter an integer7
factorial is
5040
c:\Masm615>
Fibonacci values
mov edx, offset prompt
call crlf
call writestring
call readint
call crlf
fld1 ;;load a 1 for subtacting and comparing..this will be st(2)
fld1 ;;prod value initialized in st(1)
top:
cmp eax,0
je done
fadd st(1),st
fsubr st,st(1)
;;;cute huhn?st=st(1)-st
dec eax
jmp top
done:
fistp dummy
fistp answer
mov edx,offset p2
call writestring
call crlf
fwait
mov eax,answer
call writedec
Fibonacci
c:\Masm615>fibs
enter an integer4
fib is
8
c:\Masm615>fibs
enter an integer6
fib is
21
c:\Masm615>fibs
enter an integer7
fib is
34
c:\Masm615>
Mimicking real io
• You can output reals by outputting first the
integer part, subtracting this from the
original value, then repeatedly multiplying
the fraction by ten, (subtracting this off
from the remainder) and outputting this
sequence of fractional digits.
• This is NOT an IEEE f-p conversion
routine!
Rounding control & the int part
fstcw control
or control,0C00h ;;;chop or truncate
fldcw control
fild ten ;;ten is in st(1)
fild num ;;num is in st(0)
fsqrt ;;sqrt in st
fist intsqr ;;;store chopped result, don’t pop
call crlf
mov edx,offset message
call writestring
fwait
mov ax,intsqr ;;write the int part
call writedec
realio
mov edx,offset dot;;decimal point
call writestring
fisub intsqr ;;subtract from sqrt the int part leaving fractional part
;now loop & store 5 decimal places
mov edi, offset decimals
mov ecx, 5
up:
fmul st,st(1) ;;multiply by 10 to shift dec point
fist digit ;store truncated int
fisub digit ;;subtract it off of the total
fwait
mov ax,digit
add al,48
mov byte ptr [edi],al ;;store this digit
inc edi
loop up
Run of realio
c:\Masm615>realio
enter an integer:
121
sqrt of integer 11.00000
c:\Masm615>realio
enter an integer:
123
sqrt of integer 11.09053
c:\Masm615>realio
enter an integer:
143
sqrt of integer 11.95826
c:\Masm615>
Download