CATEGORII DOCUMENTE |
COPROCESORUL ARITMETIC 8087 SI APLICATII
1. Descrierea pinilor si modul de conectare in sistem cu microprocesor
8087
Coprocesorul 8087
CLK CLocK) - intrare - pin 19 - este tactul de baza al microprocesorului si este obtinut de la generatorul de ceas 8284.
READY - intrare - pin 22 - este o intrare sincrona activa in 1 indicind terminarea ciclului bus curent.
RESET - intrare - pin 21 - dupa tranzitia in 1 a acestui semnal, coprocesorul trece in starea de initializare.
RQ/GT0/ (RQ/GT1/) (ReQuest/GranT) - bidirectionale - pini 31,33 - sint semnale bidirectionale pentru arbitrarea accesului pe magistrala locala intre microprocesor si coprocesor. Daca 8087 doreste ocuparea magistralei, are loc urmatorul protocol :
- 8087 activeaza una din liniile RQ/GT0/ (prioritatea cea mai mare) sau RQ/GT1/ catre 8086, semnalindu-i ca exista o cerere de acces pe busul local;
- 8086 raspunde la aceasta cerere pe acceasi linie RQ/GT0/ sau RQ/GT1/ cum ca cedeaza busul si ca a trecut in starea HOLD. Din acest moment 8087 are acces pe busul local;
- la terminarea activitatii pe busul local, 8087 mai activeaza o data linia RQ/GT0/ (RQ/GT1/), indicind procesorului 8086 ca a cedat busul si ca poate fi preluat de master. [ ]
BUSY - iesire - pin 23 - este activ in starea 0 logic si se conecteaza cu intrarea TEST/ de la 8086. El semnaleaza unitatii centrale ca 8087 executa o instructiune aritmetica.
AD0AD15 (Address Data bus) - intrari/iesiri - reprezinta magistrala de adrese (bitii inferiori) si date multiplexata. Semnificatia este analoaga celei de la 8086.
A16/S3, A17/S4, A18/S5, A19/S6 (Address/Status) - pinii 3..35. In starea T1 sint cei mai semnificativi biti ai adresei, iar in T2, T3, Tw si T4 sint biti de stare (vezi 8086).
BHE//S7 (Bus High Enable/Status) - iesire - pin 34 - indica octetii implicati in transferul de date pe bus dupa cum urmeaza :
BHE A0 |
Octeti transferati |
0 0 0 1 1 0 1 1 |
D15 D0 (cuvint) D15 D8 (octet superior) D7 . D0 (octet inferior) combinatie interzisa |
S0/, S1/, S2/ (Status) - iesiri - pinii 26,27,28 - sint semnale pentru controlul accesului la memorie sau la dispozitive periferice. Ele sint destinate circuitului 8288 pentru a decodifica ciclul magistrala care se executa.
S0/ S1/ S2/ |
Ciclul bus |
0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 |
Ciclu de confirmare intrerupere Citire cod instructiune Scriere de la periferic Scriere operand in memorie Citire de la periferic Citire operand din memorie Halt Ciclu bus inactiv |
INT (INTerrupt) - intrare - pin 25 - intrare folosita de sistemul de intreruperi.
QS0, QS1 (Queue Status) - pinii 25,24 - indica starea cozii de asteptare.
2. Arhitectura interna a coprocesorului
Din punct de vedere structural, coprocesorul matematic 8087 este alcatuit din doua unitati de procesare :
- unitatea de control (Control Unit);
- unitatea de executie (Execution Unit).
Responsabila de decodificarea si executia instructiunilor este unitatea de executie. Ea contine registrii de lucru efectivi (adresabili de catre utilizator) sau temporari (nu se pot adresa, dar sint folositi intern de catre coprocesor), registrii de stare si o interfata cu unitatea de control. De asemenea, ea executa toate instructiunile care implica registrii stiva (instructiuni aritmetice, comparari, operatii de logaritmare/exponentiere, operatii cu constante sau cu transfer al datelor). Lungimea operanzilor este de 80 de biti, din care 64 de biti partea fractionara, 15 biti exponentul si un bit de semn. Pe baza codului instructiunii, a operanzilor din registrele interne sau furnizati de unitatea de control, unitatea de executie face operatia matematica rapid si cu precizie mare, dupa care depune rezultatul in unul din registrele interne sau il transmite unitatii de control pentru a-l depune in memorie.
Unitatea de control preia codul instructiunilor aritmetice din memorie, citeste/scrie operanzii din/in memorie si executa toate instructiunile de control ale 8086. Unitatea contine o serie de registri de control si stare, interfata pentru generarea adresei de memorie, interfata cu bus-ul de date si interfata cu unitatea de executie.
Schema bloc interna a 8087
3. Tipuri de date
Coprocesorul 8087 adreseaza sapte tipuri de date, folosind pentru aceasta modurile de adresare ale microprocesorului 8086. Tabelul urmator sintetizeaza cele sapte tipuri de date.
Tip Data |
Nr. biti |
Digiti semnifi- cativi |
Precizie |
Utilizare |
Cuvint Intreg |
16 |
4 - 5 |
16 biti |
index, contor, control program |
Intreg Scurt |
32 |
9 |
32 biti |
calcule cu numere intregi |
Intreg Lung |
64 |
18 |
64 biti |
extinderea gamei pt. calcule cu numere intregi |
Zecimal Impache- tat |
80 |
18 |
18 digiti |
conversii zecimale |
Real Scurt |
32 |
6 - 7 |
24 biti |
precizie ridicata pentru nr. reale mici |
Real Lung |
64 |
15 - 16 |
53 biti |
calcule in virgula mobila |
Real Temporar |
80 |
19 - 20 |
64 |
calcule de inalta precizie |
Formatul numerelor intregi nu se modifica, el avind acelasi inteles ca pentru microprocesorul 80x86 (primul bit codifica semnul, iar ceilalti valoarea in complement fata de 2; valoarea zero se reprezinta cu toti bitii zero).
a) Numerele zecimal impachetate contin 10 octeti, pe fiecare octet fiind memorati cite 2 digiti (in domeniul 0h - 9h). Aceste numere nu se memoreaza in complement fata de 2. Primul octet are bitul cel mai semnificativ semnul, urmatorii sapte nu prezinta interes.
79 78 . 72 71 64 63 .. 56 55 . 16 15 8 7 . 0
S - semnul (0 = pozitiv, 1 = negativ)
X - nu au semnificatie; 8087 ii ignora
Di - digitii ( i=17,16,,0)
b) Numerele reale sint reprezentate in trei modalitati, diferenta constind doar in lungime (numar de biti alocati); de fapt structura este aceeasi : bit de semn, exponent si mantisa.
Tipurile de reprezentari real scurt si real lung exista doar in memorie; daca un astfel de numar este incarcat intr-unul din registrele 8087, el este convertit la tipul real temporar - formatul utilizat in operatiile interne ale coprocesorului.
Tipul real scurt :
31 30 . 23 22 21 . 1 0
S |
E7 .. E0 |
f1 f2 f3 f22 f23 |
Tipul real lung :
62 . 52 51 50 49 .. 1 0
S |
E10 E0 |
f1 f2 f3 .. f51 f52 |
S - semnul
fi - bitii semnificativi ai partii zecimale
Ei - exponentul (127 = 7Fh pentru real scurt si 1023 = 3FFh pentru real lung)
Tipul real temporar :
78 . 64 63 62 . 1 0
S |
E14 E0 |
I0 f1 f2 f3 .. f62 f63 |
S - semnul
I0 - bitul intreg al mantisei
fi - bitii partii zecimale
EI - bitii exponentului (16383 = 3FFFh)
Nota : Punctul zecimal (virgula) se considera chiar la stinga bitului f1 !!
4. Diferente 8087-80287
Coprocesorul 80287 se utilizeaza alaturi de microprocesorul 80286 pentru a creste puterea de calcul si performantele, mai ales in modul de lucru protejat. In modul de lucru real, 80287 se comporta aproximativ ca un 8087. Pentru 80287 exista urmatoarele instructiuni suplimentare :
FSTSW - STore Status Word;
FNSTSW - STore Status Word, fara WAIT;
FSETPM - SET Protected Mode.
in schimb existind citeva instructiuni 8087 care nu se pot executa pe procesorul 80287 (vezi setul de instructiuni).
Alte diferente constau in :
a) 80287 semnaleaza o eroare in exterior prin intermediul semnalului ERROR de la microprocesorul 80286. Prin aceasta se arata ca precedenta instructiune a coprocesorului a generat o eroare nemascata. 80286 testeaza automat aceasta linie dupa incarcarea unei instructiuni in 80287 si daca nivelul e zero se genereaza INT 16 [1,2].
b) instructiunile 8087 pentru activarea (FENI/FNENI) sau dezactivarea (FDISI/FNDISI) intreruperilor nu sint recunoscute de catre 80287, care le ignora. De aici decurge si faptul ca rutinele care se executa corect pe 8087 nu se executa intotdeauna corect si pe 80287.
c) toate instructiunile 80287, cu exceptia celor de control a procesorului sint sincronizate cu unitatea centrala 80286. Aceasta este posibil din cauza ca, inainte de a executa urmatoarea instructiune ESCAPE, 80286 testeaza linia BUSY pentru a se asigura ca 80287 a terminat instructiunea precedenta. In acest fel instructiunile WAIT care erau necesare pentru 8086, aici nu-si mai au rostul.
d) deoarece 80287 nu cere instructiunea WAIT inaintea unei operatii numerice, asamblorul nu va produce cod pentru aceste instructiuni, daca s-a precizat in program, rezultind un cod mai compact.
e) In instructiunile coprocesorului 80287 se poate sa apara sau nu mnemonica WAIT sau NO-WAIT. Daca instructiunea de control este de tipul WAIT, atunci 80286 va executa inainte o instructiune WAIT.
SETUL DE INSTRUCTIUNI AL COPROCESORULUI 8087
5 Formatul instructiunilor
Instructiunile 8087 au un format asemanator cu cel de la 8086, cu precizarea ca fiecare cod de operatie incepe cu valoarea 11011 (ESC), ce precizeaza ca instructiunea este dedicata coprocesorului. Exista citeva tipuri de formate :
a) pentru instructiuni cu referire la memorie
11011 xxx mod xxx r/m deplasament
5 biti 3 2 3 3 1-2 octeti
b) pentru instructiuni cu referire la un registru
stiva
11011 xxx xxx ST(i)
5 biti 3 2 3 3
c) pentru instructiuni fara referinta explicita
11011 xxx xxxxxx
5 biti 3 2 6
6. Instructiuni de transfer
Prin instructiunile de transfer se asigura incarcarea, in registrul virf al stivei ST(0) (Stack Top) a unui numar de un anumit tip. De asemenea, ST poate fi transferat in memorie sau poate fi schimbat cu un alt registru. Operatiile de incarcare sau memorare ST(0) conduc la modificarea numarului care indica virful stivei (TOP) in urmatorul sens : incarcarea este similara cu un 'push' (TOP scade cu 1), iar memorarea este similara cu un 'pop' (TOP creste cu 1).
a) instructiuni de incarcare ST(0) (LoaD) :
FLD ST(i) push, ST(0) ST(i)
FLD mem10r push, ST(0) mem10r
FLD mem8r push, ST(0) mem8r
FLD mem4r push, ST(0) mem4r
FBLD mem10d push, ST(0) mem10d
FILD mem8i push, ST(0) mem8i
FILD mem4i push, ST(0) mem4i
FILD mem2i push, ST(0) mem2i
b) instructiuni de memorare ST(0) (STore)
FST ST(i) ST(i) ST(0)
FST mem8r mem8r ST(0)
FST mem4r mem4r ST(0)
FIST mem2i mem2i ST(0)
FIST mem4i mem4i ST(0)
FSTP ST(i) ST(i) ST(0), pop
FSTP mem10r mem10r ST(0), pop
FSTP mem8r mem8r ST(0), pop
FSTP mem4r mem4r ST(0), pop
FSTP mem10d mem10d ST(0), pop
FSTP mem8i mem8i ST(0), pop
FSTP mem4i mem4i ST(0), pop
FSTP mem2i mem2i ST(0), pop
c) instructiuni de interschimbare (EXCHange) :
FXCH ST(i) ST(0) ST(i)
FXCH ST(0) ST(1)
d) incarcarea unor constante
FLDL2E push, ST(0) log2e
FLDL2T push, ST(0) log210
FLDLG2 push, ST(0) lg2
FLDLN2 push, ST(0) ln2
FLDPI push, ST(0) PI (PI=3,1415)
FLD1 push, ST(0) +1.0
FLDZ push, ST(0) 0.0
7. Operatiile arimetice
(ADD, SUBstract, MULtiply, DIVide)
Vom descrie in aceasta sectiune instructiunile aritmetice de adunare, scadere, inmultire si impartire puse la dispozitie de coprocesor. Pentru aceste instructiuni destinatia este totdeauna intr-un registru stiva.
a) instructiuni de adunare (ADD
FADD ST(1) ST(1)+ST(0), pop
FADD ST(i) ST(0) ST(0)+ST(i)
FADD ST(0),ST(i) ST(0) ST(0)+ST(i)
FADD ST(i),ST(0) ST(i) ST(i)+ST(0)
FADDP ST(i),ST(0) ST(i) ST(i)+ST(0), pop
FADD mem8r ST(0) ST(0)+mem8r
FADD mem4r ST(0) ST(0)+mem4r
FIADD mem4i ST(0) ST(0)+mem4i
FIADD mem2i ST(0) ST(0)+mem2i
b) instructiuni de scadere (SUBstract)
FSUB ST(1) ST(1)-ST(0), pop
FSUB ST(i) ST(0) ST(0)-ST(i)
FSUB ST(0),ST(i) ST(0) ST(0)-ST(i)
FSUB ST(i),ST(0) ST(i) ST(i)-ST(0)
FSUBP ST(i),ST(0) ST(i) ST(i)-ST(0), pop
FSUB mem8r ST(0) ST(0)-mem8r
FSUB mem4r ST(0) ST(0)-mem4r
FISUB mem4i ST(0) ST(0)-mem4i
FISUB mem2i ST(0) ST(0)-mem2i
FSUBR ST(1) ST(0)-ST(1), pop
FSUBR ST(i) ST(0) ST(i)-ST(0)
FSUBR ST(0),ST(i) ST(0) ST(i)-ST(0)
FSUBR ST(i),ST(0) ST(i) ST(0)-ST(i)
FSUBRP ST(i),ST(0) ST(i) ST(0)-ST(i), pop
FSUBR mem8r ST(0) mem8r-ST(0)
FSUBR mem4r ST(0) mem4r-ST(0)
FISUBR mem4i ST(0) mem4i-ST(0)
FISUBR mem2i ST(0) mem2i-ST(0)
c) instructiuni de inmultire (MULtiply) :
FMUL ST(1) ST(1)*ST(0), pop
FMUL ST(i) ST(0) ST(0)*ST(i)
FMUL ST(0),ST(i) ST(0) ST(0)*ST(i)
FMUL ST(i),ST(0) ST(i) ST(i)*ST(0)
FMULP ST(i),ST(0) ST(i) ST(i)*ST(0)
FMUL mem8r ST(0) ST(0)*mem8r
FMUL mem4r ST(0) ST(0)*mem4r
FIMUL mem4i ST(0) ST(0)*mem4i
FIMUL mem2i ST(0) ST(0)*mem2i
d) instructiuni de impartire (DIVide)
FDIV ST(1) ST(1)/ST(0), pop
FDIV ST(i) ST(0) ST(0)/ST(i)
FDIV ST(0),ST(i) ST(0) ST(0)/ST(i)
FDIV ST(i),ST(0) ST(i) ST(i)/ST(0)
FDIVP ST(i),ST(0) ST(i) ST(i)/ST(0), pop
FDIV mem8r ST(0) ST(0)/mem8r
FDIV mem4r ST(0) ST(0)/mem4r
FIDIV mem4i ST(0) ST(0)/mem4i
FIDIV mem2i ST(0) ST(0)/mem2i
FDIVR ST(1) ST(0)/ST(1)
FDIVR ST(i) ST(0) ST(i)/ST(0)
FDIVR ST(0),ST(i) ST(0) ST(i)/ST(0)
FDIVR ST(i),ST(0) ST(i) ST(0)/ST(i)
FDIVRP ST(i),ST(0) ST(i) ST(0)/ST(i), pop
FDIVR mem8r ST(0) mem8r/ST(0)
FDIVR mem4r ST(0) mem4r/ST(0)
FIDIVR mem4i ST(0) mem4i/ST(0)
FIDIVR mem2i ST(0) mem2i/ST(0)
8 Instructiuni de comparare
Instructiunile de comparare se aplica asupra a doi registri, sau asupra unui registru si a unui numar aflat in memorie si au efect asupra indicatorilor de conditie C3,C2,C1,C0.
FCOM compara ST(0) cu ST(1)
FCOM ST(i) compara ST(0) cu ST(i)
FCOM mem8r compara ST(0) cu mem8r
FCOM mem4r compara ST(0) cu mem4r
FCOMP compara ST(0) cu ST(1), pop
FCOMP ST(i) compara ST(0) cu ST(i), pop
FCOMP mem8r compara ST(0) cu mem8r, pop
FCOMP mem4r compara ST(0) cu mem4r, pop
FICOM mem4i compara ST(0) cu mem4i
FICOM mem2i compara ST(0) cu mem2i
FICOMP mem4i compara ST(0) cu mem4i, pop
FICOMP mem2i compara ST(0) cu mem2i, pop
FCOMPP compara ST(0) cu ST(1), pop,pop
9 Instructiuni pentru evaluarea functiilor
Daca operatiile aritmetice de adunare, scadere, inmultire si impartire sint disponibile si pe 80x86, dar pentru numere intregi de 8 sau 16 biti, coprocesorul 80x87 efectueaza si operatii cu o precizie mult mai mare si in plus dispune de o serie de functii matematice utile in evaluarea expresiilor, aceasta fiind una din noutatile introduse de coprocesorul matematic.
FPREM ST(0) REPEAT(ST(0)-ST(1)), repeta operatia de scadere pina la un rest mai mic ca ST(1).
FRNDINT ST(0) ROUND(ST(0)), partea intreaga a lui ST(0).
FXTRACT push, ST(1) exponentul lui ST(0)
ST(0) partea intreaga a lui ST(0)
(extrage din ST(0) partea fractionara si exponentul).
FSCALE este instructiunea inversa lui FXTRACT (reface numarul din partea fractionara aflata in ST(0) si din exponent, aflat in ST(1)).
FSQRT ST(0) SQRT(ST(0)); radacina patrata din ST(0).
FABS ST(0) ABS(ST(0)), modulul din ST(0).
FCHS ST(0) -ST(0), schimba semnul lui ST(0).
FPTAN push, ST(1)/ST(0) TAN(ST(0)), cu 0 < ST(0) < < PI/4; evalueaza tangenta.
FPATAN ST(0) ARCTAN(ST(1)/ST(0)), pop; (inversa instructiunii FPTAN).
F2XM1 ST(0) 2.0ST(0) - 1, cu 0 < ST(0) < 0.5
FYL2X ST(0) ST(1)*log2ST(0), pop.
FYL2XP1 ST(0) ST(1)*log2(ST(0)+1.0), pop (0 < ST(0) < 1-SQRT(2)/2).
10. Instructiuni pentru comanda coprocesorului
Aceste instructiuni se refera la modul in care se pot modifica registrii de control si stare, controlul flagurilor, controlul virfului stivei, controlul intreruperilor si initializarea coprocesorului. Unele instructiuni se pot executa fara ca microprocesorul sa execute instructiunea WAIT, asa cum a fost explicat in sectiunile anterioare.
a) Initializarea coprocesorului
FINIT initializeaza 80x87.
FNINIT initializeaza 80x87, fara WAIT (No Wait).
b) Controlul intreruperilor
FENI activare intrerupere (ENable Interrupt).
FNENI activare intrerupere fara WAIT.
Aceasta instructiune este specifica pentru 8087 si nu se executa pe 80287, deoarece 80286 face supravegherea automata a erorilor pentru instructiunile 80287 !
FDISI dezactivare intreruperi (DISable Interrupt).
FNDISI (No wait). Analog anterior, instructiunile sint specifice pentru 8087 !
c) Operatii asupra cuvintului de control
FSTCW mem2i STore Control Word.
mem2i cuvintul de control 80x87.
FNSTCW mem2i (No wait).
FLDCW mem2i LoaD Control Word.
cuvintul de control 80x87 mem2i.
d) Operatii asupra cuvintului de stare
FSTSW AX AX cuvintul de stare.
FNSTSW AX (No wait).
FSTSW mem2i mem2i cuvintul de stare.
FNSTSW mem2i (No wait).
e) Operatii asupra mediului
FSTENV mem14 mem14 mediul 80x87 (STore ENVironment). Prin mediu intelegem cei 14 octeti definiti de : cuvintul de control, de stare, cuvintul caare arata continutul registrilor stiva (tag word), pointerul instructiune si pointerul operand.
FNSTENV mem14 (No wait).
FLDENV mem14 mediul 8087 mem14 (LoaD ENVironment).
f) Operatii asupra starii generale a coprocesorului (mediul + stiva
FSAVE mem94 mem94 starea 80x87.
Starea desemneaza cei 94 de octeti care definesc mediul si cei 8 registri de stiva.
FNSAVE mem94 (No wait).
FRSTOR mem94 starea 80x87 mem94.
g) Stergerea flagurilor pentru exceptii
FCLEX se sterg bitii P,U,O,Z,D,I (flaguri pentru exceptii) din cuvintul de stare.
FNCLEX (No wait).
h) Operatii asupra stivei
Instructiunile opereaza asupra bitilor TOP pentru a pointa catre alt registru ca virf al stivei.
FINCSTP INCrement Stack Top Pointer
TOP TOP + 1.
FDECSTP DECrement Stack Top Pointer
TOP TOP - 1
FFREE ST(i) elibereaza stiva pina la ST(i).
i) Trecerea in modul protejat
FSETPM SET Protected Mode.
j) Fara actiune
FNOP Not OPeration (fara actiune).
FWAIT indica o instructiune WAIT 80x86.
TEMA: Se vor scrie scurte secvente folosind instructiunile coprocesorului si se vor executa pas cu pas folosind DEBUG.COM si se va urmari cum se modifica zonele de memorie afectate.
APLICATII CU SETUL DE INSTRUCTIUNI 8087
11. Asamblorul TASM si coprocesorul matematic
Directive de asamblare utilizate
Asamblorul TASM permite definirea unor numere reale in doua formate: formatul MICROSOFT si formatul IEEE. Coprocesorul 8087 foloseste formatul IEEE: numarE[+|-]exponent
De exemplu 0,000032538 se defineste:
r_s DD 3.2538E-5
Constantele se pot defini si sub forma codificata. In acest caz ele trebuie urmate de indicatorul de numere reale (R). De exemplu:
ieee_short DD 3F800000R; 1.0 in format scurt
Este de precizat ca pentru numere reale scurte, TASM-ul tipareste pe listing numerele in ordinea CMSB la stinga, contrar reprezentarii interne calculatorului. Succesiunea 00 00 5B BE din memorie (care reprezinta un numar real scurt) se rearanjeaza : BE 5B 00 00 (cu CMSB la stinga). Se deduce :
semn = 1
caracteristica = 01111100
parte semnificativa = 10110000000000000000000
exponent = 7C-7F = -3
mantisa = 1.10110000000000000000000 = 1+0.5+0.125+0.0625 = = 1.6875
numar = (-1)**1*1.6875*2**(-3) = -0.2109375
EXEMPLUL 1 : In segmentul de date DS se considera 4 numere reale a1, a2, a3, a4 care incep la adresa simbolica 'var'. Sa se scrie programul care evalueaza in variabila 'expr' valoarea
expr=a1 + 2*a2 + 3*a3 + 4*a4.
Urmariti modul in care evolueaza valoarea lui 'expr' din memorie folosind depanatorul de programe.
TITLE EXMPL01
PAGE 1,1
COMMENT * Avind in memorie sirul var cu urmatoarea structura
a1,a2,a3,a4 dorim sa evaluam expresia :
expr= a1+(2*a2)+(3*a3)+(4*a4) *
STIVA SEGMENT PARA STACK 'STACK'
DW 256 DUP(?)
STIVA ENDS
DATA SEGMENT PARA PUBLIC 'DATA'
var dd 1.1,2.22,3.333,4.4444; definim ai-urile
aux dd 1.0
expr dt ? ;memoreaza rezultatul
DATA ENDS
Segment de cod
‑‑‑‑‑‑‑‑‑‑‑‑‑‑----- ----- --------
CODE SEGMENT PARA PUBLIC 'CODE'
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STIVA,ES:NOTHING
push ds
xor ax,ax ;init. pt. return
push ax
mov ax,DATA
mov ds,ax ;init. DS
mov cx,4 ;nr. variabile din expresie
mov bx,offset var ;adr. primului termen
finit ;initializare coprocesor
bucla:
fld [bx] ;incarc primul termen
;in ST(0)
fmul aux ; inmultim cu 1 (sau 2,3,4)
fstp expr ;memoreaza rezultat partial
fld1 ;st(0) <‑‑ 1.0
fadd aux ;calcul coeficient
fstp aux ;memoreaza in aux coeficientul
add bx,4 ;modificare offset
loop bucla
ret
MAIN ENDP
CODE ENDS
END MAIN
EXEMPLUL 2 : Fara a folosi instructiunea de interschimbare FXCH si fara variabile auxiliare, sa se interschimbe doua date reale 'var1' si 'var2' aflate in DS.
TITLE EXMPL02
PAGE 2,2
COMMENT * Avind in memorie doua variabile programul
realizeaza interschimbarea lor fara o variabila
auxiliara si fara instr. FXCH(eXCHange). Algoritmul
decurge dupa cum urmeaza:
B <== B ‑ A
A <== A + B
B <== A ‑ B *
STIVA SEGMENT PARA STACK 'STACK'
DW 256 DUP(?)
STIVA ENDS
DATA SEGMENT PARA PUBLIC 'DATA'
var1 DD 1.5 ;prima variabila
var2 DD 5.5 ;a doua variabila
varp1 DD ?
varp2 DD ?
DATA ENDS
Segment de cod
‑‑‑‑‑‑‑‑‑‑‑‑‑‑
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE,DS:DATA,SS:STIVA,ES:NOTHING
START:
push ds
xor ax,ax ;init. pt. return
push ax
mov ax,DATA
mov ds,ax ;init. DS
finit
fld var2 ;st(0) <== var2
fst st(1) ;st(1) <== var2
fld var1 ;st(0) <== var1
fsub st(1),st(0) ;st(1) <== st(1) ‑ st(0)
fadd st(1),st(0) ;st(0) <== st(0) + st(1)
fsubr st(1),st(0) ;st(1) <== st(0) ‑ st(1)
fstp varp1 ;varp1 <== st(0)
fld st(1) ;st(0) <== st(1)
fstp varp2 ;varp2 <== st(0)
ret
CODE ENDS
END START
EXEMPLUL 3 Sa se scrie secventele de program pentru calculul expresiilor :a) 2x, b) ex, c) 10x, d) xy pe baza urmatoarelor relatii :
2x = 1 + (2x - 1);
ex = 1 + (2x*log2e - 1);
10x= 1 + (2x*log2(10) - 1);
xy = 1 + (2y*log2(x) - 1);
Definirea datelor :
x DT 2.073E-2
y DT 3.8767E-4
2lax DT ?
elax DT ?
10lax DT ?
xlay DT ?
a)
wait
finit
fld x ; ST(0)=x
f2xm1 ; ST(0)=2x-1
fld 1 ; ST(0)=1, ST(1)=2x-1
fadd st,st(1) ; ST=2x-1+1=2x
fstp 2lax
b)
fld x ; x in virful stivei
fldl2e ; ST(0)=log2e, st(1)=x
fmul st,st(1) ; inmultire ST(0)*ST(1)
f2xm1 ; ST=2x*log2(e)-1
fld1 ; ST=1, ST(1)=2x*log2(e)-1
fadd st,st(1) ; ST=ex
fstp elax ;memoreaza in elax pe ST
c)
fld x
fldl2t ; ST(0)=log210, ST(1)=x
fmul st,st(1)
f2xm1
fld1
fadd st,st(1)
fstp 10lax
d)
fld y
fld x ; ST=x, ST(1)=y
fyl2x
f2xm1
fld1
fadd st,st(1)
fstp xlay
fwait
EXEMPLUL 4 In programul de mai jos sint prezentate instructiuni de control si comparare ale 8087.
TITLE EXEMPL04
;COMMENT * Prezinta citeva instructiuni de control si ; comparare ale coprocesorului matematic
CODE SEGMENT PARA PUBLIC
ASSUME CS:CODE,DS:CODE,SS:CODE
org 100h
start: jmp start1
cw DW (?) ;cuvint de control
sw DW (?) ;cuvint de stare
start1:
finit ; initializeaza coprocesor
fstcw [cw] ;
mov ax,[cw] ;| salveaza cuvintul de control si
mov di,ax ;/ pune‑l deoparte
mov ax,1800h ;
mov [cw],ax ;| seteaza modul de lucru al coprocesorului
fldcw cw ;/
fclex ; sterge flagurile pentru
; exceptii
fstsw [sw] ;
mov ax,[sw] ;| memoreaza in bx cuvintul de stare
mov bx,ax ;/
clc ;
mov cl,2 ;|
rcl ax,cl ;|
clc ;|
mov cl,4 ;| urmareste in carry valorile bitilor
rcl ax,cl ;| c3,c2,c1,c0 din cuvintul de tare al
clc ;| coprocesorului
rcl ax,1 ;|
clc ;|
rcl ax,1 ;/
fldl2e ; incarca in st(0) log2e
fldpi ; incarca in st(0) pi=3,14
fcom ; compara st(0) cu st(1)
fstsw [sw] ; memoreaza cuvintul de stare in dx
mov cx,[sw] ;/
fld st(1) ; incarca in st(0) st(1)
ftst ; compara st(0) cu 0
fstsw [sw] ; memoreaza cuvintul de stare in dx
mov dx,[sw] ;/
fcomp st(2) ; compara st(0) cu st(2) si extrage st(0)
fstsw [sw] ; memoreaza cuvintul de stare in si
mov si,[sw]
; Cuvintul de stare
; este memorat in registri diferiti dupa fiecare modificare ; ; pentru a se putea face o comparatie intre efectele
; instructiunilor asupra lui.
mov ax,4c00h ; revenire in DOS
int 21h ;/
CODE ENDS
END START
EXEMPLUL In segmentul de date, incepind de la adresa simbolica 'tab1' se gasesc 5 numere mari n0,n1,n2,n3,n4. Sa se aranjeze aceste numere in ordinea n4,n3,n2,n1,n0, incepind de la adresa 'tab2'.
TITLE EXMPL05
PAGE 3,3
COMMENT *Avind in memorie la adresa tab1 5 numere mari
asezate in ordinea n0,n1,n2,n3,n4 programul
realizeaza aranjarea lor in ordinea
n4,n3,n2,n1,n0 la adresa tab2*
STIVA SEGMENT PARA STACK 'STACK'
DW 512 DUP(?)
STIVA ENDS
DATA SEGMENT PARA PUBLIC 'DATA'
tab1 DT 23.55e23,24.56e22,25.6754e18,4556.82e76,723465e‑4
tab2 DT 5 dup(?)
DATA ENDS
Segment de cod
‑‑‑‑‑‑‑‑‑‑‑‑‑‑
CODE SEGMENT PARA PUBLIC 'CODE'
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STIVA,ES:NOTHING
push ds
xor ax,ax
push ax ;
mov ax,DATA
mov ds,ax ;pregatire DS
mov cx,5 ;contor numere
mov bx,offset tab1 ;inceput tab1
mov ax,offset tab2+40
finit ;initializare
et:
fld [bx] ;st(0) <== a0
add bx,10 ;un numar are 10 octeti
xchg ax,bx
fstp [bx] ;memorez a0 in tab2 pe poz. 4
sub bx,10
xchg ax,bx
loop et
ret
MAIN ENDP
CODE ENDS
END MAIN
Program pentru verificarea unor exceptii ale coprocesorului 80387.
;* Programul 'Impartire' calculeaza raportul X^256/Y^256 ; si cu ajutorul procedurii' Ver ' verifica si trateaza citeva ; din exceptiile ce pot sa apara. ;
S SEGMENT STACK 'STACK'
DW 10 DUP(?)
S ENDS
C SEGMENT
ASSUME CS:C, DS:C
X DD 10e‑37 ; In X se da deimpartitul
Y DD 10e+37 ; In Y se da impartitorul
XpeY DD ? ; In XpeY se va depune rezultatul
Cuvint DW ? ; Cuvint este folosit de instructiunile de
; comanda a coprocesorului matematic 8087
Div0 DB 13,10,'Impartire cu 0$'
Depasire_sus DB 13,10,'Rezultat prea mare$'
Depasire_jos DB 13,10,'Rezultat prea mic$'
Impartire:
mov ax,C ; Initializeaza registrul
mov ds,ax ; segment de date DS
finit ; Initializeaza coprocesorul
fld X ; Incarca X
fld Y ; Incarca Y
fclex ; Sterge flagurile pentru exceptii
fdiv ; Imparte X la Y
fmul St(0),St(0) ;
fmul St(0),St(0) ; | Ridica
fmul St(0),St(0) ; | raportul
fmul St(0),St(0) ; | X/Y
fmul St(0),St(0) ; | la
fmul St(0),St(0) ; | puterea
fmul St(0),St(0) ; | 256
fmul St(0),St(0) ;/
call Ver
mov ax,4C00h ; Preda controlul
int 21h ; sistemului de operare DOS
; Procedura 'Ver' verifica daca s‑a impartit la 0, daca numarul e prea mare sau daca numarul e prea ;mic.
Ver proc
fstsw Cuvint ; Depune cuvintul de stare in ; 'Cuvint'
mov BX,Cuvint ; Muta in BX 'Cuvint'
mov AX,BX ;
and AX,4h ; | Verifica flagul care
cmp AX,0 ; | indica impartire la 0
jne Imp_cu_0 ;/
mov AX,BX ;
and AX,8h ; | Verifica flagul care
cmp AX,0 ; | indica depasire sus
jne Dep_sus ;/
mov AX,BX ;
and AX,10h ; | Verifica flagul care
cmp AX,0 ; | indica depasire jos
jne Dep_jos ;/
ret
Imp_cu_0:
mov dx,offset Div0 ; Afiseaza
mov ah,9 ; | 'Impartire cu 0'
int 21h ;/ pe ecran
ret
Dep_sus:
mov dx,offset Depasire_sus ; Afiseaza
mov ah,9 ; | 'Rezultat prea mare'
int 21h ;/ pe ecran
ret
Dep_jos:
mov dx,offset Depasire_jos ; Afiseaza
mov ah,9 ; | 'Rezultat prea mic'
int 21h ;/ pe ecran
ret
Ver ENDP
C ENDS
END IMPARTIRE
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1743
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved