Sunteți pe pagina 1din 20

12. UTILIZAREA COPROCESORULUI MATEMATIC 12.

1 Arhitectura coprocesorului 8x87


Coprocesoarele 8x87/80287/80387, corespunzatoare celor trei game ale microprocesoarelor INTEL 80x86, sint module procesor specializate pentru calcule matematice, care lucreaza cu numere reprezentate in virgula flotanta (VF). Microprocesoarele 80486 i Pentium au integrat in ele si modulul deVF 80387 alaturi de un modulul binar 80386. Coprocesorul asigura cresterea considerabila a vitezei de executie a operatiilor aritmetice, calculul functiilor trigonometrice sau logaritmice si o crestere a preciziei de calcul (numarul de cifre semnificative). El este o extindere a resurselor procesorului de baza 80x86, ca registre si set de instructiuni, folosind in comun memoria centrala. Cele doua procesoare pot lucra in paralel, programul putind contine atit instructiuni de baza cit si in VF. Pentru sincronizarea lor in program se va folosi instructiunea FWAIT,inaintea instructiunilor 8x86, care folosesc date rezultate in memorie din prelucrari in 8x87. Mnemonicele coprocesorului incep cu litera F (FLD,FADD,..). MEMORIE CENTRALA Programe 8x86/87 Date 8x86/87

PROCESOR 8 x8 6

PROCESOR VF 8x87

Cele doua procesoare folosesc aceleasi magistrale de date si adresa (BUS). Coprocesorul nu are mecanism propriu de calcul al adreselor (segment,baza,index), acest calcul se face in 8x86, care-i furnizeaza adresa instructiunii curente (IP-instr.pointer) si adresa operandului (OP-operand pointer) in forma reala. Sunt admise toate modurile de adresare, dar adresa se calculeaz n procesorul de baz 8x86. Coprocesorul 8x87 nu are instruciuni propri de salt. Fazele executiei unei instructiuni 8x87 sint: - Citire instructiune de catre 8x86 - Calcul adresa operand in 8x86 - Comunicare adresa operand si cod instructiune spre 8x87 - Executie instructiune VF in 8x87 si memorare rezultat - Anuntare procesor 8x86 ca s-a terminat executia Instructiunile de VF sint recunoscute dupa primii 5 biti din codul operatiei, care sint aceeasi 11011 si se numesc ESCAPE. Cind lucreaza coprocesorul pune BUSY=1 (primul bit din status word), pentru a putea fi testat de procesorul 8x86 in WAIT.

Coprocesorul 8x87 contine: - Unitatea de comanda si control a transferurilor de informatii - Unitatea de executie a instructinilor in virgula flotanta - Registre generale de VF organizate ca stiva ST(0),ST(1),..ST(7) Registrele si caile interne ale coprocesorului VF sint de mare viteza si 80 biti (1semn,15-exponent,64-mantisa). Unitatea de comanda si control contine 5 registre (14 octeti), care pastreaza starea momentana a lui 8x87 (ENVIRONMENT). Ele pot fi memorate la adrese consecutive prin FSTENV (store environment) si ulterior incarcate prin FLDENV (load environment). +0 +2 +4 +6 +8 +10 +12 15 CONTROL WORD STATUS WORD TAG WORD INSTRUCTION POINTER OPERAND POINTER 0 -precizie,masti de intrerupere - indicatori,stare si intrerupere - indicatori reg - adresa reala, cod instructiune curenta - adresa reala operand

Starea completa a coprocesorului cuprinde si cele 8 registre generale (stiva) de 10 octeti fiecare (14+8*10=94 octeti),se poate memora prin FSAVE si restaura prin FRSTORE.Salvarea registrelor se face cu octetii mai putin semnificativi in fata si in ordinea ST(0),ST(1),....ST(7), dupa registrele ENVIRONMENT. Registrul INSTRUCTION POINTER pastreaza pe 20 biti adresa reala si codul instructiunii curente ( fara primii 5 biti 11011). 15 0 INSTRUCTION POINTER -low (bitii 15-0) IP -high | 0 | OPERATION CODE 15 12 10 0 Registrul OPERAND POINTER contine pe 20 biti adresa reala (calculata de 8x86) a operandului din memorie utilizat in instructiunea curenta. 15 0 OPERAND POINTER -low adress (bitii 15-0) OP high | 0 0 0 15 12 0

Registrele generale organizate ca stiva circulara are fiecare 80 biti,pentru precizie maxima (1-semn,15-exponent, 64- mantisa sau "significand"). Toate datele primite din memorie se convertesc si se pastreaza in VF format lung (temporary).Din memorie se pot incarca numere intregi binare,numere in zecimal codificat binar (BCD) de 18 cifre si numere

codificate in VF. Conversiile necesare se fac la citirea sau scrierea in memorie utilizind instructiuni specifice. 15 bii 64 bii S EXPONENT MANTISA R0 ST(6) R1 ST(7) R2 ST(0) <--TOP=2 R3 ST(1) ST(2) R7 79 63 0 ST(5)

