Professional Documents
Culture Documents
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)
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 programmers 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
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
16-bit vs 32-bit?
Almost all the examples here were done in 32 bit. But the coprocessor works in 16 bit as well.
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
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
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
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!
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>