cap2.pdf

26
ARHITECTURA SISTEMELOR DE CALCUL 11 2. PROIECTAREA SETULUI DE INSTRUCłIUNI În acest capitol vom proiecta un set de instrucŃiuni reprezentativ pentru multe sisteme cu set redus de instrucŃiuni (RISC - Reduced Instruction Set Computer). Vom stabili mnemonicele şi formatele care vor fi utilizate în capitolele următoare. 2.1. Caracteristicile procesorului Indiferent de tip, toate procesoarele execută două operaŃii de bază: extrag instrucŃiuni din memorie, şi execută instrucŃiunile extrase. Prima problemă de proiectare constă în stabilirea setului de instrucŃiuni şi a formatelor de instrucŃiuni pe care procesorul le va recunoaşte. În ultima perioadă arhitecturile RISC au devenit foarte populare. În contrast cu procesoarele CISC (Complex Instruction Set Computer), procesoarele RISC recunosc un set redus de instrucŃiuni simple, cu formate şi moduri de adresare simple. În consecinŃă, hard-ul procesorului se reduce cantitativ iar proiectarea sa devine mult mai “curată“ şi atractivă. Majoritatea procesoarelor RISC prezintă seturi şi formate de instrucŃiuni cu un grad ridicat de similaritate. Nu există o definiŃie foarte precisă a procesorului RISC, a instrucŃiunii reduse sau a instrucŃiunii complexe. În general o instrucŃiune complexă este aceea care necesită mulŃi paşi pentru execuŃie, în timp ce o instrucŃiune redusă poate fi executată în foarte puŃini paşi. Procesoarele RISC prezintă un număr important de trăsături comune rezultate din principiul unanim acceptat de către toŃi proiectanŃii de structuri RISC: cel mai simplu este şi cel mai rapid. 2.1.1. Utilizarea memoriei şi a registrelor O trăsătură importantă şi comună tuturor procesoarelor RISC, care vizează setul de instrucŃiuni, este decizia de utilizare a memoriei numai pentru memorarea datelor, şi de a utiliza registrele CPU (Central Processing Unit) pentru toate operaŃiile aritmetico-logice. În contrast cu arhitecturile CISC, în cazul RISC nu este posibilă execuŃia operaŃiilor (instrucŃiunilor) aritmetice asupra unor operanzi locaŃi în memorie. Obiectivul esenŃial în cazul RISC este acela de a proiecta pentru viteză maximă, evitând utilizarea memoriei ori de câte ori este posibil, deoarece accesele la memorie sunt mult mai lente comparativ cu accesele la registre CPU. Pentru flexibilitate maximă, în cazul instrucŃiunilor aritmetice, se utilizează formatul cu trei adrese (de registru). De regulă în procesor se implementează un set de 32 registre. Numărul reprezintă un compromis între două cerinŃe: - un număr cât mai mare de registre reprezintă optimul pentru compilator - comutarea contextului devine tot mai lentă cu creşterea numărului de registre.

Upload: muntean-remus

Post on 25-Dec-2015

217 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

11

2. PROIECTAREA SETULUI DE INSTRUCłIUNI În acest capitol vom proiecta un set de instrucŃiuni reprezentativ pentru multe sisteme cu set redus de instrucŃiuni (RISC - Reduced Instruction Set Computer). Vom stabili mnemonicele şi formatele care vor fi utilizate în capitolele următoare. 2.1. Caracteristicile procesorului Indiferent de tip, toate procesoarele execută două operaŃii de bază: extrag instrucŃiuni din memorie, şi execută instrucŃiunile extrase. Prima problemă de proiectare constă în stabilirea setului de instrucŃiuni şi a formatelor de instrucŃiuni pe care procesorul le va recunoaşte. În ultima perioadă arhitecturile RISC au devenit foarte populare. În contrast cu procesoarele CISC (Complex Instruction Set Computer), procesoarele RISC recunosc un set redus de instrucŃiuni simple, cu formate şi moduri de adresare simple. În consecinŃă, hard-ul procesorului se reduce cantitativ iar proiectarea sa devine mult mai “curată“ şi atractivă. Majoritatea procesoarelor RISC prezintă seturi şi formate de instrucŃiuni cu un grad ridicat de similaritate. Nu există o definiŃie foarte precisă a procesorului RISC, a instrucŃiunii reduse sau a instrucŃiunii complexe. În general o instrucŃiune complexă este aceea care necesită mulŃi paşi pentru execuŃie, în timp ce o instrucŃiune redusă poate fi executată în foarte puŃini paşi. Procesoarele RISC prezintă un număr important de trăsături comune rezultate din principiul unanim acceptat de către toŃi proiectanŃii de structuri RISC: cel mai simplu este şi cel mai rapid. 2.1.1. Utilizarea memoriei şi a registrelor O trăsătură importantă şi comună tuturor procesoarelor RISC, care vizează setul de instrucŃiuni, este decizia de utilizare a memoriei numai pentru memorarea datelor, şi de a utiliza registrele CPU (Central Processing Unit) pentru toate operaŃiile aritmetico-logice. În contrast cu arhitecturile CISC, în cazul RISC nu este posibilă execuŃia operaŃiilor (instrucŃiunilor) aritmetice asupra unor operanzi locaŃi în memorie. Obiectivul esenŃial în cazul RISC este acela de a proiecta pentru viteză maximă, evitând utilizarea memoriei ori de câte ori este posibil, deoarece accesele la memorie sunt mult mai lente comparativ cu accesele la registre CPU. Pentru flexibilitate maximă, în cazul instrucŃiunilor aritmetice, se utilizează formatul cu trei adrese (de registru). De regulă în procesor se implementează un set de 32 registre. Numărul reprezintă un compromis între două cerinŃe:

- un număr cât mai mare de registre reprezintă optimul pentru compilator - comutarea contextului devine tot mai lentă cu creşterea numărului de registre.

Page 2: CAP2.pdf

Proiectarea setului de instrucŃiuni

12

De asemenea, pe măsură ce creşte numărul de registre (în termenii puterilor lui 2), creşte şi timpul de acces la registre şi acest lucru trebuie evitat. Evident că şi memoria trebuie accesată pentru citirea şi încărcarea în registre a diverşilor operanzi şi pentru memorarea diverselor rezultate obŃinute în registre. Transferurile cu memoria sunt gestionate prin instrucŃiuni de tip load şi respectiv store şi acestea sunt principalele instrucŃiuni care accesează memoria. Formatul load/store este caracteristic procesoarelor RISC. Vom nota cele 32 registre R0 - R31. Deşi toate vor fi registre generale, adiŃional câteva dintre acestea vor avea şi funcŃii speciale. R0 va conŃine permanent constanta 0 şi nu poate fi utilizat în alt scop. Acesta este un principiu general de proiectare şi este respectat deoarece este foarte avantajos să avem un registru care conŃine constanta zero pentru instrucŃiunile de ştergere (iniŃializate cu zero) şi de comparare cu zero. Nu vom prevedea o instrucŃiune explicită de tip “move” registru - registru. Aceste transferuri vor fi realizate prin instrucŃiuni ADD (adunare) în care unul dintre operanzi va fi R0 (constanta zero). 2.1.2. Lungimea instrucŃiunilor şi a operanzilor Începând cu 1990 tehnologiile de fabricaŃie au permis integrarea procesoarelor pe 32 şi chiar 64 biŃi într-un singur circuit VLSI. Evident că în cazul RISC, unde unitatea de comandă este simplă, proiectantul trebuie să decidă dacă va utiliza aria disponibilizată în alte scopuri cum ar fi, de exemplu, memorie cache ”on-chip“ de capacitate mai mare. 32 biŃi asigură o precizie rezonabilă pentru operaŃiile cu întregi în timp ce 64 biŃi par rezonabili pentru operaŃiile în virgulă flotantă. Există deja procesoare care suportă chiar 128 biŃi. De exemplu, procesorul RISC i860 are instrucŃiuni "load/store" pe 128 biŃi. DiferenŃe arhitecturale semnificative sunt foarte puŃine între procesoarele pe 32 şi respectiv 64 de biŃi în ceea ce priveşte unitatea de control; principalele diferenŃe constau în lungimea diferită a registrelor interne, ALU şi respectiv numărul diferit de linii aferente busurilor interne şi externe CPU. Odată cu creşterea lungimii cuvântului la 32/64 biŃi a apărut şi necesitatea specificării în codul instrucŃiunii a lungimii operanzilor ce vor fi procesaŃi: 8 biŃi, 16 biŃi, 32 biŃi, 64 biŃi etc. O soluŃie tipică la această problemă constă în includerea în formatul instrucŃiunii a unui câmp, să zicem de 2 biŃi, care va specifica lungimea operandului/operanzilor procesaŃi: 00 -8 biŃi, 01 -16 biŃi, 10 -32 biŃi, 11 -64 biŃi. Nu vom include în formatul instrucŃiunii pe care-l vom propune un astfel de câmp considerând că toate transferurile vor fi pe 32 biŃi. Propunem ca exerciŃiu de proiectare includerea unui astfel de câmp în format. Unitatea cea mai mică adresabilă în memorie este octetul (8 biŃi). Pentru eficienŃă codul instrucŃiunii nu trebuie să aibă o lungime arbitrară ci trebuie compus dintr-un număr exact de octeŃi. Procesoarele CISC au de regulă instrucŃiuni de lungime variabilă. Procesoarele RISC au instrucŃiuni de lungime fixă. Vom alege o lungime fixă pentru instrucŃiune: 32 biŃi. Aceasta conduce la simplificarea decodificatorului instrucŃiunii. Lungimea de 32 biŃi este uzuală în cazul RISC deşi nu este posibilă specificarea unei constante pe 32 biŃi într-o instrucŃiune pe 32 biŃi. Vom specifica constante pe 16 biŃi şi printr-o secvenŃă de două instrucŃiuni, un registru pe 32 biŃi va putea fi încărcat cu o

Page 3: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

13

constantă pe 32 biŃi, compusă din două constante pe 16 biŃi. Această complicaŃie va fi evitată la încărcarea constantei zero, operaŃie realizabilă printr-o singură instrucŃiune dacă se utilizează R0 care conŃine permanent constanta zero pe 32 biŃi. 2.1.3. Lungimea adreselor de memorie Utilizarea adreselor pe 32 biŃi este convenabilă dacă registrele procesorului au de asemenea 32 biŃi. Utilizarea adreselor pe 64 biŃi ar fi o altă variantă care Ńinteşte în viitor. Vom prevedea adrese pe 32 biŃi care asigură adresarea unei memorii interne de maxim 4 gigaocteŃi (232). 2.2. Formate de instrucŃiuni Vom aloca 6 biŃi, biŃii 31 la 26, pentru câmpul principal de opcode, ceea ce va permite codificarea a 64 instrucŃiuni diferite. În ideea extinderii numărului de instrucŃiuni, pentru instrucŃiunile care nu utilizează toŃi biŃii rămaşi (biŃii 25 la 0), vom utiliza în anumite cazuri un câmp secundar de sub-opcode. De exemplu, câmpul principal de opcode ar putea specifica o clasă de instrucŃiuni (aritmetice), în timp ce câmpul sub-opcode va selecta operaŃia (aritmetică) propriu-zisă. Vom avea cinci clase de instrucŃiuni: 2.2.1. Formatul registru – registru – registru (R-R-R) Pentru eficienŃă şi viteză aceste instrucŃiuni vor opera numai cu operanzi preluaŃi din registre. O operaŃie aritmetico-logică se va aplica celor doi operanzi preluaŃi din registre iar rezultatul va fi depus tot într-un registru; 15 biŃi vor fi necesari pentru a specifica cele 3 registre.

Fig. 2.1. Formatul registru – registru – registru (formatul R-R-R) Este de dorit să păstrăm câmpurile definite în formatul R-R-R pe aceleaşi poziŃii în toate formatele pe care le vom defini ulterior. Aceasta înseamnă că toate instrucŃiunile care vor avea un registru destinaŃie (Rd) vor utiliza biŃii 25 la 21 pentru selecŃia destinaŃiei şi toate instrucŃiunile care utilizează două registre sursă vor utiliza biŃii 20 la 16 pentru selecŃia sursei Rs1 şi respectiv biŃii 15 la 11 pentru selecŃia sursei Rs2. InstrucŃiunile care

Page 4: CAP2.pdf

Proiectarea setului de instrucŃiuni

14

utilizează un singur registru sursă, cum ar fi cele care operează cu un registru şi o constantă, vor specifica unicul registru sursă în câmpul 20 la 16 (Rs1). BiŃii neutilizaŃi din codul instrucŃiunii conduc la o slabă compactare a secvenŃelor de cod şi deci la o ineficientă stocare a acestora în memorie. Dar nu acesta este factorul esenŃial care trebuie luat în considerare; factorul esenŃial este viteza cu care instrucŃiunea poate fi decodificată şi executată. Un exemplu de instrucŃiune registru – registru – registru ar fi: ADD R1,R4,R5 ; R1 = R4 + R5 Utilizând R0, care memorează permanent constanta zero, putem crea o instrucŃiune “move”: ADD R2,R3,R0 ; R2 = R3 (+0) În consecinŃă, o instrucŃiune “move” registru – registru – registru specifică este nenecesară.

InstrucŃiunile aritmetice (care se încadrează în acest format) vor realiza operaŃii ca: adunare, scădere, înmulŃire, împărŃire (operaŃii cu întregi), deplasare/rotire la stânga sau la dreapta cu unul sau mai mulŃi biŃi, iar instrucŃiunile logice vor realiza operaŃii ca AND, OR, NOT, XOR. Numerele reprezentate în virgulă flotantă vor avea operaŃii (instrucŃiuni) proprii de adunare, scădere, înmulŃire şi împărŃire şi în acest context s-ar putea renunŃa la instrucŃiunile de înmulŃire/împărŃire în virgulă fixă. InstrucŃiunile de deplasare/rotire necesită numai un operand. Rs1 ar putea specifica operandul deplasat iar Rs2 ar putea specifica numărul de poziŃii deplasate. BiŃii neutilizaŃi (biŃii 10 la 0) ar putea fi utilizaŃi ca “sub-opcode” pentru o unitate funcŃională cum ar fi ALU. Astfel, câmpul “opcode” va specifica o clasă de operaŃii (de exemplu aritmetico-logice), iar câmpul “sub-opcode” va selecta operaŃia propriu-zisă la ALU. 2.2.2. Formatul registru - registru - constantă (R-R-I) Sunt foarte frecvente situaŃiile în care unul dintre operanzii unei instrucŃiuni aritmetico-logice este o constantă. Pentru codificarea constantei respective se utilizează un câmp din codul instrucŃiunii şi de aceea acest mod de adresare se numeşte imediat, iar formatul se mai numeşte şi registru - registru - imediat. Cel mai adesea constantele necesare sunt constante mici. O dimensiune rezonabilă pentru aceste constante este 16 biŃi şi această dimensiune se încadrează bine în formatul din fig. 2.2. Combinând două constante de 16 biŃi se obŃine o constantă pe 32 biŃi. Câmpurile “opcode”, Rd şi Rs1 rămân pe aceleaşi poziŃii pe care au fost fixate în formatul R-R-R (important pentru reducerea complexităŃii decodificatorului instrucŃiunii). Un exemplu de instrucŃiune R-R-I ar fi: ADD R4,R5,64 ; R4 = R5 + 64

Page 5: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

15

Fig. 2.2. Formatul registru - registru - constantă (formatul R-R-I) Formatul registru–registru-constantă poate fi utilizat cu toate operaŃiile aritmetico-logice prevăzute pentru formatul R-R-R, inclusiv operaŃiile de deplasare/rotire în care numărul de poziŃii deplasate va fi specificat de constanta utilizată. 2.2.3. Formatul registru - memorie (R-M) Pentru că toate instrucŃiunile procesează operanzi preluaŃi din registre, aceştia trebuie mai întâi transferaŃi din memorie în registre. InstrucŃiunile R-M (instrucŃiunile “load/store”), prin care se vor realiza transferurile registru - memorie, trebuie să specifice adresa locaŃiei de memorie ce va fi implicată în transfer, şi multe moduri de adresare pot fi utilizate pentru adresarea locaŃiei respective. Totuşi, modul de adresare registru indirect cu “offset” pe care îl vom implementa este un mod de bază din care derivă majoritatea celorlalte moduri. În modul de adresare indirect registru, un registru specificat conŃine adresa locaŃiei de memorie ce se va implica în transfer. OpŃional un “offset” dat de o constantă memorată în codul instrucŃiunii poate fi adunat la conŃinutul registrului respectiv pentru a genera adresa utilizată la accesarea memoriei. InstrucŃiunile “load” încarcă conŃinutul locaŃiei respective în registrul destinaŃie în timp ce instrucŃiunile “store” memorează registrul sursă în locaŃia respectivă. LD R1,200[R8] ; conŃinutul locaŃiei de memorie adresată ; de R8 + 200 este încărcat în R1. ST 16[R3],R4 ; R4 este copiat în locaŃia de memorie adresată

; de R3 + 16. O primă variantă de format pentru instrucŃiunile “load/store” ar fi formatul R-R-I din figura 2.3. Pentru “load” Rd specifică registrul ce va fi încărcat în timp ce pentru “store” Rd specifică registrul ce va fi copiat în memorie; în ambele cazuri Rs1 specifică registrul ce conŃine adresa. Inevitabil, în cazul “load” Rd este destinaŃie iar în cazul “store“ Rd este sursă ceea ce implică o complicaŃie minoră la proiectarea procesorului (decodificatorului instrucŃiunii). ComplicaŃia poate fi evitată recurgând la formatul din figura 2.4. a cărui deficienŃă constă în reducerea numărului de biŃi alocaŃi constantei de la 16 la 11 (offset în domeniul -210 până la +210 -1).

Page 6: CAP2.pdf

Proiectarea setului de instrucŃiuni

16

Fig.2.3. Formatul “load/store“ - versiunea 1

Fig.2.4. Formatul “load/store” - versiunea 2 2.2.4. Formatul instrucŃiunilor de “branch” În limbajele de nivel înalt apar puncte de decizie implementate, de exemplu, prin declaraŃii IF: if((x!=y)&&(z<0))

{

a=b-3 ; b=b+4 ;

}

Page 7: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

17

Compilatoarele trebuie să translateze astfel de declaraŃii în instrucŃiuni maşină. Este neraŃional să prevedem câte o instrucŃiune maşină pentru fiecare declaraŃie IF (datorită numărului vast de declaraŃii IF posibile). De asemenea, n-ar fi o idee bună încercarea de a proiecta un set de instrucŃiuni maşină copiind instrucŃiunile unui anumit limbaj de nivel înalt. Este evident că trebuie să extragem primitivele esenŃiale ale limbajelor de nivel înalt şi acestea să fie implementate în limbajul maşină. O construcŃie IF de orice complexitate poate fi descompusă în declaraŃii IF simple de forma: if (x relaŃie y ) goto L1 unde relaŃie poate fi orice relaŃie permisă în limbajele de nivel înalt: <, >, <=, >=, ==, !=. De exemplu, secvenŃa C anterioară poate fi compilată într-o secvenŃă echivalentă de instrucŃiuni maşină: if (x==y) goto L1;

if (z>=0) goto L1; a=b-3;

b=b+4;

L1:

Există mai multe posibilităŃi de implementare a declaraŃiei IF cu instrucŃiuni maşină fiecare având un impact particular asupra proiectării procesorului. Partea goto L1 revendică specificarea adresei de salt L1 de unde se va extrage următoarea instrucŃiune în cazul în care condiŃia specificată în declaraŃia IF este îndeplinită. Deoarece astfel de instrucŃiuni se utilizează pentru implementarea buclelor de program de lungime relativ mică, pentru calculul adresei de salt se utilizează în general o adresare relativă la PC (adresa de salt se obŃine adunând la PC-ul curent un “offset” specificat). Acest mod de adresare permite compilatorului să genereze secvenŃe de cod relocabile care pot fi încărcate în orice zonă de memorie fără schimbarea adreselor de “branch”. În concluzie, instrucŃiunile de branch vor realiza salturi condiŃionate relative la PC (Program Counter) . AdiŃional sunt necesare şi salturi necondiŃionate pe care le vom realiza prin instrucŃiuni jump. A. Utilizarea registrului de condiŃii Registrul de condiŃii sau de flag-uri este un registru special care caracterizează rezultatele ALU obŃinute în cadrul instrucŃiunilor aritmetice: Z - zero = 1 - caracterizează rezultat zero = 0 - caracterizează rezultat diferit de zero

Page 8: CAP2.pdf

Proiectarea setului de instrucŃiuni

18

C - carry = 1 - caracterizează rezultat cu transport (împrumut) = 0 - caracterizează rezultat fără transport (împrumut) S - semn = 1 - caracterizează rezultat negativ = 0 - caracterizează rezultat pozitiv O - overflow = 1 - caracterizează rezultat cu depăşire = 0 - caracterizează rezultat fără depăşire Pentru a implementa o declaraŃie IF, mai întâi se execută o instrucŃiune aritmetică poziŃionând flag-urile de condiŃii în acord cu rezultatul obŃinut. Cea mai utilizată este instrucŃiunea de comparare care este similară cu instrucŃiunea de scădere, cu deosebirea că rezultatul nu este depus la nici o destinaŃie ci doar se poziŃionează flag-urile în acord cu valoarea sa. Apoi o instrucŃiune de branch condiŃionat examinează condiŃia testată şi, dacă aceasta este îndeplinită, realizează saltul la adresa specificată. Există condiŃii pentru a căror verificare trebuie examinate mai multe flag-uri. O listă tipică de instrucŃiuni branch ar fi:

BL - branch if less – salt dacă este mai mic decât ( < ) BG - branch if greater – salt dacă este mai mare decât ( > ) BGE - branch if greater or equal – salt dacă este mai mare sau egal cu ( >= ) BLE - branch if less or equal – salt dacă este mai mic sau egal cu ( <= ) BE - branch if equal – salt dacă este egal cu ( == ) BNE - branch if not equal – salt dacă nu este egal cu ( != )

Considerând că compilatorul alocă variabilelor x şi y registrele R1 şi respectiv R2, declaraŃia: if (x==y) goto L1 poate fi translatată într-o secvenŃă de două instrucŃiuni maşină: CMP R1,R2 ; poziŃionează flag-urile în acord cu rezultatul ; scăderii R1-R2 BE L1

Cele două instrucŃiuni trebuie executate în secvenŃă şi de aici rezultă o restricŃie pentru compilatoarele cu reorganizare care nu pot introduce între cele două instrucŃiuni decât instrucŃiuni care nu afectează flag-urile de condiŃii. De asemenea prima instrucŃiune trebuie executată complet înainte de startarea celei de branch rezultând penalităŃi în cazul procesoarelor pipeline. Registrul de condiŃii este o parte din ceea ce se numeşte starea procesorului şi trebuie salvat la fiecare comutare de context. Cu toate dezavantajele menŃionate registrul de condiŃii este încă foarte popular.

Page 9: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

19

B. Evitarea utilizării unui registru de condiŃii O soluŃie care evită atât utilizarea registrului de condiŃii cât şi necesitatea execuŃiei succesive a celor două instrucŃiuni constă în combinarea celor două instrucŃiuni într-o singură instrucŃiune de branch condiŃionat. Această instrucŃiune compară conŃinutul a două registre şi execută saltul pe baza unei condiŃii specificate (de exemplu de egalitate): BEQ R1,R2,L1 ; salt la L1 dacă R1 = R2 O astfel de instrucŃiune este necesară pentru fiecare condiŃie deşi instrucŃiunea BEQ în combinaŃie cu o instrucŃiune BL (sau BG) formează un set care face posibil orice tip de test. Să presupunem că dispunem şi de instrucŃiunea: BL R1,R2,L1 ; salt la L1 dacă R1 < R2 Cele două instrucŃiuni (BEQ şi BL) sunt suficiente pentru a implementa toate tipurile de test necesare: CondiŃie SecvenŃa de cod aferentă R1 < R2 BL R1,R2,L1

R1 > R2 BL R2,R1,L1

R1 >= R2 BL R2,R1,L1

BEQ R1,R2,L1

R1 <= R2 BL R1,R2,L1

BEQ R1,R2,L1

R1 == R2 BEQ R1,R2,L1 R1 != R2 BL R1,R2,L1

BL R2,R1,L1

Pentru a elimina secvenŃele de două instrucŃiuni, sunt necesare încă două instrucŃiuni: BGE - salt dacă este mai mare sau egal cu ... BNE - salt dacă nu este egal cu ... Testarea pe condiŃie de zero este o operaŃie foarte des utilizată în programe şi de aceea pot fi prevăzute două instrucŃiuni speciale: BEQZ (“branch if zero”) şi BEQNZ (“branch if not zero”).

Page 10: CAP2.pdf

Proiectarea setului de instrucŃiuni

20

BEQZ R3,L1 ; salt la adresa L1 dacă R3 == 0. BEQNZ R3,L1 ; salt la adresa L1 dacă R3 != 0. În cazul nostru aceste teste sunt uşor de realizat utilizând registrul R0 (care memorează permanent constanta zero) şi instrucŃiunile BEQ şi BNE: BEQ R3,R0,L1 ; salt la adresa L1 dacă R3 == 0. BNE R3,R0,L1 ; salt la adresa L1 dacă R3 != 0. Întotdeauna alegerea instrucŃiunilor în cazurile RISC este strâns dependentă de modul de implementare al procesului şi de efectul pe care introducerea a câtorva noi instrucŃiuni îl va avea asupra performanŃelor generale ale acestuia. CondiŃia de “egalitate” revendică un comparator, care operează foarte rapid, în timp ce alte condiŃii cum ar fi “mai mare sau egal”, revendică un sumator (scăzător), care operează mai lent. C. OpŃiunea noastră privind instrucŃiunile branch Considerăm oportună includerea în clasa branch a patru instrucŃiuni: BEQ Ri,Rj,L1 BNE Ri,Rj,L1

BL Ri,Rj,L1 BGE Ri,Rj,L1 Aceste instrucŃiuni vor permite implementarea pe o singură instrucŃiune a oricărei condiŃii de salt. Formatul cel mai potrivit pentru aceste instrucŃiuni este prezentat în fig. 2.5., unde Ri este Rd, Rj este Rs1 şi L1=PC+offset. Din nou utilizăm câmpul Rd pentru selecŃia unui registru sursă şi nu destinaŃie.

Fig. 2.5. Formatul instrucŃiunilor de branch (format de tip R-R-I ) 2.2.5. InstrucŃiunile de salt (jump) InstrucŃiunea jump realizează un salt necondiŃionat la o adresă specificată în codul instrucŃiunii. Aceste instrucŃiuni sunt necesare la implementarea construcŃiilor IF-THEN-ELSE; sunt de asemenea utile la implementarea buclelor FOR şi WHILE în care condiŃia de

Page 11: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

21

ieşire din buclă este calculată la începutul buclei. InstrucŃiunea jump va fi utilizată la sfârşitul buclei pentru revenirea pe începutul acesteia. Utilizând mnemonica JMP, vom avea instrucŃiunea: JMP L1 ; salt la adresa L1 Adresa de salt L1 se obŃine adunând la PC offset-ul specificat în codul instrucŃiunii (adresare relativă la PC ca în cazul instrucŃiunilor branch).

Fig. 2.6. Formatul instrucŃiunii jump (formatul I) Să menŃionăm că şi instrucŃiunile branch pot fi făcute necondiŃionate. Un exemplu ar fi: BEQ R1,R1,L1 ; salt dacă R1 = R1 InstrucŃiunile jump utilizează un offset pe 26 biŃi (fig. 2.6.) spre deosebire de instrucŃiunile branch care utilizează un offset doar pe 16 biŃi. DistanŃa maximă de salt va fi mult mai mare în cazul jump. Atât în cazul branch cât şi în cazul jump ar putea fi folosit şi un al doilea mod de adresare, modul registru - indirect. În acest caz în instrucŃiune este specificat explicit un registru (altul decât registrul PC) care conŃine adresa instrucŃiunii pe care se va executa saltul (fig. 2.7.).

Fig. 2.7. Formatul instrucŃiunii jump cu mod de adresare indirect - registru Astfel de instrucŃiuni ar putea fi utile la implementarea declaraŃiilor SWITCH/CASE din limbajele de nivel înalt şi pentru revenirea din proceduri. Cu formatul din figura 2.7. putem avea, de exemplu: JMP [R1] ; salt la instrucŃiunea a cărei adresă este

; conŃinută în R1

Page 12: CAP2.pdf

Proiectarea setului de instrucŃiuni

22

