Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Procesoare de 32 de biti Coprocesoare matematice

calculatoare



+ Font mai mare | - Font mai mic



Procesoare de 32 de biti Coprocesoare matematice

1 Arhitectura procesoarelor de 32 de biti



1.1 Generalitati

Aparitia si dezvoltarea procesoarelor Intel de 32 de biti a constituit o adevarata revolutie in domeniul calculatoarelor personale, atat prin cresterea, performantelor hardware (in special cresterea spatiului de memorie adresabil direct), cat si prin perspectivele deschise sistemelor de programe.

Procesoarele de 32 de biti sunt compatibile ca arhitectura cu cele de 16 biti, prin aceea ca registrele de 16 biti se regasesc ca subregistre ale registrelor de 32 de biti. Aceasta a permis ca setul de instructiuni al procesoarelor de 16 biti sa fie un subset al celui specific procesoarelor de 32 biti, ceea ce face ca orice program dezvoltat pentru procesoarele de 16 biti sa poata fi executat si pe masini de 32 de biti. In plus, toate instructiunile care utilizau operanzi de 16 biti se extind si asupra operanzilor de 32 de biti. Aceasta compatibilitate a setului de instructiuni a fost unul din scopurile declarate ale noii generatii de procesoare, pentru a conserva imensa cantitate de software dezvoltata anterior.

Figura 1 descrie registrele procesoarelor de 32 de biti, din punctul de vedere al programelor de aplicatie.

Exista opt registre generale de 32 de biti, care au numele registrelor generale de 16 biti, cu prefixul E (de la extended). Astfel, registrul EAX se numeste acumulator extins, ESP se numeste stack pointer extins etc. Primii 16 biti mai putin semnificativi ai acestor registre sunt disponibili si ca registre de 16 biti (AX, SP etc.), fiind practic identice cu registrele generale 8086.

Aceeasi abordare se regaseste si in cazul registrelor EIP (contor program extins) si EFLAGS (registru de flaguri extins). Subsetul de bistabili din registrul FLAGS se regaseste in partea low a registrului EFLAGS.

Registrele de segment au fost pastrate de 16 biti, dar s-au adaugat doua noi registre: FS si GS.

Pe langa registrele generale din Figura 1, procesoarele de 32 de biti dispun de registre de control, de gestiune a adresei, de depanare si de test. Acestea difera de la un tip de procesor la altul si sunt folosite in principal de programele de sistem.

Figura 1 Registrele procesoarelor de 32 de biti

Una din modificarile majore ale arhitecturii este semnificatia registrelor de segment, care actioneaza in general ca selectoare de segment. Acestea nu mai indica in mod nemijlocit adresa de baza a segmentului de memorie, ci un descriptor de segment (incarcat intr-un registru special de control) care precizeaza adresa de baza a segmentului, dimensiunea acestuia si drepturile de acces asociate. Abordarea respectiva permite ca adresa de baza si limita segmentului sa poata fi specificate pe 32 de biti, crescand dimensiunea maxima a unui segment pana la 4 GB.

1.2 Moduri de adresare pe 32 de biti

Modurile de adresare (formarea adresei fizice) au fost mult dezvoltate fata de cele pe 16 biti. Se introduc urmatoarele notiuni:

. deplasament - o valoare imediata pe 8 sau 32 de biti, continuta in instructiune;

. registru de baza - orice registru general de 32 de biti (spre deosebire de adresarea pe 16 biti unde ca registre de baza se utilizeaza doar BX si BP);

. registru index - orice registru general de 32 de biti, cu exceptia lui ESP (spre deosebire de adresarea pe 16 biti unde ca registre index se utilizeaza doar SI si DI);

. factor de scala - indexul poate fi inmultit cu un factor de scala de valoare 1, 2, 4 sau 8 (inexistent in adresarea pe 16 biti).

Se obtin astfel 9 moduri posibile de adresare:

. adresare directa - adresa efectiva a operandului face parte din instructiune, putand fi pe 8,16 sau 32 de biti; exemplu:

INC dword ptr [1000H]

. adresare indirecta prin registre - adresa efectiva a operandului este continuta intr-unul din registrele de baza; exemplu:

MOV [EBX] , EAX

. adresare bazata - adresa efectiva a operandului este formata din continutul unui registru de baza la care se poate adauga un deplasament; exemplu:

ADD ECX, [EAX+32]

. adresare indexata - adresa efectiva a operandului este formata din continutul unui registru index la care se poate adauga un deplasament; exemplu:

MUL byte ptr TABLOU [ESI]