La un moment dat oricare registru poate fi virful stivei ST(0), iar urmatorul ST(1).Celelalte registre vor avea o adresa relativa fata de ST(0). Numarul registrului virf de stiva se gaseste memorat in zona TOP din STATUS WORD. Operatiile de incarcare decrementeaza TOP cu 1 si incarca in noul registru ST(0). Operatiile de memorare cu "pop" memoreaza din ST(0) si incrementeaza TOP cu 1. Registrul STATUS WORD contine: - indicatorii de conditii, pozitionati dupa efectuarea instructiilor de comparatie/test, care se pot memora cu FSTSW (store status word) pentru a fi analizate de 8x86, cind trebuie sa se faca salturi conditionate (8x87 nu are instructiuni de salt). - bitii care indica aparitia unor cereri intreruperi spre 8x86, sau datorate rezultatelor obtinute - indicatorul registrului virf de stiva TOP 15 B 14 C3 13 10 9 TOP C2 C1 8 C0 7 IR 6 5 P 4 U 3 O 2 Z 1 D 0 I

B =1 - coprocesor 8x87 ocupat C3--C0 - indica rezultatul unei comparatii sau test C0 =1 - ST(0) < sursa (echivalent cu S la 8x86) C3 =1 - ST(0) > sursa (echivalent cu Z la 8x86) TOP =0...7 - indica nr. registru virf de stiva IR =1 - cerere intrerupere la 8x86 (intrerupt request) P U O Z D I - indicatori intreruperi datorate rezultatului P =1 - precision -s-a pierdut un bit si rezultatul rotunjit U =1 - underflow -exponent prea mic (depasire inferioara) 0 =1 - overflow prea mare (depasire superioara) Z =1 - zero divide - impartire numar # 0 cu zero D =1 - denormalized - numar nenormalizat I =1 - invalid operation - 0/0, infinit/infinit,nenumeric Intreruperea se poate anula cu FCLEX (clear 8x87). Registrul CONTROL WORD contine indicatori de stabilire precizie si masti de intrerupere: 15 rezervat 12 IC 11 RC 9 PC 7 IEM x 5 PM 4 UM 3 OM 2 ZM 1 0 DM IM

IC - Infinit Control 0 - nu face distinctie intre + si - infinit 1 - face distinctie intre + si - infinit RC - Rounding Control - stabileste modul de rotunjire 00 - rotunjire la cel mai apropiat ( implicit ) 01 - rotunjire in sus 10 - rotunjire in jos 11 - trunchiere PC - Precizion Control - precizie de lucru prescrisa(rotunjire) 00 - 24 biti pentru mantisa - short real 01 - rezervat 10 - 53 biti - long real 11 - 64 biti - temporary real ( implicit ) IEM - Intrerupt Enable Mask - implicit = 1 (mascate) 0 - intreruperile nemascate,tratate prin procedura utilizator 1 - toate intreruperile sint tratate standard de 8x87 x - rezervat (bit 6) Mastile specifice intreruperilor pot avea valorile: 0 - intrerupere exceptie tratata prin procedura utilizator 1 - intreruperea exceptie este mascata (implicit) Raspunsurile la fiecare exceptie mascata (masca = 1)sint: PM - Precision Mask - furnizeaza rezultatul rotunjit UM - Underflow Mask - rezultat = 0 OM - Overflow Mask - rezultat = numar maxim cu semn ZM - Zero divide Mask -rezultat = numar maxim cu semn DM - Denormalized - continua calculul cu nr.nenormalizat IM - Invalid operation Mask - rezultatul este valoarea nenumerica a operandului (ex: radical din numar negativ) Registrul TAG WORD contine 8 grupe de 2 biti numite TAG(0), TAG(1),...TAG(7) corespunzatoare celor 8 registre generale ST(0), ST(1),....ST(7). Fiecare TAG(I) indica continutul lui ST(I) : TAG(I) = 00 - valoare valida in ST(I) normalizata sau nu 01 - zero in ST(I) 10 - continut special nenumeric,+ sau - infinit,anormal 11 - valoare zero de initializare

12.2 Tipuri de date


Sint admise 7 tipuri de date, care pot fi operanzi din memorie si care prin incarcare se convertesc in format intern Virgula Flotanta (VF) pe 80 biti numit Temporary Real.In registrele interne se pastreaza datele numai in format VF de unde se pot memora in alte formate prin instructiuni specifice, care asigura si conversia. Specificarea adresei operandului se poate face in toate modurile admise de 8x86, care asigura calcularea adresei. In toate tipurile primul bit este considerat semn, iar bitii din stinga sint cei mai semnificativi. Caracteristicile tipurilor admise sint date in tabelul urmator:

Tip date Biti Cifre zec. Precizie Exponent* WORD INTEGER 16 4-5 16 biti nu SHORT INTEGER 32 9 32 biti nu LONG INTEGER 64 18 64 biti nu PACKED DECIMAL 80 18 18 cif.zec nu SHORT REAL 32 6-7 24 biti 127 (8) LONG REAL 64 15-16 53 biti 1023 (11) TEMPORARY 80 19-20 64 biti 16383 (15) REAL *Exponentul este utilizat ca putere a lui 2, iar in paranteza se da puterea corespunzatoare a lui 10 pentru domeniul maxim. In real mantisa este pozitiva si da precizia, iar semnul este al mantisei (S = 1 negativ). Bitii de exponent dau caracteristica (CAR), care este pozitiva. Valoarea exponentului (EXP) se calculeaza: EXP = CAR - 7FH - pentru SHORT REAL - 3FFH - pentru LONG REAL - 3FFFH - pentru TEMPORARY REAL Valoarea unui numar real - N (reprezentat in virgula flotanta) se calculeaza dupa formula: N = M*2**EXP unde: M - este valoarea mantisei 1 < M < 2 EXP - valoare calculata exponent Tipurile intregi cu semn sint cele acceptate de procesorul 8x86 si de Macroasamblor prin directivele de definire date: DW - define word - pentru WORD INTEGER ( 16 biti ) DD - define double-word - pt. SHORT INTEGER ( 32 biti ) DQ - define quad-word - pt. LONG INTEGER ( 64 biti ) Tipul PACKED DECIMAL utilizeaza 10 octeti si este un numar zecimal codificat binar cu semn (BCD), avind 18 cifre zecimale, codificate fiecare pe 4 biti (doua pe octet). Primul octet contine doar semnul pe primul bit. 79 S 71 63 56 .......... 15 7 * D17D16 D15D14 D13 .......... D4 D3D2 Tipul este recunoscut de macroasamblor prin definitia: DT -define ten-byte in care valoarea se specifica in hexa 0 D1D0

Tipurile reale sint numere codificate in virgula flotanta unde reprezentarea se face prin mantisa pozitiva (significant), caracteristica si semn. Mantisa se trece intotdeauna intr-o forma normalizata 1 < M < 2 de forma: 1^ffffffff unde: ^ - este punctul zecimal virtual f - sint biti fractionari (23, 52 sau 63) Bitul intreg este implicit dar nu exista in memorie pentru formatul SHORT si LONG, el existind fizic numai la TEMPORARY REAL. SHORT REAL 31 30 S E7 .. . 22 EO f1 f2 0 .... f22 f23 - in mantisa 1 este implicit

exponent LONG REAL 63 62 S E10

mantisa 51 E0 f1 f2 f3 0 f51 f52

- EXP < 127 (7FH) - mantisa 6-7 cifre zecimale

.......

EXP < 1023 (3FFH) - mantisa 15-16 cifre zec. 0 f62 f63

TEMPORARY REAL 79 78 63 S E14.... E1 E0 1^f1 f2 f3 f14

......

EXP < 16383 (3FFFH) - mantisa 19-20 cifre zecimale

12.3 Asamblarea programelor


Pentru generare de cod pentru coprocesor Macroasamblorul se poate lansa in doua moduri MASM ...... /R - genereaza cod real executabil pe 8x87 existent /E - emulare - genereaza chemari de subprograme din biblioteca pentru mnemonice 8x87 intilnite Codurile instructiunilor 8x87 generate in modul /R pot fi executate fara a exista fizic coprocesorul daca se lanseaza inainte : EM87 /L Acesta incarca un emulator 8x87 rezident in memorie, care se apeleaza prin intreruperile de exceptie instructiune inexistenta, declansate de codurile 8x87 din program. La terminarea programelor care utilizeaza mnemonici 8x87 emulatorul se elimina prin: EM87 /U - descarcare emulator 8x87 din memorie Pentru ca macroasamblorul sa recunoasca mnemonicele 8087 in program, trebuie inainte sa se dea comanda: .8087 Daca se utilizeaza alte coprocesoare se vor da comenzile: .287 - pentru 80287 .387 - daca se utilizeaza 80387 sau procesorul 80486 Pentru specificarea setului de instructiuni se utilizeaza: .286C - set comun neprivilegiat 80286 .286P - set privilegiat 80286 .386 - set instructiuni 80386 Pentru testarea programelor care utilizeaza coprocesorul, depanatorul AFD nu poate fi folosit, deoarece nu recunoaste setul de instructiuni al coprocesorului si se recomanda CODVUE. OBSERVATIE In macroasamblor nu exista definitii de tipuri speciale de date pentru coprocesorul 8x87, ele fiind recunoscute prin lungimea definita de instructiunile de VF ce le utilizeaza: X1 dw 4530 - intreg pe 2 oct. utilizabil de 8x86 sau 8x87 X2 dd 4530 - intreg pe 4 oct. utilizabil de 80386 sau 8x87 X3 dq 4530 - intreg pe 8 oct. utilizabil de 8x87 (LONG) X4 dt 4530H - packed decimal (10 oct.) utilizabil de 8x87

X5 X6 X7

dd dq dt

45.30 - short real (4 oct.) utilizabil de 8x87 4.53E+4 - long real (8 oct.) utilizabil de 8x87 4530.0 - temporary real (10 oct.) direct utiliz. 8x87

12.4 Instructiuni pentru transfer de date la 8x87


Coprocesorul 8x87 executa 69 instructiuni (72 la 80287). Instructiunile de transfer 8x87 executa incarcarea(sau memorarea) datelor, de tipurile precizate, din memorie in registrul ST(0), sau intre registrele 8x87. Schimbul de date cu memoria este insotit de conversia lor in temporary real daca e cazul, sau ajustarea mantisei si exponentului,pentru SHORT si LONG REAL. Toate instructiunile de incarcare decrementeaza inainte stiva.Nu exista instructiuni imediate. Pentru transferul datelor intre locatii de memorie se folosesc instructiunile 8x86 cunoscute. Pentru precizarea unei adrese de operand din memorie se pot folosi toate modurile de adresare. Reg. ST(0) se poate nota ST. Prezentam sintetic instructiunile din aceasta grupa: Transferuri de numere intregi: FILD intreg - integer load - incarca din memorie in ST FIST intreg - integer store - memorare ST ca intreg FILDP intreg - idem FILD urmat de decrem. stiva reg. (pop) FRNDINT - rotunjire la intreg a lui ST Transferuri de numere zecimale codificate binar: FBLD decimal - BCD load - incarcare nr. zecimal din memorie FBST decimal - BCD store - memorare ST ca nr.zecimal Transferuri de numere reale intre ST si memorie: FLD real - incarcare numar real din memorie in ST FST real - memorare ST la o adresa de memorie FSTP real - idem ca FLD urmat de decrem. stiva registre

Transferuri intre ST si registrele stiva: FLD ST(I) - ST(I) -> ST FLD ST - copiaza ST in sus in stiva de registre FST ST(I) - ST -> ST(I) FSTP ST(I) - ST -> ST(I) si incrementare stiva reg.(pop) FXCH - ST <=> ST(1) interschimb FXCH ST(I) - ST <=> ST(I) FXTRACT - exp(ST) => ST , mantisa(ST) => ST(1) si push FDECSTP - decrementare stack pointer registre FINCSTP - incrementare stack pointer Incarcari de constante in ST: Pentru a suplini lipsa incarcarilor imediate exista instructiuni care incarca in ST anumite constante, des folosite in calculele matematice. Incarcarea incepe cu decrement FLDZ 0.0 => ST - constanta zero in VF FLD1 1.0 => ST - constanta 1.

FLDPI 3.14.. => ST - constanta PI FLDL2E log in baza 2 din E => ST FLDL2T log in baza 2 din 10 => ST FLDLG2 log in baza 10 din 2 => ST FLDLN2 log natural din 2 => ST Pentru incarcarea altor valori de constante, ele se vor defini in memorie cu un tip recunoscut in VF si vor fi incarcate prin instructiunile corespunzatoare tipului. Instructiuni pentru registrele de stare FSTSW dest - memorare STATUS WORD la o adresa de memorie FSTSW AX - memorare STATUS WORD in AX (la 80287) FCLEX - sterge flag-uile exceptie,intrerupere,busy Prin instructiunea FSTSW indicatorii de conditii 8x87, pozitionati dupa executia instructiunilor de VF, se depun in memorie sau AX de unde se pot depune in reg. FLAGS al lui 8x86 prin SAHF (instructiune 8x86). Valoarea acestor indicatori se poate testa prin instructiunile de salt conditionat (Jcond), uzuale pentru a realiza ramificari ale programului. Mentionam ca 8x87 nu are instructiuni proprii de salt. Indicatorii C3 - C0 se vor memora automat peste Z si S. Reg. FLAGS se poate incarca in AH prin LAHF. FSTCW FLDCW FSTENV FLDENV FSAVE FRSTORE dest sursa dest sursa dest sursa - memoreaza reg. CONTROL WORD - incarca din memorie reg. CONTROL WORD - memorare reg. ENVIRONMENT (14 octeti) - incarca din memorie reg. ENVIRONMENT - salvare ENVIRONMENT + reg.generale (94oct) - restaurare ENVIRONEMENT si reg.generale

Toate unstructiunile din aceasta clasa includ un FWAIT pentru sincronizare cu 8x86. Ele au si forma fara FWAIT cind au prefixul FN (ex: FNSTSW,FNSTCW, ...FNSAVE, FNRSTORE).

12.5.Instructiuni aritmetice in VF
Aceasta grupa cuprinde instructiuni puternice de calcul matematic, pentru care a fost conceput coprocesorul matematic. La 80287 fata de 8x87, se adauga doar 3 instructiuni pentru control in mod protejat. Setul lui 80387 cuprinde citeva instructiuni in plus care vor fi indicate. FWAIT - asteapta terminarea unei instructiuni 8x87 FNOP - nici o operatie FABS - valoare absoluta din ST |ST| => ST Adunari real - real FADD FADD ST,ST(I) FADD ST(I),ST FADD real FADDP ST(I),ST Scaderi real - real ST(1) + ST => ST(1) -adunare registre ST + ST(I) => ST ST + ST(I) => ST(I) ST + real => ST -real din memorie ST + ST(I) => ST(I) -adunare urmata de incrementare stiva registre (pop)

FCHS - schimba semnul lui ST (change sign) FSUB ST(1) - ST => ST(1) - scadere reg. FSUB ST,ST(I) ST - ST(I) => ST FSUB ST(I),ST ST(I) - ST => ST(I) FSUB real ST - real => ST -real din memorie FSUBP ST(I),ST ST(I) -ST => ST(I) -scadere si pop Scaderi reale inverse (reversed) FSUBR ST - ST(I) => ST(I) -substract real reversed FSUBR ST(I),ST ST - ST(I) => ST(I) FSUBR ST,ST(I) ST(I) - ST => ST FSUBR real real - ST => ST -real din memorie FSUBRP ST(I),ST ST - ST(I) => ST(I) -scadere si pop reg Comparatii numere reale FCOM ST - ST(1) => pozitionare indicatori de conditie FCOM ST(I) ST - ST(I) => pozit.indic.conditie FCOM real ST - real => pozit.indic.conditie FCOMP ST(I) ST - ST(I) -comparatie si apoi pop reg FCOMPP -compara ST cu ST(1) si apoi dubla incrementare(pop) FTST -compara ST cu 0 ST - 0 => pozit.indic.(test ST) FXAM -examineaza ST si poz.indicatorii C3,C2,C1,C0 pentru cazul unor rezultate anormale(depasiri inferioare sau superioare) Comparatia consta dintr-o scadere a operandului specificat din valoarea lui ST si pozitionarea indicatorilor de conditie, functie de rezultat (valoarea operanzilor nu se shimba) astfel: C3(Z) C0(S) 0 0 pt. ST > referinta (rezultat > 0) 0 1 ST > referinta (rezultat < 0) 1 0 ST = referinta (rezultat = 0) 1 1 -rezultat +infinit sau -infinit Indicatorii C3--C0 fac parte din primul octet din STATUS WORD, se memoreaza cu FSTSW AX, in AX de unde se depun cu SAHF in reg FLAGS si se pot testa cu instructiuni de salt conditionat. Operatii real - intreg FIADD intreg ST + intreg => ST -intreg din memorie FISUB intreg ST - intreg => ST FISUBR intreg intreg - ST => ST -substract reversed FICOM intreg ST - intreg => pozitioneaza indicatorii FICOMP intreg comparatie ST cu intreg si pop reg FIMUL intreg ST*intreg => ST -inmultire cu intreg Operandul intreg, de orice lungime, este citit din memorie, convertit in VF (real) si utilizat in instructiune. Operatii de inmultire si impartire in VF FMUL ST(1)*ST => ST(1) -inmultire real - real FMUL ST(I),ST ST(I)*ST => ST(I) FMUL ST,ST(I) ST*ST(I) => ST FMUL real ST*real => ST -real din memorie FMULP ST(I),ST ST(I)*ST => ST -inmultire si pop

FDIV FDIV ST(I),ST FDIV ST,ST(I) FDIV real FDIVP ST(I),ST FDIVR FDIVR ST(I),ST FDIVR ST,ST(I) FDIVR real FDIVRP ST(I)/ST Instructiuni speciale

ST(1)/ST => ST(1) -impartire real - real ST(I)/ST => ST(I) ST/ST(I) => ST ST/real => ST -real din memorie ST(I)/ST => ST -impartire si pop ST/ST(1) => ST(1) -divide reversed ST/ST(I) => ST(I) ST(I)/ST => ST ST/real => ST -real din memorie ST(I)/ST => ST(I) -divide rev. si pop

In aceasta grupa am cuprins instructiuni de calcul functii exponentiale, logaritmice si trigonometrice usuale: FPREM pentru ST/ST(1) da restul partial (modul) in ST FSQRT radicalul din ST => ST pt. ST > 0 FCOS cos(ST) => ST - calcul cos(x) numai 80387 FSIN sin(ST) => ST - calcul sin(x) numai 80387 FPTAN tang(a) - pentru 0 < a < PI/4 - rezultatul sub forma x/y in ST si ST(1) FPATAN arctg(x/y) => ST - unde x in ST si y in ST(1) - rezultatul in noul ST care este dupa pop in locul lui y FSCALE calculeaza f= ST*2**ST(1) => ST - interpreteaza ST(1) ca intreg si il adauga la exponentul lui ST pentru a obtine inmultirea cu 2 la puterea N FYL2X calculeaza f= Y*log2(X) =>ST (peste Y dupa pop) - se cere X>0 in ST si Y -real in ST(1) FYLN2XP1 calculeaza f= Y*log2(X+1) =>ST (peste Y dupa pop) - se cere X>0 in ST si Y -real in ST(1) pt.X<rad(2)/2 (0.75) F2XM1 calculeaza f= 2**X-1 =>ST -unde X in ST Aceasta functie permite calculul functiilor exponentiale pentru orice baza prin formulele cunoscute: 10**X = 2**X*log2(10) e**X = 2**X*log2(e) - unde e este baza log. naturali Y**X = 2**X*log2(Y) Constantele logaritmice se incarca prin FLDL2T si FLDL2E.

12.6 Exemple de programe cu instructiuni 8x87


Folosind instructiunile prezentate si exemplele de program se vor scrie programe, care sa utilizeze numere reale, intregi si zecimale codificate binar (BCD) pentru calcule matematice utizind coprocesorul 8x87, real s-au emulat cu EM87 /L. - Se va asambla programul si pentru datele constante generate cu diferite lungimi se va studia modul de codificare si se vor calcula valorile in zecimal pentru numerele reale. - Se va studia modul de codificare a instructiunilor de VF

10

- Se va scrie un program pentru una din problemele: - rezolvarea unei ecuatii de gradul 2, - calcul sin(x) si cos(x) prin dezvoltare in serie, - extragerea radacinii patrate dupa formula iterativa: X(i)= [N/X(i-1)+X(i-1)]/2 - unde X(1)=N/2 - calculul unei integrale definite cu metoda trapezelor Prezentam mai jos listingul unui exemplu de program simplu in care se declara diferite tipuri de variabile si se executa citeva instructiuni. Programul va trebui lansat din DOS sau CodeView. El va afisa pe ecran rezultatul adunarii a doua numere zecimale codificate binar Y3 = Y1 + Y2. Cele doua numere au fost alese incit rezultatul sa fie de "tip ASCII" pentru a putea fi afisat direct pentru verificare. Se va afisa 8754. EM87 / l -incarcare emulator rezident in memorie MASM ex1f.asm,ex1f,ex1f /r - macroasamblare cu instr.VF reale ---------------------------------------------------------------Microsoft (R) Macro Assembler Version 5.00 6/9/93 23:29:14 Page 1-1 adresa cod generat etic. instructiuni 0100 * segment de date * 0000 .data 0000 1B2F5D40 0004 33338340 0008 08070504000000000000 0012 30303030000000000000 001C 00000000000000000000 0026 24 0027 00000000 002B 0000803F 002F 0000A040 .model small .stack 256 x1 x2 y1 y2 y3 db x3 x4 x5 dd dd dt dt dt '$' dd dd dd 3.456 4.1 4050708h 30303030h 0 0 1.0 5.0

* segment de cod cu specificare coprocesor * .8x87 0000 .code 0000 B8 ---- R st1: mov ax,@data 0003 8E D8 mov ds,ax 0005 9B D9 06 0000 R fld x1 000A 9B D8 06 0004 R fadd x2 000F 9B D9 16 0027 R fst x3 0014 9B DF 26 0008 R fbld y1 0019 9B DF 26 0012 R fbld y2 001E 9B D8 C1 fadd st,st(1) 0021 9B DF 36 001C R fbstp y3 * afisare text pe ecran * 0026 BA 001C R mov dx,offset y3 0029 B4 09 mov ah,9 002B CD 21 int 21h 002D B4 4C mov ah,4ch 002F CD 21 int 21h 11

0031

end

st1 6/9/93 23:29:14

Microsoft (R) Macro Assembler Version 5.0 Segments and Groups: Name DGROUP .. . . . . . . . . . . _DATA . . . . . . . . . . STACK . . . . . . . . . . _TEXT . . . . . . . . . . . Symbols: Name ST1 . . . . . . . . . . . . X1 . . . . . . . . . . . . . X2 . . . . . . . . . . . . . X3 . . . . . . . . . . . . . X4 . . . . . . . . . . . . . X5 . . . . . . . . . . . . . Y1 . . . . . . . . . . . . . Y2 . . . . . . . . . . . . . Y3 . . . . . . . . . . . . . Type L NEAR L DWORD L DWORD L DWORD L DWORD L DWORD L TBYTE L TBYTE L TBYTE

Length Align Combine Class GROUP 0033 WORD PUBLIC 'DATA' 0100 PARA STACK 'STACK' 0031 WORD PUBLIC 'CODE' Value Attr 0000 0000 0004 0027 002B 002F 0008 0012 001C _TEXT _DATA _DATA _DATA _DATA _DATA _DATA _DATA _DATA

@CODE . . . . . . . . . . . . . TEXT @CODESIZE . . . . . . . . . . . @DATASIZE . . . . . . . . . . . @FILENAME . . . . . . . . . . . 30 Source Lines 30 Total Lines 23 Symbols

_TEXT TEXT 0 TEXT 0 TEXT ex1f

50940 + 309892 Bytes symbol space free 0 Warning Errors 0 Severe Errors ------------------------------------------------------------------Se observa ca numerele zecimale Y1 si Y2 se aliniaza la stinga unde cifrele au si ponderea cea mai mare. Numerele X1 si X2 care sint reprezentate in VF (reale) au octetii inversati, incit exponentul si ponderile mai mari apar in dreapta. Variabila X3=0 are atit mantisa cit si exponentul 0. X4 = 1. are reprezentarea 00 00 80 3F care in registru va fi: 3F 80 00 00 Deoarece primul bit din octetul 2 este din exponent printr-o deplasare spre stinga obtinem: 7F 00 00 00 deci EXP = 7F - 7F = 0

12

Mantisa este aparent 0 dar contine un 1. care in SHORT REAL nu se reprezinta. Ea este pentru numerele normalizate: 1 =< Mantisa < 2 deci Mantisa = 1 pentru X4 Valoarea lui X4 va fi: X4 = M*2**EXP = 1.*2**0 = 1. Procedam la fel pentru X5 = 5. care e reprezentat 00 00 A0 40 In registru va fi 40 A0 00 00 si dupa o deplasare stinga devine: 81 40 00 00 avind deci EXP = 81 - 7F = 2 Mantisa este M = 1. + 4/16 + 0/256 = 1.25 X5 = M*2**EXP = 1.25*2**2=1.25*4 = 5. care e valoarea corecta Se observa ca pentru a simplificarea calculului mantisei lucram cu puterile negative a lui 16 si cu cifrele hexa din mantis. Calculam si valoarea lui X2 = 4.1 care se reprezinta prin: 33 33 83 40 si devine dupa inversarea cifrelor 40 83 33 33 iar dupa o deplasare dreapta 81 06 66 66 .Rezulta exponentul: EXP = 81 - 7F = 2 iar mantisa: M = 1. + 0/16 + 6/(16*16) + 6/(256*16) + 6/(256*256) + ... X2 = 2**2 *M = 4*M = 4 + 24/256 + 24/(256*16) +..=4.09375+0.00586 X2 = 4.09961 cu o aproximatie sub destul de buna sub 1% desi am neglijat ultimele 3 cifre hexa din mantisa Program de calcul pentru functia exponentiala Calculam valoarea functiei exponentiale prin descompunerea in serie dupa formula: E**x = 1 + x/1! + x**2/2! x**3/3! + x**4/4! + .... Calculam suma iterativ S = S + T pina cind termenul T devine mai mic decit EPS = 0.0001 Un termen Ti il calculam dupa formula T = T*X/I Variabilele folosite si valorile initiale sint: S - suma partiala, initial S = 1 T - valoarea termenului curent, initial T = 1 I - rangul termenului curent, initial I = 1 In dreapta programului se vede structura considerata pentru stiva de registre a coprocesorului in momentul initial. ; ----------------------------------------------; PROGRAM DE CALCUL EXP(X) ; -----------------------------------------------.MODEL SMALL .STACK 256 .80287 .DATA EPS DD 0.00001 ;precizie X DD 2.541 EX DD 0. ;valoare calculata ST-----> +0 T=1 +1 I=1 .CODE +2 S=1 START: MOV AX,@DATA +3 1 MOV DS,AX +4 X ; Fiecare incarcare de registru e precedata de +5 decrem. stiva reg. FLD X ; incarcare X real 13

FLD1 ; incarcare constanta 1. FLD ST ; S=1 FLD ST ; I=1 FLD ST ; T=1 CICLU: FMUL ST,ST(4) ; T=T*X =>ST FDIV ST,ST(1) ; T=T*X/I FADD ST(2),ST ; S=S+T FINCSTP ; incrementare pointer reg. FADD ST,ST(2) ; I=I+1 FDECSTP ; refacere pointer reg. FCOM EPS ; T < EPS ? FSTSW AX ; salvare indicatori si test FWAIT ; asteptare terminare instr. VF SAHF ; memorare indicatori in reg. FLAGS JL GATA ; test S=1 (indicator C0) JMP CICLU FLD ST,ST(2) ; memorare rezultat FST EX GATA: MOV AH,4CH INT 21H ; iesire in DOS END START

12.7. Conversie numere din intreg in flotant


Consideram un numar binar intreg pe 4 octeti (32 biti), care il vom converti in virgula flotanta (VF) pe 4 octeti (SHORT REAL) Numar intreg 23c.b. N , - virgula pentru mantisa VF 127+23

, - virgula intreg

CAR

- caracteristica initiala numar intreg

Consideram numarul pozitiv intreg N, care are virgula virtuala in dreapta, ca o mantisa supraunitara cu o caracteristica CAR asociata: N = N*2**0 => EXP = 0 => CAR = EXP+127 = 127 Daca N este considerat o mantisa pentru reprezentarea VF short real, atunci virgula va fi vazuta deplasata cu 23 c.b. spre stinga. Pentru a nu schimba valoarea numarului, care devine N*2**(-23), trebuie sa marim caracteristica cu 23. Pastrind separat mantisa si caracteristica vom avea un numar in VF cu: M = N*2**(-23) si CAR = 127+23 = 150 -caracteristica initiala Cum numarul nostru in VF este in general nenormalizat, il vom supune unei normalizari, utilizind o macroinstructiune NF4, pe care o vom defini si care apeleaza un subprogram SNF4. Numarul ce se normalizeaza va fi dat prin mantisa M1 si caracteristica C1 separate. Ele vor fi incarcate in DX:AX si respectiv in BX de macroinstructiunea NF4, 14

care dupa chemarea subprogramului SNF4 obtine numarul in flotant in DX:AX si il memoreaza peste mantisa initiala (vezi programul alaturat). Subprogramul SNF4 considera ca mantisa este nenormalizata, existind 2 cazuri: a) - Este ocupata zona caracteristicii (primul octet), caz in care se fac deplasari spre dreapta a mantisei si incrementari corespunzatoare ale caracteristicii, pentru a nu modifica valoarea numarului. b) - Mantisa are zerouri pe primele pozitii dupa virgula si in acest caz se fac deplasari spre stinga si decrementari ale caracteristicii, pina cind primul bit din octetul 2 al mantisei devine 1. Deplasarile spre stinga sau dreapta ale mantisei, ce se gaseste in registrele DX:AX se face combinind o deplasare a unui registru cu rotirea prin carry a celuilalt. Dupa ce mantisa a fost normalizata, primul bit care este 1 implicit se sterge si mantisa se concateneaza cu caracteristica. Daca avem macroinstructiunea de normalizare NF4, atunci conversia unui numar intreg in VF se reduce la o normalizare cu o caracteristica initiala CAR=150 Pentru exemplificare consideram numarul intreg N = 5 N = 00 00 00 05 si CAR = 127 + 23 = 150 = 96H Pentru normalizare sint necesare 21 deplasari spre stinga: M = 00 A0 00 00 si CAR = 150 - 21 = 129 = 81H Prin suprimarea bitului 1 implicit rezulta: M = 00 20 00 00 Adaugind caracteristica obtinem numarul in flotant: NF = 40 A0 00 00 care reprezinta in flotant numarul intreg 5. ; -------------------------------; PROGRAM DE CONVERSIE INTREG REAL ; --------------------------------.286c .287 dosseg .model small .stack 100 .data x dd 51420 ; nr intreg xf dd 51420. ; nr in vf cx1 dw 127+23 ; caracteristica implicita .code ; Definitie macro pt normalizare vf nf4 MACRO c1,m1 ; caract. si mantisa PUSHA ; salvare registre mov ax,word ptr m1 ; mantisa pe 4 octeti mov dx,word ptr m1+2 mov bx,c1 ; caract. pe 2 octeti CALL SNF4 ; subprogram normalizare mov word ptr m1,ax ; memorare nr. normalizat mov word ptr m1+2,dx ; peste mantisa initiala POPA ENDM 15

; --------------------------; Subprogram normalizare VF ; - intrare mantisa 4 oct in DX:AX si caract in BX ; - iesire nr in vf pe 4 oct in DX:AX ; --------------------------snf4 PROC near ; normalizare prin depl dreaapta mantisa si increm. CAR c11: cmp dh,0 ; test octet1 din mant =0 jz c2 ; octet1=0 depl. stinga inc bx ; car =car+1 si depl. dreapta DX:AX shr dx,1 ; DX -> CF -> AX rcr ax,1 jmp c11 ; normalizare prin depl. stinga mantisa si decrem. CAR c2: mov cl,80h ; verif. bit1 din octet2 mantisa and cl,dl ; selectie bit1 cmp cl,80h jz c3 ; terminare normalizare dec bx ; car=car-1 si depl. stinga mantisa shl ax,1 ; DX <- CF <- AX rcl dx,1 jmp c2 ; Concatenare CAR cu mantisa normalizata c3: and dl,7fh ; sterge bit 1 din mantisa (implicit=1) shl dx,1 or dh,bl ; concatenare CAR si mantisa shr dx,1 ret snf4 ENDP ; -----------------------------; program principal conversie intreg flotant ; -----------------------------st1: mov ax,@data mov ds,ax ; cif: nf4 cx1,x ; conversie intreg real ; end st1 16

---------------------------------------------------

17

12.8. Conversia numerelor din VF in intreg


Si in acest caz separam caracteristica (CAR) de mantisa (M). Mantisa va furniza cifrele semnificative ale numarului ( 6-7 la short real), iar caracteristica va da ordinul de marime. Algoritmul va fi invers decit la conversia intreg - flotant. 8c.b. 23c.b. MANTISA '- virgula mantisa vf ' -virgula pt.numar intreg CAR - caracteristica Valoarea numarului in VF este: NF = M*2**EXP Pentru a avea deplasari numai intr-un singur sens, deplasam initial mantisa la stinga cu 8 c.b. si completam 1 implicit pe primul bit. Vom considera numarul intreg rezultat dupa mutarea virgulei mantisei (care se gaseste acum dupa primul bit), spre dreapta cu nr. de pozitii indicate de exponent ( EXP = CAR-127 ). Exponentul specifica nr. de cifre binare intregi ale numarului, iar restul fiind biti ce dau zecimale, care se pierd in cazul numerelor intregi. Vom avea urmatoarele cazuri: a) EXP = 31 - virgula se va deplasa cu 31 c.b. spre dreapta, chiar peste virgula corespunzatoare numerelor intregi. Mantisa va reprezenta chiar numarul intreg. b) EXP < 0 - virgula va trebui mutata spre stinga si numarul va fi < 1, deci intregul rezultat va fi N = 0. c) EXP > 31 - virgula trebuie mutata cu mai mult de 31 pozitii spre dreapta, rezultind depasire (numar cu mai mult de 32 c.b.) d) 0 =< EXP < 31 - virgula se va deplasa spre dreapta cu mai putin de 31 c.b. si va trebui adusa pe ultima pozitie din dreapta, corespunzatoare numerelor intregi. Aceasta se realizeaza cu 31 - EXP deplasari spre dreapta. Vom exemplifica algoritmul pe numarul NF = 3.456 care in hexa este NF = 40 5D 2F 1B CAR = 40H => EXP = CAR - 7FH = 80H - 7FH = 1 M = 00 5D 2F 1B - mantisa Dupa deplasarea stinga cu 8 c.b. si completare 1 implicit: M = DD 2F 1B 00 Pentru transformarea in numar intreg sint necesare 31 - EXP = 31 - 1 = 30 deplasari spre dreapta si rezulta: N = 00 00 00 03 restul bitilor fractionari s-au pierdut

; ------------------------------------; PROGRAM DE CONVERSIE FLOTANT - INTREG ; ---------------------------------------

18

.286c .287 dosseg .model small .stack 100 .data mdep db 10,13,'Depasire!! Nr. in VF prea mare $' xf dd 51420. ; numar in VF x dd 0 ; numar convertit intreg xr dd 51420 ; numar intreg de referinta ; CFI Definitie macro pentru conversie pozitiv flotant - intreg MACRO N,NF ; numar intreg si flotant pusha ; salvare registre mov dx, word ptr nf+2 ; nr. flotant pe 4 oct. in DX:AX mov ax,word ptr nf CALL SCFI ; chemare subpr. conv. flotant -intreg mov word ptr n+2,dx ; memorare numar intreg mov word ptr n,ax ENDM ; ------------------------------------------; Subprogram conversie flotant - intreg ; - intrare DX:AX numar flotant ; - iesire DX:AX numar intreg convertit ; -------------------------------------------SCFI PROC NEAR mov bx,dx ; verificare NF=0 or bx,ax jnz c1 ; NF > 0 RET ; NF = 0 => N = NF c1: mov bx,dx ; bx = CAR shl bx,1 ; bh = CAR mov cx,8 ; 8 depl. stinga mantisa d8: shl ax,1 ; DX <- CF <- AX rcl dx,1 loop d8 or dh,80h ; fortare bit implicit 1 mantisa sub bh,127 ; EXP = CAR-127 cmp bh,31 ; comparare EXP cu 31 jnz c3 RET ; EXP = 31 => N=NF nu se fac deplasari c3: js c4 ; EXP < 31 mov dx,offset mdep ; EXP >31 - mesaj depasire mov ah,9 int 21h RET c4: cmp bh,0 ; comparare EXP cu 0 jns c5 ; 0 =< EXP < 31 xor ax,ax ; EXP<0 => N=0 mov dx,ax RET 19

c5:

mov cl,31 ; 0 =< EXP < 31 sub cl,bh ; CL = 31-EXP nr.deplasari dreapta mov ch,0 c6: shr dx,1 ; 31-EXP deplasari dreapta mantisa rcr ax,1 ; DX -> CF -> AX loop c6 RET SCFI ENDP ; ------------------------------------------; Program principal conversie flotant intreg ; ------------------------------------------ST1: mov ax,@data mov ds,ax ; conv: CFI x,xf ; conversie X -> XF ; int 3 ; terminare END ST1 ------------------------------------------------------------------

20