sau chiar: JMP 134[R2] ; salt la instrucŃiunea a cărei adresă se obŃine ; adunând R2 + 134. Să notăm că, în aceste cazuri, adresa de salt este o adresă absolută şi nu relativă la PC deşi, dacă se dovedeşte util, ea ar putea fi interpretată şi ca adresă relativă. Să mai notăm că notaŃia [R1] utilizată aici nu înseamnă “conŃinutul locaŃiei de memorie a cărei adresă este dată de R1“ ca în cazul instrucŃiunilor load/store. 2.2.6. Apelul procedurilor O facilitate a limbajelor de nivel înalt este aceea de a permite organizarea şi execuŃia procedurilor. O secvenŃă de instrucŃiuni care se repetă de mai multe ori pe parcursul unui program se organizează într-o procedură care se apelează din diverse puncte ale programului principal. După fiecare execuŃie procedura returnează controlul programului principal printr-o revenire pe instrucŃiunea următoare celei care a realizat apelul procedurii. Procedurile pot fi imbricate (o procedură apelează altă procedură, care apoi apelează altă procedură, ... etc.). De regulă este permis ca o procedură să se apeleze pe ea însăşi (proceduri recursive). La apel, procedurii i se transmit de regulă parametrii care vor fi utilizaŃi în calculele executate în interiorul procedurii. La sfârşitul execuŃiei procedurile pot returna valori. Două mecanisme esenŃiale trebuie să funcŃioneze pentru implementarea procedurilor:

- mecanismul de apel şi respectiv de revenire din procedură. - mecanismul de transmitere a parametrilor procedurii şi de returnare a

rezultatelor obŃinute în procedură.

A. InstrucŃiunile CALL/RET

În cazul procesoarelor CISC două instrucŃiuni speciale sunt prevăzute pentru apelul procedurilor (instrucŃiunea CALL) şi pentru revenirea din proceduri (instrucŃiunea RET). InstrucŃiunea CALL salvează în stivă adresa de revenire (adresa instrucŃiunii ce urmează după CALL) şi apoi execută un salt necondiŃionat la adresa de start a procedurii. InstrucŃiunea RET de la sfârşitul procedurii realizează revenirea în programul principal citind adresa de revenire din stivă şi executând un salt necondiŃionat la această adresă (fig. 2.8).

Page 13: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

23

B. Stiva Stiva este o structură de date de tip coadă care funcŃionează pe principiul LIFO (Last-In-First-Out). Stivele pot fi implementate în memoria principală sau utilizând registre interne procesorului. Stiva a fost preferată în memorie (mai cu seamă în cazul procesoarelor CISC) datorită numărului aproape nelimitat de apeluri imbricate sau recursive. Un registru special al procesorului numit SP (Stack Pointer) memorează permanent adresa vârfului stivei. La memorarea unui cuvânt (de exemplu, de 32 biŃi) în stivă, mai întâi este decrementat cu 4 registrul SP (cuvântul este format din 4 octeŃi) şi apoi cuvântul respectiv este scris în memorie la adresa SP. La citirea unui cuvânt din stivă, mai întâi se citeşte locaŃia de la adresa SP şi apoi SP este incrementat cu 4. A rezultat astfel o stivă care creşte în jos (depunerea în stivă se face cu decrementare de adresă).

Fig.2.8. Apeluri de procedură prin instrucŃiuni CALL/RET Stiva poate fi creată şi în interiorul procesorului utilizând un set de registre dedicate. Avantajul stivelor interne este viteza operaŃiilor cu stiva care va fi mult superioară. În cazul RISC se preferă stivele interne deşi, în această variantă, stiva va conŃine un număr finit şi relativ mic de locaŃii. C. Transferul parametrilor prin stivă Procesoarele care execută instrucŃiuni CALL/RET execută şi instrucŃiuni PUSH/POP pentru salvare/restaurare date în/din stivă. InstrucŃiunea PUSH decrementează registrul SP şi apoi memorează data specificată (registrul specificat) la această adresă.

Page 14: CAP2.pdf

Proiectarea setului de instrucŃiuni

24

InstrucŃiunea POP citeşte locaŃia adresată de SP (vârful stivei) şi o plasează în registrul specificat, după care incrementează registrul SP. Transferul parametrilor se realizează prin instrucŃiuni PUSH/POP. Înainte de apelul procedurii (CALL) în programul principal parametrii sunt memoraŃi în stivă prin instrucŃiuni PUSH, iar după apel (în procedură) parametrii sunt preluaŃi din stivă prin instrucŃiuni POP. D. Utilizarea ferestrei de registre pentru transferul parametrilor şi

pentru variabile locale Deoarece procedurile sunt foarte utilizate în multe aplicaŃii, salvarea şi restaurarea registrelor la apelul procedurilor şi respectiv revenirea din proceduri consumă o parte semnificativă din timpul procesorului afectând negativ performanŃele acestuia. Proiectul RISC elaborat la Universitatea Berkeley (1985) introducea conceptul ferestrei de registre (register window) prin care un set de registre interne era utilizat pentru simplificarea şi creşterea vitezei de transmitere a parametrilor între procedurile imbricate. Era prevăzut un număr de registre locale pentru fiecare procedură. Ideea a fost preluată în câteva dintre următoarele procesoare printre care şi procesorul SUN Sparc. Principiul “register window” presupune implementarea în cadrul procesorului a unui set amplu de registre care va memora adresele de revenire şi parametrii transferaŃi între proceduri (fig. 2.9.).

Set de registre

Pointer-ul de fereastră(selectează fereastra curentă)

Registre pentru procedura 1

Registre pentru procedura 3

Registre pentruprocedura 2

Registre pentruprocedura 4

parametrii de ieşire din procedura 1şi respectiv de intrare în procedura 2

parametrii de ieşire din procedura 2şi respectiv de intrare în procedura 3

Registre disponibiletuturor procedurilor(variabile globale)

Fig. 2.9. Fereastra de registre implementată în procesoare RISC

Page 15: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

25

Fiecare procedură poate accesa un subset de registre alocat procedurii respective în cadrul setului de registre. Subsetul alocat unei proceduri este denumit fereastră de registre (register window). Registrele din centrul ferestrei sunt utilizate numai de procedura respectivă. Registrele din partea superioară a ferestrei sunt accesate de procedura respectivă şi de procedura care a apelat-o, iar registrele din partea inferioară de procedura respectivă şi procedura apelată de aceasta. Atât partea superioară cât şi partea inferioară a ferestrei se suprapune peste porŃiuni similare alocate altor proceduri. Când o procedură este apelată de către altă procedură (iniŃial de către programul principal), fereastra se mută pe poziŃia imediat următoare, iar la revenirea din procedură fereastra se mută înapoi. Presupunând că setul va conŃine un număr suficient de registre pentru imbricarea procedurilor, putem afirma că nu mai este necesară salvarea parametrilor şi a adresei de revenire în memorie. Setul de registre este gestionat de un registru pointer de fereastră care identifică permanent fereastra curentă. Un al doilea set de registre accesibil tuturor procedurilor este prevăzut pentru variabilele globale. Analizând diverse programe s-a constatat că, de regulă, numărul de proceduri imbricate nu este mai mare de 8 şi extrem de rar depăşeşte 11, iar depăşirea accidentală a acestor limite se face pentru perioade de timp rezonabil de scurte. Pentru exploatarea eficientă a acestor caracteristici setul de registre este adresat într-o manieră circulară. Un exemplu specific ar fi procesorul RISC II realizat la Universitatea Berkeley, care are în total 138 registre configurate în 8 ferestre a câte 32 registre fiecare, plus 10 registre globale. Aranjarea circulară a celor 8 ferestre de registre este prezentată în figura 2.10.

Fig. 2.10. ConfiguraŃia circulară a ferestrelor de registre la procesorul RISC II

Page 16: CAP2.pdf

Proiectarea setului de instrucŃiuni

26

Pointerul ferestrei curente (CWP - Current Window Pointer) are 3 biŃi şi selectează permanent fereastra care va fi accesată. Registrul care va fi accesat în cadrul ferestrei va fi specificat în instrucŃiune prin numărul său (0 - 31). Registrele numerotate de la 0 la 9 referă întotdeauna registrele globale indiferent de numărul ferestrei curente. Registrele globale sunt accesibile tuturor procedurilor. Registrele numerotate de la 10 la 31 referă întotdeauna registre din cadrul ferestrei curente. Adresa efectivă a unui registru din setul R10 - R31 se obŃine prin concatenarea celor 3 biŃi ce formează adresa de fereastră (conŃinutul CWP) cu cei 5 biŃi care specifică adresa registrului în cadrul ferestrei. Să observăm că prin suprapunerea ferestrelor apar grupuri de registre care răspund la două adrese. De exemplu, registrul 0:26 din fereastra 0 (programul principal) este în acelaşi timp şi registrul 1:10 din fereastra 1 (procedură pe primul nivel de imbricare). În general numărul procedurilor imbricate este limitat şi aranjamentul circular al ferestrelor se potriveşte bine acestei caracteristici. Ori de câte ori acest număr depăşeşte valoarea 8, va trebui utilizată memoria principală pentru salvarea conŃinutului anumitor registre. Un alt dezavantaj potenŃial apare în sistemele de operare multitasking, la comutarea task-urilor; salvarea contextului consumă timp suplimentar (număr mare de registre). E. OpŃiunea noastră privind mecanismul de apel al procedurilor OpŃiunea are la bază două considerente. În primul rând considerăm oportună evitarea instrucŃiunilor complexe de tip CALL/RET care vor crea probleme în cazul implementării procesorului în tehnică pipeline (instrucŃiuni specifice CISC). În al doilea rând, pentru că apelul procedurilor poate fi foarte frecvent, considerăm oportună evitarea utilizării memoriei pentru memorarea adreselor de revenire, a parametrilor şi pentru salvarea registrelor. Dacă operaŃiile sunt frecvente, ar trebui implementate în acord cu filozofia RISC. Principiul ferestrelor de registre este atractiv şi oportun pentru că utilizează registre şi pentru modul eficient de transmitere a parametrilor. În cazurile în care numărul procedurilor imbricate depăşeşte numărul ferestrelor trebuie recurs la memorie pentru salvarea adreselor de revenire şi transmiterea parametrilor. O ultimă posibilitate constă în transformarea instrucŃiunilor CALL/RET în secvenŃe de instrucŃiuni simple. Un singur registru intern va fi utilizat pentru memorarea adresei de revenire: R31. O instrucŃiune CALL simplificată, numită JAL (Jump And Link), va executa saltul la adresa specificată în instrucŃiune şi va memora adresa de revenire în R31. Pentru revenirea din procedură se poate utiliza un simplu salt necondiŃionat la instrucŃiunea a cărei adresă este dată de R31; va fi suficientă o instrucŃiune JMP cu mod de adresare indirect - registru. InstrucŃiunea JAL poate utiliza formatul I din figura 2.6. Mecanismul va funcŃiona evident pentru un singur nivel de apel. Pentru imbricare, R31 va fi memorat în stivă, utilizând un al doilea registru ca pointer de stivă: R29. În esenŃă, se creează o stivă în vârful căreia se va afla R31, iar restul locaŃiilor se vor afla în memorie. SecvenŃa de cod necesară pentru apelul şi revenirea dintr-o procedură va fi:

Page 17: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

27

SUB R29,R29,4 ; decrementează pointerul de stivă (4 octeŃi) ST [R29],R31 ; memorează ultima adresă de revenire în stivă JAL Proc_Label ; salt la Proc_Label şi memorează adresa de

; revenire în R31. LD R31,0[R29] ; după revenirea din procedură, se restaurează ; adresa de revenire anterioară în R31. ADD R29,R29,4 ; incrementează pointerul de stivă (4 octeŃi) Revenirea de la sfârşitul procedurii va fi simplă: JMP [R31] ; salt la locaŃia a cărei adresă se află în R31 Există două alternative pentru salvarea registrelor: salvare înainte de apelul procedurii (salvarea executată de către apelant) şi respectiv după apel (salvarea executată de către apelat). Pentru memorarea parametrilor în stivă, înainte de apel, va fi necesară o secvenŃă de forma: SUB R29,R29,4 ST [R29],R31

SUB R29,R29,4

ST [R29],Parametru1

SUB R29,R29,4 ST [R29],Parametru2

JAL Proc_Label

După definirea principalelor formate de instrucŃiune se poate trece la proiectarea procesorului. Evident că vor trebui incluse în setul de instrucŃiuni prezentat şi alte instrucŃiuni, dar putem considera că toate aceste instrucŃiuni noi se vor încadra în formatele deja descrise. InstrucŃiunile descrise sunt specifice filozofiei RISC. 2.3. ExecuŃia instrucŃiunilor ExecuŃia instrucŃiunilor se face în paşi elementari succesivi. În fiecare pas elementar se vor executa anumite operaŃii simple, interne procesorului. 2.3.1. Structura procesorului Structura internă a procesorului este prezentată în figura 2.11. În structură pot fi identificate registrele generale R0 - R31 şi un număr de registre specializate:

PC - Program Counter - conŃine permanent adresa următoarei instrucŃiuni de executat

Page 18: CAP2.pdf

Proiectarea setului de instrucŃiuni

28

IR - Instruction Register - conŃine codul instrucŃiunii curente (în curs de execuŃie)

MAR - Memory Address Register - conŃine adresa locaŃiei de memorie ce va fi accesată în timpul unei operaŃii de citire/scriere memorie.

MDR - Memory Data Register - conŃine data trimisă spre memorie (la scriere) şi respectiv data recepŃionată din memorie (la citire)

A - registru tampon - memorează conŃinutul registrului sursă Rs1 selectat în setul de registre generale

B - registru tampon - memorează conŃinutul registrului sursă Rs2 selectat în setul de registre generale

C - registru tampon - conŃine valoarea ce va fi memorată în registrul destinaŃie Rd selectat în setul de registre generale

Fig. 2.11. Structura procesorului cu control centralizat

Page 19: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

29

În structură mai apare:

ALU -unitatea aritmetico-logică în care se vor executa operaŃiile aritmetice şi logice

Unitate de control -va genera semnalele de comandă pentru realizarea transferurilor de date şi a altor operaŃii interne procesorului. Va utiliza conŃinutul registrului IR (codul instrucŃiunii curente) pentru a determina ce comenzi trebuie să genereze şi în ce secvenŃă. InstrucŃiuni diferite vor impune secvenŃe de comenzi diferite. SecvenŃierea în timp a comenzilor se va face pe baza semnalului de tact al procesorului.

În structură mai apar 3 busuri interne (busurile S1, S2 şi D) care interconectează registrele şi ALU. Primele două busuri, S1 şi S2, sunt dedicate celor doi operanzi sursă posibil de specificat în instrucŃiune. S1 şi S2 transportă operanzii pe intrările ALU. Busul D transportă rezultatele ALU la destinaŃia specificată în instrucŃiune. Structura cu trei busuri este specifică formatului de instrucŃiune cu trei adrese (de registru). Cele două registre, MAR şi MDR, au fost prevăzute pentru interfaŃarea procesorului cu memoria şi nu sunt accesibile programatorului (nu pot fi specificate în nici o instrucŃiune maşină). Înaintea oricărui acces la memorie, în MAR va fi încărcată adresa locaŃiei ce urmează a se accesa. În instrucŃiunile LD (load), MDR va fi încărcat cu datele citite din memorie , iar în instrucŃiunile ST (store), MDR va fi încărcat de către procesor cu datele ce vor fi scrise în memorie. Registrele A, B şi C sunt de asemenea inaccesibile programatorului şi au fost prevăzute pentru interfaŃarea setului de registre generale R31 - R0. Registrele A şi B vor fi încărcate cu datele citite din registrele sursă specificate în instrucŃiune (Rs1 şi Rs2) iar registrul C va fi încărcat cu datele ce urmează a fi depuse în registrul destinaŃie specificat în instrucŃiune (Rd). Setul de registre generale are structura unei memorii multiport sincronă rapidă cu 32 locaŃii a câte 32 biŃi, care va avea 3 surse de adresare:

- câmpul Rs1 din codul instrucŃiunii pentru citirea primului registru sursă în A - câmpul Rs2 din codul instrucŃiunii pentru citirea celui de-al doilea registru

sursă în B - câmpul Rd din codul instrucŃiunii pentru scrierea datelor din C în registrul

destinaŃie specificat. Pentru descrierea transferurilor interne de date vom utiliza notaŃia: Rj ← Ri ; conŃinutul registrului Ri este transferat în registrul Rj În structura din figura 2.11. aceste transferuri pot fi realizate numai prin intermediul ALU, ceea ce implică:

Page 20: CAP2.pdf

Proiectarea setului de instrucŃiuni

30

a) ALUR ← Ri ; sursa Ri se aplică pe intrarea ALU şi se transferă

; pe ieşirile ALU ( ALUR ) b) Rj ← ALUR ; ieşirile ALUR se transferă în registrul destinaŃie Rj

Pentru transferul a) este utilizat unul din busurile sursă (S1 sau S2), iar pentru transferul b) este utilizat busul destinaŃie (D). Cele două transferuri sunt simultane ceea ce înseamnă că, global, transferul Rj←Ri se va executa într-o singură perioadă de tact. Registrele Ri şi Rj trebuie să fie registre conectate direct la busuri. Registrele generale R31-R0 nu sunt conectate direct şi de aceea vor realiza transferuri prin intermediul registrelor tampon A,B,C. 2.3.2. Ciclul fetch instrucŃiune În acest ciclu, registrul PC conŃine adresa instrucŃiunii ce urmează a se citi din memorie. Această adresă va fi transferată în MAR de unde va fi aplicată pe liniile de adresă ale memoriei. După o întârziere datorată timpului de acces la memorie, cuvântul de 32 biŃi citit din locaŃia selectată (codul instrucŃiunii) va fi încărcat în MDR prin intermediul liniilor de date ale memoriei. InstrucŃiunea este apoi transferată din MDR în IR şi PC este incrementat cu 4 pentru a pointa pe următoarea instrucŃiune în memorie (codul instrucŃiunii conŃine 4 octeŃi). Cele trei acŃiuni (operaŃii) din cadrul ciclului fetch instrucŃiune sunt: MAR ← PC ; se încarcă în MAR adresa instrucŃiunii IR ← MDR ; se încarcă în IR codul instrucŃiunii citit din memorie PC ← PC + 4 ; incrementare PC (codul instrucŃiunii de lungime fixă - ; 4 octeŃi) Prima operaŃie trebuie executată înaintea celei de a doua, dar a doua şi a treia pot fi executate simultan dacă incrementarea registrului PC nu implică utilizarea ALU (registrul PC implementat cu logică specială de incrementare). EvidenŃiind operaŃiile simultane, ciclul fetch instrucŃiune devine: MAR ← PC

IR ← MDR , PC ← PC + 4

Procesorul operează sincron astfel că fiecare operaŃie sau grup de operaŃii simultane startează la începutul perioadei de tact. Ciclul fetch instrucŃiune este independent de tipul instrucŃiunii şi conŃine întotdeauna aceleaşi operaŃii. Procesarea unei instrucŃiuni începe întotdeauna cu ciclul (faza) fetch instrucŃiune.

Page 21: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

31

2.3.3. Ciclul de execuŃie A doua fază, faza de execuŃie a instrucŃiunii, are un conŃinut dependent de tipul instrucŃiunii ce urmează a se executa. În cazul instrucŃiunilor aritmetico-logice, de exemplu, cei doi operanzi trebuie preluaŃi din registrele sursă specificate în codul instrucŃiunii şi transferaŃi în registrele tampon A şi respectiv B: A ← Rs1

B ← Rs2

BiŃii IR20 - 16 din codul instrucŃiunii selectează registrul Rs1, iar biŃii IR15 - 11 selectează registrul Rs2 (fig. 2.1.). Deoarece cele două câmpuri de selecŃie a registrelor sursă sunt situate, în general, pe aceleaşi poziŃii indiferent de tipul instrucŃiunii, este posibilă extragerea lor şi adresarea setului de registre generale înainte de decodificarea instrucŃiunii (decodificarea câmpului opcode). Putem, de asemenea, permite ca cele două operaŃii de transfer a registrelor sursă în registrele A şi respectiv B să se facă automat pentru toate instrucŃiunile chiar dacă cei doi operanzi sursă nu vor fi utilizaŃi (cum ar fi cazul instrucŃiunii de salt necondiŃionat JMP care poate să nu specifice nici o sursă - vezi fig. 2.6.). Pentru aceste instrucŃiuni care nu au operanzi sursă, conŃinutul registrelor A şi B nu va mai fi utilizat ulterior. Aceasta nu conduce la o degradare a performanŃelor procesorului deoarece am prevăzut căi de date dedicate şi independente între setul de registre generale şi registrele tampon A şi B. Dacă setul RG (registre generale) este implementat ca o memorie multiport atunci cele 2 operaŃii pot fi executate simultan: A ← Rs1 , B ← Rs2

Am prevăzut, de asemenea, o cale de date dedicată între registrul C şi setul RG care va fi utilizată la memorarea rezultatului în registrul destinaŃie. Următoarele operaŃii depind de tipul sau clasa instrucŃiunii ce urmează a se executa. Tipul instrucŃiunii este codificat în câmpul opcode şi va fi cunoscut doar după decodificarea acestui câmp. Câmpul opcode va fi decodificat în unitatea de control. A. InstrucŃiunile aritmetico-logice R-R-R ExecuŃia instrucŃiunilor aritmetico-logice, cum ar fi ADD R1,R2,R3, presupune în continuare următoarele operaŃii:

- transferul registrelor A şi B (cei doi operanzi sursă) pe intrările ALU. A va fi transferat pe busul S1, iar B pe busul S2.

- transferul rezultatului obŃinut pe ieşirile ALU în registrul C; acest transfer va fi efectuat pe busul D.

- transferul registrului C în registrul destinaŃie adresat în setul RG cu câmpul IR25 - 21 din codul instrucŃiunii (fig. 2.1.).

Page 22: CAP2.pdf

Proiectarea setului de instrucŃiuni

32

În concluzie: C ← A <operaŃie> B Rd ← C

Cele două operaŃii specificate pot fi descompuse, specificând şi busurile: S1bus ← A , S2bus ← B

Dbus ← S1bus <operaŃie> S2bus C ← Dbus

OperaŃia ALU va fi specificată prin decodificarea câmpului opcode (sau sub-opcode dacă există). B. InstrucŃiunile aritmetico-logice R-R-I InstrucŃiunile aritmetico-logice care utilizează două registre şi o constantă sunt similare cu cele care utilizează trei registre cu excepŃia că locul celui de-al doilea registru sursă este preluat de constanta specificată în câmpul IR15 - 0 din codul instrucŃiunii (fig. 2.2). Utilizând notaŃia IR15 - 0 pentru a specifica constanta, vom avea: C ← A <operaŃie> IR15-0 Constanta poate fi extrasă din codul instrucŃiunii (aflat în IR) pe unul din busurile S1 sau S2 (fig. 2.11.) de unde va fi aplicată pe una din intrările ALU. Să ne reamintim că nu am prevăzut o instrucŃiune specială de transfer (move) registru-registru. Transferurile registru-registru pot fi executate numai prin ALU utilizând instrucŃiunea ADD în care unul dintre operanzi va fi R0 (constanta zero). C. InstrucŃiunile cu referire la memorie (load/store) În formatul instrucŃiunilor load/store - versiunea 1 (fig. 2.3.), adresa locaŃiei de memorie este specificată de conŃinutul registrului sursă Rs1 la care se adaugă un offset codificat în câmpul IR15 - 0 al codului instrucŃiunii. Adresa astfel calculată trebuie încărcată în registrul MAR: MAR ← A + IR15-0

Această adunare poate fi efectuată în ALU. Următoarele operaŃii sunt dependente de tipul referinŃei la memorie: load sau store.

Page 23: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

33

În cazul instrucŃiunilor load, conŃinutul locaŃiei adresate în memorie va fi transferat prin intermediul registrelor MDR şi C în registrul destinaŃie Rd selectat de câmpul IR25 - 21 din codul instrucŃiunii. SecvenŃa completă va fi: MAR ← A + IR15-0 ; fixarea adresei de acces C ← MDR ; încărcarea datelor citite din memorie Rd ← C ; transferul datelor citite în Rd Un timp acoperitor trebuie să treacă (timpul de acces la memorie) din momentul încărcării adresei în MAR şi până la transferul datelor din MDR în C. Pentru instrucŃiunile store ne confruntăm cu o excepŃie: registrul sursă este specificat în câmpul destinaŃie al codului instrucŃiunii (IR25 - 21). O primă soluŃie ar fi ca în primul pas al fazei de execuŃie, simultan cu încărcarea registrelor A şi B, să fie încărcat şi registrul C cu conŃinutul registrului destinaŃie: A ← Rs1 , B ← Rs2 , C ← Rd

După acest prim pas conŃinutul registrului C va fi emis spre memorie prin intermediul registrului MDR. SecvenŃa completă pentru execuŃie va fi: MAR ← A + IR15-0 ; fixarea adresei de acces MDR ← C ; fixarea datelor de scris în memorie Acest principiu impune implementarea setului RG cu trei porturi de citire. O soluŃie alternativă, care păstrează adresa registrului sursă în câmpul destinaŃie al codului instrucŃiunii (IR25 - 21), constă în utilizarea unui hardware de redirectare atunci când este decodificată o instrucŃiune store. Acest hardware, activat pe durata fazei de execuŃie a instrucŃiunilor store, determină utilizarea registrului B în locul registrului C. SecvenŃa de operaŃii ce compun ciclul de execuŃie devine: A ← Rs1 , B ← Rd ; acŃionează hardware -ul de redirectare MAR ← A + IR15-0

MDR ← B ; acŃionează hardware -ul de redirectare În acord cu structura procesorului din figura 2.11., în ultimele două operaŃii (încărcarea adresei în MAR şi respectiv a datelor de scris în memorie în MDR), traseul datelor transferate trece prin ALU. Din acest motiv cele două operaŃii nu pot fi executate simultan. Dacă în structura procesorului s-ar implementa o cale de date directă între registrele B şi MDR atunci cele două transferuri ar fi putut fi simultane.

Page 24: CAP2.pdf

Proiectarea setului de instrucŃiuni

34

D. InstrucŃiunile de branch În faza de execuŃie a instrucŃiunilor de branch trebuie verificată condiŃia de salt specificată în instrucŃiune. Dacă condiŃia este adevărată, atunci se va calcula adresa de salt şi se va încărca în PC. CondiŃiile de salt, stabilite pe baza registrelor Rs1 şi Rs2 (vezi paragraful 2.2.4 C), pot fi verificate examinând rezultatul scăderii Rs1 - Rs2: condiŃie ← A <operaŃie> B Adresa de salt se calculează adunând offset-ul specificat în instrucŃiune (fig. 2.5.) la adresa curentă din PC: ALUR ← PC + IR15-0

Cu resurse hard suficiente, adresa de salt poate fi calculată simultan cu evaluarea condiŃiei de salt. Din păcate, calculul adresei de salt revendică ALU şi busurile de date interne. Acesta e motivul pentru care anumite procesoare RISC operează cu o singură condiŃie de branch, A = 0, care poate fi evaluată utilizând un hardware simplu şi rapid de detecŃie de zero. Pasul final din faza de execuŃie constă în încărcarea adresei de salt în PC dacă este îndeplinită condiŃia testată: IF CondiŃie=TRUE THEN PC ← ALUR

În caz contrar, încărcarea în PC se inhibă şi se va trece la următoarea instrucŃiune din secvenŃă. E. InstrucŃiunile de salt (jump) Realizează salturi necondiŃionate relative la PC prin simpla adunare a offset-ului specificat în instrucŃiune la conŃinutul registrului PC. Deoarece avem de-a face cu un offset pe 26 biŃi, va fi necesar un hardware de validare, activat pe durata execuŃiei instrucŃiunii JMP, şi care va valida transferul întregului offset (IR25 - 0) pe busul intern. În aceste condiŃii execuŃia devine: PC ← PC + IR25-0

Pentru instrucŃiunile jump cu adresare indirectă-registru, ca de exemplu JMP123[R4], secvenŃa de execuŃie va fi: PC ← A + IR15-0

Page 25: CAP2.pdf

ARHITECTURA SISTEMELOR DE CALCUL

35

Registrul specificat a fost încărcat în A în pasul anterior, iar offset-ul are doar 16 biŃi (fig.2.7.). InstrucŃiunea de apel procedură, JAL, este similară cu instrucŃiunea JMP; suplimentar JAL va încărca adresa de revenire în R31. ExecuŃia instrucŃiunii JAL va fi: R31 ← PC

PC ← PC + IR25-0

Deoarece registrul PC a fost incrementat deja în ciclul fetch instrucŃiune, în R31 se va încărca adresa instrucŃiunii ce urmează după JAL în secvenŃă. F. InstrucŃiunile de control Sunt instrucŃiuni cel mai adesea fără operanzi şi care specifică doar o operaŃie. InstrucŃiunea NOP (No OPeration) este prezentă în orice set de instrucŃiuni. Este utilizată la separarea dependenŃelor între instrucŃiuni (procesoare pipeline) şi la depanarea programelor când NOP înlocuieşte instrucŃiunile eliminate. Cel mai convenabil cod pentru NOP este zero (32 biŃi de 0) ceea ce înseamnă că o memorie iniŃializată cu zero va conŃine numai instrucŃiuni NOP. InstrucŃiunea HALT opreşte procesorul (inhibă semnalul de tact). Ieşirea din această stare de oprire se poate face, de regulă, numai printr-o întrerupere sau prin iniŃializarea procesorului (RESET).

Page 26: CAP2.pdf

Proiectarea setului de instrucŃiuni

36