. adresare indexata cu factor de scala - adresa efectiva a operandului este formata din continutul unui registru index, inmultit cu un factor de scala, la care se poate adauga un deplasament; exemplu:

MOV EAX, dword ptr TABLOU [EDI*4][100H]

. adresare bazata si indexata - adresa efectiva a operandului este formata din continutul unui registru de baza la care se aduna continutul unui registru index; exemplu:

MOV EAX, [ESI][EBX]

. adresare bazata si indexata cu factor de scala - adresa efectiva a operandului este formata din continutul unui registru de baza la care se adauga continutul unui registru index, inmultit cu un factor de scala; exemplu:

MOV ECX, [EDX*8][EAX]

. adresare bazata si indexata cu deplasament - adresa efectiva 3 operandului este formata din continutul unui registru de baza la care se adauga continutul unui registru index, la care se poate adauga un deplasament; exemplu:

ADD EDX, [ESI] [EBP + 10000H]

. adresare bazata si indexata, cu factor de scala si deplasament - adresa efectiva a operandului este formata din continutul unui registru de baza la care se adauga continutul unui registru index, inmultit cu un factor de scala, la care se poate adauga un deplasament; exemplu:

MOV EAX, TABLOU [EDI*4] [EBP+800H]

Figura 2 ilustreaza modul cel mai general de adresare (bazata si indexata, cu factor de scala si deplasament), in care adresa efectiva AE se calculeaza dupa relatia:

AE = Registru_Baza + Registru_Index * Factor_Scala + Deplasament

Factorul de scala este foarte util la parcurgerea tablourilor de date simple (pe 2, 4 sau 8 octeti), permitand ca indicele logic al tabloului sa coincida cu continutul registrului index. De exemplu, o instructiune C de forma:

long int tablou [1000];

for (i = 0; i < 1000; i++)

tablou[i] += 10;

se implementeaza prin secventa:

MOV CX,

XOR EBX, EBX

bucla:

ADD _TABLOU [EBX*4], 10

INC EBX

LOOP bucla

in care registrul EBX are exact aceeasi semnificatie ca si indicele i din programul C.

1.3 Modurile Real si Protected

Pentru a pastra compatibilitatea cu programele dezvoltate pentru masini de 16 biti, procesoarele de 32 de biti dispun de doua moduri de operare: modul Real Address (pe scurt, modul Real) si modul Protected Virtual Address (pe scurt, modul Protected).

In modul Real, procesorul se comporta ca un procesor de 16 biti foarte rapid, permitand insa accesul la date si adrese de 32 de biti.

Modul Protected ofera mecanisme sofisticate de gestiune a memoriei (paginare, drepturi de acces la segmente etc.). In acest mod de operare, unitatile de program se numesc taskuri. Se poate executa o comutare de task, pentru a intra intr-un regim special de functionare, denumit mod Virtual 8086. Fiecare asemenea task se comporta (din punct de vedere software) ca o masina de tip 8086, permitand programelor de 16 biti (aplicatii sau chiar un intreg sistem de operare) sa poata fi executate ca taskuri.

Figura 2 Moduri de adresare pe 32 de biti

Atat in modul Real, cat si in modul Protected, procesorul poate executa instructiuni de 16 biti, prin examinarea unui bit din descriptorul de segment asociat registrului CS. Acest bit precizeaza lungimea implicita a operanzilor si a adreselor (16 sau 32 de biti).

In afara dimensiunii implicite, se poate forta o anumita dimensiune prin prefixele numite Operand Size (Dimensiune operand) si Addess Length (Lungime adresa). Aceste prefixe (de valoare 66H si 67H) sunt generate automat de catre macroasambloare. Sa presupunem modul Real si sa (consideram urmatoarea secventa de cod sursa:

. code

MOV AX, word ptr [DI][100H]

MOV EAX, dword ptr [DI][100H]

MOV AX, word ptr [EDI][100H]

MOV EAX, dword ptr [EDI][100H]

Fisierul listing generat va contine urmatoarea descriere:

0000 8B 85 0100 MOV AX, word ptr [DI][100H]

0004 66| 8B 85 0100 MOV EAX, dword ptr [DI][100H]

0009 67| 8B 87 00000100 MOV AX, word ptr [EDI][100H]

0010 66| 67| 8B 87 00000100 MOV EAX, dword ptr [EDI][100H]

Se observa acelasi cod al instructiunii MOV (8BH), acelasi deplasament 100H generat pe 16 sau 32 de biti si prefixele inserate automat. Prima instructiune este cu operand si adresare de 16 biti. A doua instructiune este cu operand pe 32 de biti si adresare pe 16 biti; se observa prefixul 66H si offset-ul 100H generat pe 16 biti. A treia instructiune este cu operand pe 16 biti si adresare pe 32 de biti; se observa prefixul 67H si offset-ul 100H generat pe 32 de biti. In fine, ultima instructiune este cu operand si adresare pe 32 de biti; se observa ambele prefixe si offset-ul 100H generat pe 32 de biti.

In modul de operare Real, formarea adresei fizice este exact ca la procesoarele de 16 biti (vezi Figura 3). Selectorul de segment este unul din cele 4 registre de segment, iar offset-urile sunt pe 16 biti, conducand astfel la o lungime maxima a unui segment de 64KB. Pointerii catre date sau catre instructiuni pot fi memorati pe 4 octeti (doi octeti pentru adresa de segment si doi octeti pentru offset).

Asambloarele dispun de directiva DD (Define DoubleWord), care genereaza pointeri pe 4 octeti, ca in exemplul urmator:

.data

TABLOU DD 256 dup (?)

ADR_16 DD TABLOU

.code

LES BX, ADR_16

MOV EAX, ES:[BX]

Instructiunea LES BX, ADDR_16 incarca perechea de registre (ES:BX) cu un pointer pe 4 octeti.

In modul de operare Protected, registrele selectoare de segment (de 16 biti) sunt incarcate cu adresa unui descriptor de segment, iar offset-urile pot fi de 16 sau 32 de biti (vezi Figura 4), conducand la o lungime maxima a unui segment de 4 GB. Pointerii pot fi pe 4 octeti (doi octeti pentru descriptorul de segment si doi octeti pentru offset) sau pe 6 octeti (patru octeti pentru offset).

Asambloarele dispun de directiva DP (Define Pointer), care genereaza pointeri pe 6 octeti, ca in exemplul urmator:

Figura 3 Adresarea in modul Real

.data

TABLOU DD 256 dup (?)

ADR_32 DP TABLOU

.code

LFS EBX, ADR_32

MOV EAX, FS:[EBX]

Instructiunea LFS EBX, ADDR_32 incarca perechea de registre (FS:EBX) cu un pointer pe 6 octeti.

Sa consideram urmatoarea secventa sursa:

.data

TABLOU DD 256 dup (?)

ADR_16 DD TABLOU

ADR_32 DP TABLOU

.code

LEA BX, TABLOU ; Acces prin point near

; de 16 biti in

MOV EAX, [BX] ; cadrul segmentului selectat

; prin DS

LEA EBX, TABLOU ; Acces prin point near

; de 32 de biti in

MOV EAX, [EBX] ; cadrul segmentul selectat prin DS

LES AX, ADR_16 ; Acces prin point far

; de 32 de biti in

MOV EAX, ES:[BX] ; cadrul segmentul selectat

; prin ES 

LFS EBX, ADR_32 ; Acces prin pointer far

; de 48 de biti in

MOV EAX, FS:[EBX] ; cadrul segmentului selectat

; prin FS

Figura 4 Adresarea in modul Protected

Listingul generat la asamblare pentru secventa de mai sus este:

.data

TABLOU DD 256 dup (?)

0400 00000000sr ADR_16 DD TABLOU

0404 000000000000sr ADR_32 DP TABLOU

040A .code

0000 BB 0000r  LEA BX, TABLOU

0003 66| 8B 07  MOV EAX, [BX]

0006 66| 8D 1E 0000r LEA EBX, TABLOU

000B 66| 67| 8B 03 MOV EAX, [EBX]

000F C4 1E 0400r  LBS BX, ADR_16

0013 66| 26: 8B 07  MOV EAX, ES:[BX]

0017 66| OF B4 1E 0404r LFS EBX, ADR_32

001D 66| 64: 67| 8B 03 MOV EAX, FS:[EBX]

Se observa prezenta a trei categorii de prefixe. Prefixele de operand pe 32 de biti (marcate cu 66|), cele de adresa pe 32 de biti (marcate cu 67|) si prefixele de segment (marcate cu 26: pentru ES: si cu 64: pentru FS:). Instructiunea LEA (Load Effective Address) permite incarcarea atat offset-urilor de 16 biti, cat si a celor de 32 de biti.

In mod implicit, accesul la date se face prin selectorul DS (la fel ca la 8086), cu exceptia modurilor de adresare care implica registrele EBP si ESP, caz in care selectorul implicit este SS. Se poate folosi orice prefix de segment, cu aceleasi exceptii cunoscute de la 8086:

. instructiunile executate sunt accesate totdeauna prin CS;

. operatiile de salvare si restaurare in stiva implicate in instructiunile CALL, RET, PUSH si POP se executa totdeauna prin selectorul SS;

. destinatia instructiunilor pentru siruri este accesata totdeauna prin selectorul ES.

La punerea sub tensiune, procesorul este in modul Real. Trecerea in modul Protected se face prin pozitionarea unui bit din cuvantul mai putin semnificativ (numit Machine Status Word) al registrului de control CR0.

Asa cum la procesoarele de 16 biti trebuia sa incarcam registrele de segment cu valori cu sens, trecerea in modul Protected presupune definirea corespunzatoare a descriptorilor de segment si incarcarea registrelor selectoare. Aceste operatii nu vor fi descrise, in ideea ca programele de aplicatie dezvoltate in limbaj de asamblare vor opera in general in modul Real.

2 Setul de instructiuni al procesoarelor de 32 de biti

2.1 Extensia instructiunilor de 16 biti

Pentru ca asamblorul sa recunoasca instructiunile specifice, se utilizeaza directivele .286, .386, .486, care precizeaza tipul procesorului.

O serie de restrictii de la setul de baza 8086 sunt eliminate, incepand de la procesorul 80286. De asemenea, se adauga o serie de instructiuni noi.

Incarcarea registrelor de segment se poate face cu valori imediate; exemplu MOV DS, DGROUP.

Instructiunile de deplasare si rotatie se pot executa pe un numar oarecare de biti, specificat in instructiune; de exemplu: SHL AX, 4.

Instructiunea de inmultire cu semn (IMUL) are urmatoarele forme suplimentare:

IMUL reg16, im16

prin care se inmulteste registrul de 16 biti reg16 cu o valoare imediata pe 16 biti im16, iar rezultatul se depune in reg16;

IMULdreg16, sursa16

prin care se inmulteste dreg16 cu sursa16 (registru sau memorie) si rezultatul se depune in dreg16 (numai la 80386 si urmatoarele).

IMULdrea16, sursa16, im16

prin care se inmulteste sursa16 (registru sau memorie) cu valoarea imediata ini16 si rezultatul se depune in registrul dreg16 (destinatie).

Instructiunile de lucru cu stiva se extind cu:

PUSHA (Push AII)

care salveaza in stiva registrele AX, CX, DX, BX, SP, BP, SI, Dl (in aceasta ordine), iar registrul SP este scazut cu 16;

POPA (Pop All)

care reface registrele Dl, SI, BP, SP, BX, DX, CX, AX (salvate cu o instructiune PUSHA anterioara); registrul SP se reface prin adunarea valorii 16, nu prin extragerea efectiva din stiva;

PUSH im16

care pune in stiva o valoare imediata. Instructiunile pentru siruri se extind cu:

INSB, INSW (Input String) cu semnificatia:

(ES:(DI)) <- byte / word citit de la portul specificat de DX;

actualizeaza DI;

OUTSB, OUTSW (Output String)

cu semnificatia:

port specificat prin DX <- (DS:(SI));

actualizeaza SI;

Instructiunile de control se extind cu:

BOUND reg16, lim (Testeaza limite)

in care lim este adresa unei zone de memorie de doi intregi, care precizeaza limita minima si maxima pentru registrul reg16. Daca reg16 < DS:(lim) sau reg16 > DS:(lim+2), atunci se genereaza o intrerupere software pe nivelul 5.

ENTER dim_loc, nivel (Creeaza sablon stiva la intrarea in procedura) in care dim_loc si nivel sunt intregi pe 16 biti fara semn.

Semnificatia este urmatoarea:

PUSH BP

temp <- SP

daca (nivel > 0)

PUSH temp

BP <- temp

SP <- SP - dim_loc

Primul parametru dim_loc este dimensiunea necesara in stiva pentru parametrii locali ai procedurii. Daca nivel este 0, atunci semnifica este echivalenta cu:

PUSH BP

MOV  BP, SP

SUB  SP, dim_loc

care este secventa standard de intrare intr-o procedura cu parametri locali in stiva (vezi 6.6).

Daca nivel este > 0, se copiaza in stiva continutul zonei de stiva (parametri locali) a procedurii apelante. Daca procedura curenta este apelata dintr-o alta procedura, care are registrul BP pozitionat printr-o instructiune ENTER, atunci sablonul stivei curente va contine primii nivel - 1 parametri locali ai procedurii apelante.

LEAVE (Pregatire pentru iesire din procedura)

Instructiunea LEAVE reface registrele SP si BP, anuland efectul instructiunii LEAVE. Este echivalenta cu secventa:

MOV SP, BP

POP BP

Instructiunea ENTER se scrie ca prima instructiune din procedura, iar LEAVE imediat inainte de RET.

2.2 Instructiuni specifice procesoarelor de 32 de biti

Intregul set de instructiuni de transfer, aritmetice si logice se extinde cu operanzi de tip DoubleWord (registre, memorie sau valori imediate).

Instructiuni specifice de transfer

PUSHAD / POPAD  (Push / Pop All Double)

Salveaza / restaureaza registrele EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI in stiva.

PUSHFD / POPFD (Push Flags Double)

Salveaza / restaureaza registrul EFLAGS in stiva.

CMPXCHG reg / mem, reg (Compare and Exchange)

Compara si apoi interschimba cei doi operanzi, pozitionand flagurile aritmetice.

BSWAP reg32 (Byte Swap)

Inverseaza ordinea octetilor intr-un registru de 32 de bti:

XADD reg / mem, reg  (Exchange and Add)

Este echivalenta cu secventa:

XCHG  reg/mem, reg

ADD reg/mem, reg

Instructiuni specifice de conversie

MOVZX / MOVSX destinatie, sursa (Move with Zero / Sign Extension)

Copiaza operandul sursa (de 8 sau 16 biti) in operandul destinatie (de lungime dubla), completand cu 0 (MOVZX) sau cu bitul de semn al operandului sursa (MOVSX). Destinatia poate fi registru sau memorie de

16 / 32 de biti, iar sursa poate fi registru, memorie sau valoare imediata de 8 / 16 biti.

CWDE (Convert Word to DoubleWord Extended)

Converteste AX la un dublu cuvant in EAX, cu extensie de semn. Este asemanatoare cu CWD (Convert Word to Double), care are ca destinatie perechea (DX:AX).

CDQ (Convert DoubleWord to QuadWord)

Converteste registrul EAX la un cuvant cvadruplu in perechea (EDX:EAX), cu extensie de semn.

Instructiuni specifice adreselor

LFS / LGS / LSS registru, memorie

Incarca o pereche de registre cu un pointer din memorie, pe 4 sau 6 octeti. Registrul specificat poate fi de 16 sau de 32 de biti.

Instructiuni aritmetice

Operatiile de inmultire si de impartire se pot executa pe 32 de biti. Se utilizeaza registrele EAX si EDX, cu semnificatie asemanatoare ca la operatiile de 16 biti. De exemplu, instructiunea:

DIV EBX

imparte (EDX:EAX) la EBX, cu catul in EAX si restul in EDX.

Instructiuni de deplasare

SHLD / SHRD reg / mem, reg, CL / im8 (Shift Left / Right Double)

Se deplaseaza reg / mem la stanga / dreapta cu numarul de biti specificat in CL sau in operandul imediat im8 (pe 8 biti). Al doilea operand este folosit pentru a completa bitii deplasat ai primului operand. Primii doi operanzi trebuie sa fie de aceeasi dimensiune (Word sau DoubleWord).

Instructiuni pentru siruri

Setul de instructiuni pentru siruri se extinde cu operatii specifice sirurilor de intregi pe 4 octeti. Exista astfel instructiunile MOVSD (Move String Double), STOSD (Store String Double), LODSD (Load String Double), SCASD (Scan String Double). Se utilizeaza registrul acumulator extins EAX, iar adresele sursa si destinatie (SI si Dl) sunt incrementate / decrementate cu 4.

Instructiuni la nivel de bit

BSF / BSR reg, reg / mem (Bit Scan Forward / Reverse)

Instructiunea parcurge operandul sursa reg / mem (16 < 32 de biti), pana la primul bit egal cu 1. BSF parcurge de la dreapta la stanga, iar BSR invers. Indicele bitului 1 identificat este plasat in primul operand registru).

BT reg / mem, im8 / reg (Bit Test)

Plaseaza bitul cu numarul dat de im8 sau de reg al operaului reg / mem in CF.

BTC reg / mem, im8 / reg (Bit Test and Complement)

Plaseaza bitul cu numarul dat de im8 sau de reg al operandului reg / mem in CF, apoi complementeaza bitul respectiv.

BTR reg / mem, im8 / reg (Bit Test and Reset)

Plaseaza bitul cu numarul dat de im8 sau de reg al operandului reg / mem in CF, apoi forteaza bitul respectiv la valoarea 0.

BTS reg / mem, im8 / reg  (Bit Test and Set)

Plaseaza bitul cu numarul dat de im8 sau de reg al operandului reg / mem in CF, apoi forteaza bitul respectiv la valoarea 1.

Instructiuni de control

JECXZ eticheta (Jump if ECX is Zero)

Este extensia instructiunii JCXZ pentru registrul ECX.

SETccc reg / mem (Set Bytes Conditiorv)

Seteaza un octet conform unei conditii logice. Octetul poate fi un registru de 8 biti sau o locatie de memorie. Conditiile logice si semnificatiile lor sunt aceleasi ca la instructiunile de salt conditionat. In mnemonicele instructiunilor se substituie ccc cu conditia care este codificata sub forma Jccc la instructiunile de salt conditionat. Exista deci instructiuni SETG, SETGE SETNB, SETPO, SETNLE etc. De exemplu:

SETLE AL

SETNBE byte ptr [SI]

SETNC byte ptr [EBX]

3 Coprocesoare matematice

1 Arhitectura coprocesoarelor matematice

Coprocesoarele matematice sunt circuite integrate dedicate (procesoare specializate), care extind setul de instructiuni al procesoarelor centrale cu instructiuni specifice operatiilor cu numere reale in virgula mobila.

Coprocesoarele sunt fie circuite de sine statatoare (8087, 80287, 80387), fie sunt integrate in procesorul de baza (80486). In cel de-al doilea caz, nu se mai face distinctie intre setul de instructiuni al procesorului de baza si cel specific formatului in virgula mobila.

Tipurile de date recunoscute de coprocesoare sunt:

. numar real in simpla precizie (dword);

. numar real in dubla precizie (qword);

. numar real in precizie extinsa (tbytes);

. intreg pe 2 octeti (word);

. intreg pe 4 octeti (dword);

. intreg pe 8 biti (qword);

. intreg BCD pe 10 cifre (tbytes).

Aceste tipuri de date vor fi notate cu real32, real64, real80, int16, int32 si bcd80. Intregii pe 8 octeti pot fi numai incarcati in coprocesor. Intern, coprocesoarele lucreaza exclusiv cu formatul real in precizie extinsa (10 octeti), descris in Capitolul 1. La incarcarea operanzilor din memorie, toate tipurile de date de mai sus sunt convertite la tipul intern; similar, la depunerea operanzilor in memorie, au loc conversii de la formatul intern la unul din formatele de mai sus.

Arhitectura coprocesoarelor cuprinde 8 registre de cate 80 de biti, numite ST(0), ST(1), , ST(7). Aceste registre sunt organizate ca o stiva, registrul ST(0) (care se mai noteaza simplu cu ST) fiind varful stivei (vezi Figura 5). Coprocesoarele dispun de o serie ce registre suplimentare, dintre care cele mai importante sunt registrul de stare (Status Word) si registrul de control (Control Word). Registrul de stare contine flaguri care se pozitioneaza in urma instructiunilor de comparatie sau in caz de eroare. Registrul de control contine campuri care controleaza modul de executie al anumitor actiuni (de exemplu, cum se face rotunjirea la valori intregi).

Comunicatia dintre procesorul de baza si coprocesor se face exclusiv prin intermediul memoriei. Coprocesorul dispune de instructiuni de transfer intre memorie si cele 8 registre de lucru, precum si pentru cuvintele de control si de stare.

Figura 5 Arhitectura coprocesoarelor 80x87

Ne vom referi in continuare la coprocesorul 8087, deoarece setul de instructiuni este practic acelasi la toate coprocesoarele. La procesoarele mai vechi decat 80486, se pune si problema comunicatiei dintre procesorul de baza si coprocesor.

Instructiunile specifice 8087 se scriu in textul sura a fel ca instructiunile procesorului de baza. Asamblorul recunoaste mnemonicele acestor instructiuni si genereaza cod masina corespunzator. Acest cod va fi executat de catre coprocesor, in urma generarii unui semnal de catre procesorul de baza 8086.

Coprocesorul 8087 monitorizeaza permanent fluxul de instructiuni si sesizeaza prezenta unei instructiuni specifice 8087 in memorie. In acest caz, el semnaleaza intentia de a intra in executie prin semnalul electric TEST. Executia incepe numai dupa ce 8086 intra in asteptare, ca urmare a unei instructiuni WAIT. Coprocesorul recunoaste starea de asteptare si incepe executia instructiunii matematice, anuland in acelasi timp cererea efectuata prin semnalul TEST. Ca urmare, 8086 iese din starea de asteptare si isi continua executia. Asambloarele insereaza automat o instructiune WAIT inaintea fiecarei instructiuni 8087, deci nu este necesara codificarea lor explicita.

La coprocesoarele de generatie mai noua (80387), sincronizarea cu procesorul de baza se face prin semnale specializate, ceea ce elimina necesitatea instructiunilor WAIT.

In mod corespunzator, exista instructiunea 8087 FWAIT, destinata sincronizarii reciproce (8087 "asteapta' dupa 8086). Instructiunea FWAIT este necesara numai dupa operatiile de depunere in memorie executate de 8087.

Inaintea inceperii operarii propriu-zise, este necesara o instructiune FINIT, care sterge registrele interne, conditiile de eroare etc.

2 Setul de instructiuni 8087

Mnemonicele instructiunilor 8087 incep toate cu litera F. Majoritatea instructiunilor au ca operanzi varful ST al stivei coprocesorului si un alt registru ST(i) sau un operand in memorie. Cele mai multe instructiuni matematice actualizeaza stiva, prin operatiile descrise mai jos (ST si ST(0) reprezinta acelasi registru):

PUSH_ST:

for (i = 7 downto 1)

ST(i) <- ST(i-l)

POP_ST:

for (i = 1 to 7)

ST(i-l) <- ST(i)

Instructiuni pentru incarcarea datelor

FLD ST(i) (Incarca ST(i) in ST, cu deplasarea stivei)

temp <- ST(i)

PUSH_ST

ST <- temp

FLD mem (real32/64/80) (Incarca numar real din memorie in ST)

PUSH_ST

ST <- mem

FILD  mem (int16/32/64) (Incarca numar intreg din memorie in ST)

PUSH_ST

ST <- mem

FBLD mem (bcd80) (Incarca numar BCD din memorie in ST)

PUSH_ST

ST <- mem

FLDZ  (Incarca constanta 0.0 in ST)

PUSH_ST

ST <- 0.0

FLD1  (Incarca constanta 1.0 in ST)

PUSH_ST

ST <- 1.0

FLDPI  (Incarca constanta p in ST)

PUSH_ST

ST <- p

FLDL2E  (Incarca constanta log2 (e) in ST)

PUSH_ST

ST <- Iog2 (e)

FLDL2T  (Incarca constanta log2 (10) in ST)

PUSH_ST

ST <- log2 (10)

FLDLG2  (Incarca constanta log10 (2) in ST)

PUSH_ST

ST <- log10 (2)

Instructiuni pentru depunerea datelor

FST ST(i) (Depune ST in ST(i) fara descarcarea stivei)

ST(i) <- ST

FSTP ST(i)  (Depune ST in ST(i) cu descarcarea stivei)

ST(i) <- ST

POP_ST

FST mem (real32/64/80) (Depune ST real in memorie fara descarcare)

mem <- ST

FSTP mem (real32/64/80) (Depune ST real in memorie cu descarcare)

mem <- ST

POP_ST

FIST mem (int16/32) (Depune ST intreg in memorie fara descarcare)

mem <- ST

FISTP mem (int16/32) (Depune ST intreg in memorie cu descarcare)

mem <- ST

POP_ST

FBSTP mem (bcd80) (Depune ST BCD in memorie cu descarcare)

mem <- ST

POP_ST

FXCH  (Schimba ST cu ST(1))

FXCH ST(i)  (Schimba ST cu ST(i))

Instructiuni de adunare

FADD  (Aduna ST cu ST(1), cu descarcare)

ST(1) <- ST(1) + ST

POP_ST

FADD ST(i), ST  (Aduna ST la ST(i))

ST(i) <- ST(i) + ST

FADD ST, ST(i)  (Aduna ST(i) la ST)

ST <- ST + ST(i)

FADD mem (real32/64/80) (Aduna real din memorie la ST)

ST <- ST + mem

FIADD mem (int16/32) (Aduna intreg din memorie la ST)

ST <- ST + mem

FADDP ST(i)  (Aduna ST la ST(i) cu descarcarea stivei)

ST(i) <- ST(i) + ST

POP_ST

Instructiuni de scadere

FSUB  (Calculeaza ST(1) - ST cu descarcare)

ST(1) <- ST(1) - ST

POP_ST

FSUB ST(i), ST  (Scade ST din ST(i))

ST(i) <- ST(i) - ST

FSUB ST, ST(i) (Scade ST(i) din ST)

ST <- ST - ST(i)

FSUB mem (real32/64/80) (Scade real in memorie din ST)

ST <- ST - mem

FISUB mem (int16/32) (Scade intreg in memorie din ST)

ST <- ST - mem

FSUBP ST(i)  (Scade ST din ST(i) cu descarcare)

ST(i) <- ST(i) - ST

POP_ST

FSUBR  (Calculeaza ST - ST(1) cu descarcare)

Temp <- ST - ST(1)

POP_ST

ST <- temp

FSUBR ST(i), ST (Scade ST(i) din ST, rezultat in ST(i))

ST(i) <- ST - ST(i)

FSUBR ST, ST(i) (Scade ST din ST(i), rezultat in ST)

ST <- ST(i) - ST

FSUBR mem (real32/64/80) (Scade ST din real in memorie, rezultat in ST)

ST <- mem - ST

FISUBR mem (int16/32) (Scade ST din intreg in memorie, rezultat in ST)

ST <- mem - ST

FSUBPR ST(i) (Scade ST(i) din ST cu descarcare)

ST(i) <- ST - ST(i)

POP_ST

Instructiuni de inmultire

FMUL  (Inmulteste ST cu ST(1), cu descarcare)

ST(1) <- ST(1)*ST

POP_ST

FMUL ST(i), ST  (Inmulteste ST cu ST(i), rezultat in ST(i))

ST(i) <- ST(i) * ST

FMUL ST, ST(i) (Inmulteste ST(i) cu ST, rezultat in ST(i))

ST <- ST * ST(i)

FMUL mem (real32/64/80) (Inmulteste real din memorie cu ST)

ST <- ST * mem

FIMUL mem (int16/32) (Inmulteste intreg din memorie cu ST)

ST <- ST * mem

FMULP ST(i)  (Inmulteste ST cu ST(i), cu descarcare)

ST(i) <- ST(i) * ST

POP_ST

Instructiuni de impartire

FDIV  (Calculeaza ST(1) / ST cu descarcare)

ST(1) <- ST(1) / ST

POP_ST

FDIV ST(i),ST  (Imparte ST(i) la ST, rezultat in ST)

ST(i) <- ST(i) / ST

FDIV ST, ST(i) (Imparte ST la ST(i) rezultat in ST(i))

FDIV mem (real32/64/80) (Imparte ST la real din memorie)

ST <- ST / mem

FIDIV mem (int16/32) (Imparte ST la intreg din memorie)

ST <- ST / mem

FDIVP ST(i)  (Imparte ST(i) la ST, cu descarcare)

ST(i) <- ST(i) / ST

POP_ST

FDIVR  (Calculeaza ST / ST(1), cu descarcare)

temp <- ST / ST(1)

POP_ST

ST <- temp

FDIVR ST(i), ST (Imparte ST la ST(i), rezultat in ST(i))

ST(i) <- ST / ST(i)

FDIVR ST, ST(i) (Imparte ST(i) la ST, rezultat in ST)

ST <- ST(i) / ST

FDIVR mem (real32/64/80) (Imparte real in memorie la ST, rezultat in ST)

ST <- mem / ST

FIDIVR mem (int16/32) (Imparte intreg in memorie la ST, rezultat in ST)

ST <- mem / ST

FDIVPR ST(i)  (Imparte ST la ST(i), cu descarcare)

ST(i) <- ST / ST(i)

POP_ST

Instructiuni de comparatie

Instructiunile de comparatie pozitioneaza indicatorii din cuvantul de stare prin efectuarea unei operatii temporare de scadere intre operanzii care se compara.

FCOM  (Compara ST cu ST(1))

FCOM ST(i) (Compara ST cu ST(i))

FCOM mem (real32/64/80) (Compara ST cu real din memorie)

FICOM mem (int16/32) (Compara ST cu intreg din memorie)

FTST  (Compara ST cu 0.0)

FCOMP  (Compara ST cu ST(1), cu descarcare)

temp <- ST - ST(1)

POP_ST

FCOMP ST(i) (Compara ST cu ST(i), cu descarcare)

FCOMP mem (real32/64/80) (Compara ST cu real, cu descarcare)

FICOMP mem (int16/32) (Compara ST cu intreg, cu descarcare)

FCOMPP  (Compara ST cu ST(1), cu descarcare dubla)

temp <- ST - ST(1)

POP_ST

POP_ST

Instructiuni diverse

FABS  (La valoarea absoluta)

ST <- | ST |

FCHS  (Schimba semnul)

ST <- - ST

FSQRT  (Radical)

ST <- sqrt (ST)

Instructiuni de control

FINIT  (Initializeaza coprocesor)

FWAIT  (Sincronizeaza cu procesorul de baza)

FSTSW mem (int16) (Depune cuvant de stare in memorie)

FSTCW mem(int16) (Depune cuvant de control in memorie)

FLDCW mem (int16) (Incarca cuvant de control din memorie)

FNOP  (Nici o operatie)

Pe langa instructiunile de mai sus, coprocesoarele dispun de instructiuni transcendente, pentru calculul functiilor trigonometrice directe si inverse, exponentiala, logaritm etc. Aceste instructiuni nu vor fi prezentate, deoarece este putin probabil ca se vor dezvolta programe cu functii transcendente in limbaj de asamblare. 



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 2093
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved