Din secretele "creierului" calculatorului
MICROPROCESOAREMihai ScorțaruStructura internă a microprocesoarelorMicroprocesorul este o unitate centrală de prelucrare (Central Processing Unit - CPU) încorporată într-o capsulă de circuit integrat, el fiind coordonatorul tuturor operațiilor efectuate de către calculator. Are rolul de a citi instrucțiunile dintr-o zonă de memorie, de a decodifica și executa comenzile corespunzătoare. Pentru ca microprocesorul să poată citi codul instrucțiunii care urmează a fi decodificată și executată, el trebuie să genereze o adresă care va fi păstrată în memorie până când din celula selectată pe baza acestei adrese va putea fi citită data cerută. Pentru a putea fi memorată starea liniilor de adresă în timpul operației de citire, microprocesorul are nevoie de o memorie intermediară numită registru tampon de adrese (Address Buffer - AB). Informația codificată care a fost citită, trebuie și ea depusă într-un registru intermediar, numit registru tampon de date (Data Buffer - DB). Traseele de cupru cu ajutorul cărora se va genera informația binară care reprezintă o adresă se numesc magistrală de adrese (Address BUS - ABUS), iar cele care vor genera informații corespunzătoare datelor citite sau scrise în memorie poartă denumirea de magistrală de date (Data BUS - DBUS). Pentru a putea efectua diferite calcule aritmetice și logice, microprocesorul are nevoie de o unitate aritmetică și logică (Arithmetic and Logic Unit - ALU). Pentru a putea fi executată o anumită instrucțiune procesorul conține și o unitate de comandă (Command Unit - CU). Această componentă programează execuția secvențială în timp a tuturor manevrelor necesare pentru a putea executa instrucțiunea; ea generează semnalele de comandă pentru întregul sistem, dirijează fluxul de date, corelează viteza de lucru a unității centrale cu timpul de acces al memoriei etc. Activitatea sa este "pilotată" de un semnal de ceas a cărui frecvență (deocamdată) este de ordinul Mhz-ilor. Semnalele prin care microprocesorul dă comenzi de execuție spre memorie sau spre alte componente ale sistemului poartă denumirea de semnale de comandă. Semnalele prin care microprocesorul primește informații despre diferite componente ale sistemului se numesc semnale de stare. Traseele de cupru pe care circulă aceste semnale formează magistrala de comenzi (Command BUS - CBUS). În cazul în care o instrucțiune folosește date care au rezultat în urma execuției instrucțiunii precedente atunci aceste date ar trebui citite din nou din memorie. Pentru a evita acest acces suplimentar la memorie, microprocesorul este prevăzut cu regiștri, în care pot fi păstrate temporar date sau adrese de memorie. Microprocesorul mai are nevoie de un registru special în care să poată fi generată și păstrată nealterată adresa de memorie a următoarei instrucțiuni care trebuie executată. Acest registru se numește instrucțiune program (Instruction Program - IP) sau contor de program (Program Counter - PC). Mai există încă un registru special în care sunt păstrate informații referitoare la natura rezultatului unei operații aritmetice. Biții care compun acest registru se numesc indicatori de stare, iar registrul poartă denumirea de registrul indicatorilor de stare și control. Vor exista biți corespunzători diferitelor stări ale rezultatului cum ar fi: număr par sau impar, negativ sau pozitiv, nul sau nenul etc. Pe lângă magistralele externe care sunt folosite pentru "comunicarea" dintre procesor și celelalte componente ale sistemului, microprocesorul este prevăzut și cu o magistrală internă de date, necesară pentru efectuarea unor transferuri interne de date. La magistralele de date și de comenzi pot fi cuplate circuite de intrare/ieșire (Input/Output - I/O) care realizează legătura cu exteriorul. Lățimea unei magistrale reprezintă numărul de trasee de cupru care o compun. Numărul de locații de memorie care pot fi adresate direct de procesor depinde de lățimea magistralei de adrese, de exemplu o magistrală de adrese care conține 20 de trasee permite adresarea a 220 celule de memorie. Pentru a se executa o instrucțiune, au loc următoarele evenimente: microprocesorul depune pe magistrala de date valoarea din registrul IP și depune pe magistrala de comenzi comanda citește din memorie; memoria internă preia de pe magistrala de date valoarea N care a fost stocată în registrul IP, caută adresa N, preia valoarea I conținută în această locație, depune pe magistrala de date valoarea I și pe magistrala de comenzi comanda am terminat citirea; după ce recepționează această comandă, microprocesorul citește de pe magistrala de date valoarea I și execută instrucțiunea codificată prin această valoare; valoarea din registrul IP este incrementată cu o unitate (devine N+1). Valoarea registrului IP poate fi modificată de una din instrucțiunile unui program, dispărând astfel monotonia cauzată de incrementarea cu o unitate. O astfel de instrucțiune ar putea fi scade valoarea k din valoarea registrului IP. Efectul acestei instrucțiuni este întoarcerea cu k instrucțiuni înainte și repetarea lor în alt context (valorile datelor vor fi altele). Toate activitățile calculatorului sunt coordonate de către pulsurile unui oscilator numit ceas intern. După cum am văzut, execuția unei instrucțiuni constă din execuția mai multor etape parțiale. Fiecare astfel de etapă parțială este efectuată în intervalul dintre două pulsuri de ceas, astfel că intervalul de timp necesar execuției unei instrucțiuni poate fi măsurat cu ajutorul numărului de pulsuri de ceas. Structura unui microprocesor IntelÎn continuare ne vom ocupa în principal de microprocesoarele 8086 și 8088, acestea fiind denumite de cărțile de specialitate microprocesoare convenționale. Ori de câte ori vom face referire la un alt microprocesor îi vom indica numele. Microprocesoarele 8086 și 8088 au o structură pe 16 biți, deosebirea esențială dintre ele constând în faptul că 8088 este proiectat cu o magistrală de date externă de 8 biți, în timp ce 8086 dispune de una de 16 biți. Aceasta înseamnă că pot fi transferați pe magistrala de date externă 8, respectiv 16 biți deodată. Din motive comerciale, Intel a păstrat compatibilitatea cu microprocesoarele apărute anterior, ceea ce înseamnă că orice program care funcționează cu un anumit microprocesor va funcționa și cu orice alt microprocesor apărut ulterior. Microprocesorul Intel are două componente majore: unitatea de interfață cu magistrala (Bus Interface Unit - BIU) și unitatea de execuție (Executive Unit - EU). Unitatea de interfață cu magistrala transmite procesorului instrucțiuni și operanzi și rezultatele unor prelucrări spre memoria internă sau dispozitivele de intrare/ieșire. Principalele componente ale sale sunt regiștrii de segment, registrul pointer de instrucțiuni, dispozitivul de adresare și coada fluxului de instrucțiuni. Unitatea de execuție are rolul de a executa instrucțiunile care îi sunt transmise de către BIU. Principalele sale componente sunt regiștrii generali, registrul de manevră pentru memorarea operanzilor, unitatea aritmetico-logică (ALU) și registrul indicatorilor de stare și control. Magistralele cu ajutorul cărora se realizează comunicarea dintre microprocesor și celelalte componente ale sistemului de calcul sunt: magistrala de date (pe 16 biți), magistrala de adresă (pe 20 de biți) și magistrala de comenzi. Sistemul de întreruperiMicroprocesorul mai dispune de două linii pentru semnalele de întrerupere emise de dispozitivele externe: linia INTR (Interrupt Request) și linia NMI (Non-Maskable Interrupt). Pe linia INTR sosesc întreruperi în urma cărora unitatea centrală, în funcție de valoarea indicatorului de validare a întreruperilor (IF), execută diferite operații. Dacă IF este șters (are valoarea 0) înseamnă că întreruperile semnalate pe linia INTR sunt mascate sau dezactivate, ca urmare unitatea centrală le ignoră și trece la instrucțiunea următoare. Dacă IF este poziționat (are valoarea 1) înseamnă că întreruperile de pe linia INTR sunt activate și unitatea centrală oprește execuția normală a instrucțiunilor și predă controlul rutinei de tratare a întreruperilor. NMI este o linie prin care sosesc întreruperi care anunță evenimente critice. Aceste întreruperi nu pot fi dezactivate și unitatea centrală le va lua în considerare de fiecare dată când acestea sosesc. Sistemul de întreruperi este simplu și ușor de manevrat. Pot fi utilizate cel mult 256 de tipuri de întrerupere, fiecărui tip fiindu-i atribuit un cod specific. Întreruperile pot fi clasificate în întreruperi externe și întreruperi interne. Cele externe sunt numite și întreruperi hardware, iar cele interne mai poartă denumirea de întreruperi software. Diferența esențială dintre cele două tipuri de întreruperi este că cele externe sunt cauzate de dispozitivele externe, iar cele interne sunt generate prin program, folosindu-se anumite instrucțiuni. Tabela vectorilor de întrerupereTabela vectorilor de întrerupere permite asocierea dintre tipul întreruperii (reprezentat de un număr între 0 și 255) și rutina de tratare a întreruperii. Fiecare intrare a tabelei ocupă 4 bytes, ea conținând adresa rutinei de tratare a întreruperii. Tabela ocupă prima zonă a memoriei interne și poate avea până la 256 de intrări. La apariția unei întreruperi este suspendată execuția instrucțiunilor programului curent și sunt salvate pe stivă registrul cu indicatorii de stare și control și adresa instrucțiunii următoare; apoi este activată rutina de tratare a întreruperii. Unitatea aritmetică și logicăPentru efectuarea operațiilor aritmetice procesorul are nevoie de circuite specializate în acest sens. În aritmetica binară operațiile aritmetice pot fi descrise cu ajutorul unor funcții logice, de aceea este normal ca circuitele respective să fie utilizate și pentru operațiile logice propriu-zise. Aceste circuite utilizate de procesor pentru efectuarea operațiilor aritmetice și logice poartă denumirea de unitate aritmetică și logică. ALU face parte din unitatea de execuție a microprocesorului, ea având și rolul de a gestiona indicatorii de stare și control ai microprocesorului și de a manevra regiștrii generali și operanzii instrucțiunilor. Regiștrii și căile de date interne sunt de 16 biți, deoarece se dorește mărirea transferurilor interne. Coada de instrucțiuniUnitatea de execuție nu are nici o legătură cu magistrala sistemului, cea care efectuează toate operațiile necesare cu magistrala fiind unitatea de interfață cu magistrala. În timpul în care unitatea de execuție se ocupă cu execuția instrucțiunilor, unitatea de interfață cu magistrala încarcă instrucțiunile într-o memorie specială de tip RAM (Random Acces Memory) numită coada fluxului de instrucțiuni. Această memorie are o dimensiune de 4 bytes în cazul microprocesoarelor 8088 și 6 bytes în cazul 8086. Unitatea de execuție preia câte o instrucțiune din coada fluxului de instrucțiuni; apoi o execută. În majoritatea cazurilor coada fluxului de instrucțiuni conține cel puțin un byte al fluxului de instrucțiuni și unitatea de execuție nu mai trebuie să aștepte încărcarea instrucțiunii care urmează a fi executată. La un moment dat în coada fluxului de instrucțiuni sunt memorate instrucțiunile care se află în locațiile de memorie imediat următoare locației de memorie în care se află instrucțiunea care se execută la acel moment. Dacă este executată o instrucțiune care transferă controlul unei locații de memorie, coada fluxului de instrucțiuni este ștearsă, se încarcă instrucțiunea de la noua adresă și unitatea de interfață cu magistrala începe reîncărcarea cozii fluxului de instrucțiuni cu instrucțiunile următoare. Dispozitivul de adresareMicroprocesorul trebuie să poată adresa atât instrucțiunile cît și datele de care instrucțiunile au nevoie atunci când sunt executate. Adresa locației de memorie din care se va încărca o instrucțiune este suma dintre o adresă de segment și un deplasament. Pentru adresarea datelor, microprocesorul oferă câteva modalități de adresare. Segmentarea memoriei Microprocesoarele 8086 și 8088 pot adresa 1 MB de memorie care sunt grupați în mai multe segmente. Un segment de memorie este o unitate logică de memorie care poate avea cel mult 64 KB. Fiecare segment de memorie este alcătuit din mai multe locații de memorie consecutive și poate fi considerat ca o unitate care poate fi adresată independent. Fiecare segment este caracterizat printr-o adresă de bază care reprezintă adresa locației de început a segmentului și este exprimată în număr de blocuri de 16 bytes, numite paragrafe. Ca urmare, toate segmentele încep de la o adresă care este un multiplu de 16. Două segmente se numesc adiacente dacă adresa de început a unuia dintre ele este cu 1 mai mare decât adresa de sfârșit a celuilalt. Două segmente sunt parțial suprapuse dacă adresa de început a unuia se află între adresa de început și cea de sfârșit a celuilalt. Două segmente sunt suprapuse complet dacă adresele lor de început coincid. În toate celelalte cazuri segmentele se numesc disjuncte. În funcție de necesități o anumită aplicație (program) utilizează segmentele în mod diferit. Segmentele care pot fi adresate în mod curent oferă 64 KB pentru cod, 64 KB pentru stivă și 64 KB pentru date. Pentru a utiliza un spațiu de lucru mai mare, trebuie gestionate segmentele de memorie în funcție de necesități. Adrese fizice și adrese logice Adresa fizică este o valoare reprezentată pe 20 de biți care identifică în mod unic fiecare locație de memorie aflată în spațiul de adresare. Ca urmare această adresă poate fi un număr cuprins între 0 și 220-1. Pentru a nu depinde de locul în care este păstrat codul în memorie, programele folosesc adresele logice în locul celor fizice. Adresa logică este dată de o valoare de bază de segment și o valoare de deplasament. Valoarea de bază a segmentului indică adresa primului byte al segmentului care conține locația și este exprimată în paragrafe. Deplasamentul reprezintă numărul de octeți dintre locația respectivă și începutul segmentului. Atât adresa de bază cât și deplasamentul sunt reprezentate pe 16 biți. Este posibil ca mai multe adrese logice să localizeze o aceeași locație de memorie atunci când aceasta face parte din segmente diferite. De exemplu adresele logice F000:FFF0 și FFFF:0000 indică aceeași locație de memorie și anume cea care are adresa fizică FFFF0. Generarea adresei fizice cu ajutorul adresei logice se realizează înmulțind cu 16 valoarea bazei segmentului (shiftare spre stânga cu 4 poziții) și adăugând deplasamentul. Mecanisme de adresare Calculele de adresă sunt efectuate de unitatea de interfață cu magistrala, cu ajutorul unei unități de calcul, specifice, numită ADR și a unor regiștri speciali fiecare având o capacitate de 16 biți. Primele generații de calculatoare aveau o memorie de 1 MB. Primele 10 blocuri de memorie (640 KB) formează memoria RAM, următoarele 5 fiind folosite pentru memoria ecran și reținerea conținutului memoriei ROM în timpul funcționării sistemului. Pentru a putea codifica în mod unic fiecare din cele 220 de locații de memorie diferite, o adresă trebuie să fie reprezentată pe 20 de biți. Magistrala de adrese are capacitatea necesară pentru a transmite cei 20 de biți deodată, însă nu se poate spune același lucru despre magistrala de date care are o capacitate de 16 biți. Prin convenție adresa de început a fiecărui segment este un multiplu de 16, iar un segment poate avea cel mult 64 KB. Datorită acestui fapt cei mai nesemnificativi 4 bytes ai adresei de început a segmentului vor fi 0 (în baza 2 un multiplu de 16 are ultimele 4 cifre întotdeauna 0). Din acest motiv acești 4 biți nu mai trebuie memorați și ca urmare regiștrii de segment vor conține numai restul celor 16 biți. Pentru a specifica deplasamentul (offset) sunt folosiți tot 16 biți. O adresă virtuală este compusă din două numere reprezentate fiecare pe 16 biți, unul reprezentând conținutul registrului de segment, iar al doilea deplasamentul în cadrul segmentului. Adresa fizică este calculată de către BIU înmulțind cu 16 primul număr și adunând la rezultat cel de-al doilea număr. Mecanismul descris este tipic pentru procesorul 8086 și poartă denumirea de mod real (Real Adress Mode). La microprocesoarele 80286 apare încă un mod de adresare, denumit mod protejat (Protected Virtual Address Mode), iar o dată cu apariția procesorului 80386 sunt introduse modul paginat și modul virtual 8086. Aceste noi modalități de adresare au fost introduse pentru a permite adresarea de către un calculator IBM-PC a mai mult de 1 MB de memorie. Implementarea stivei Stiva este o zonă de memorie folosită pentru a stoca datele temporare. Deosebirea esențială dintre stive și alte segmente de memorie este faptul că datele de pe stivă sunt stocate începând de la adresele mai mari de memorie și continuând spre adrese mai mici. La început stiva este un segment de memorie neinițializat care are o dimensiune fixă. În timp ce sunt adăugate informații în stivă dimensiunea stivei "crește" de la adresele mari spre adresele mai mici, iar când sunt eliminate informații, stiva se "micșorează" în sens invers. Numărul de stive este limitat numai de spațiul de memorie disponibil în sistem, iar dimensiunea unei stive nu poate depăși 64 KB. Dacă se extinde stiva peste această dimensiune, informațiile adăugate vor înlocui informațiile de la începutul stivei. La un moment dat nu poate fi adresată direct decât o stivă, ea purtând denumirea de stivă curentă. RegiștriRegiștrii microprocesoarelor 8086 și 8088 sunt în număr de 14, au fiecare câte 16 biți și pot fi împărțiți în următoarele categorii: regiștrii generali, regiștrii de segment, registrul pointerului de instrucțiuni și registrul indicatorului de stare și control.
Microprocesorul 80386 utilizează aceiași regiștri ca și predecesorii săi din familia 8086, dar toți regiștrii (cu excepția celor de segment) pot fi extinse până la 32 de biți. Denumirea regiștrilor extinși începe cu litera E și ei se numesc EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI și EIP). Au fost adăugate și doi regiștri de segment suplimentari FS și GS. IndicatoriCei 16 biți ai registrului indicatorilor de stare și control poartă denumirea de indicatori (denumire sugerată și de numele registrului) sau flaguri. Cuvântul englezesc flag este tradus în limba română prin steag. Denumirea sugerează faptul că un anumit steguleț va fi ridicat în cazul în care o condiție este îndeplinită. Mai multe instrucțiuni permit modificarea execuției unui program în funcție de cei șase indicatori de stare.
Acești biți indicatori de stare sunt poziționați de către unitatea de execuție. Indicatorii de control permit controlarea unor operații ale microprocesorului și ei pot fi modificați prin program.
O dată cu apariția microprocesorului 80486 au apărut încă 7 indicatori de stare și control: indicatorul AC permite generarea unui semnal de eroare în cazul în care apar date incorect aliniate; indicatorul PG arată dacă paginarea este activă sau nu; indicatorul CE este folosit pentru conectarea memoriei cache; indicatorul WT este folosit pentru validarea și invalidarea scrierii în memoria cache; indicatorul WE controlează dacă la coprocesor apare o excepție datorată vectorului de întrerupere 2h sau 16h (numerele terminate în h indică faptul că ele sunt scrise în sistem hexazecimal - baza 16; numărul 16h poate fi scris ca 22 dacă se folosește sistemul zecimal); indicatorul TS este setat în cazul în care este lansat un task; indicatorul EM arată dacă instrucțiunile ESC sunt preluate sau transmise mai departe la coprocesor. PromisiuniÎn numărul următor al "Gazetei de Informatică" veți putea afla mai multe despre instrucțiunile microprocesorului, despre reprezentarea lor în cod mașină și despre instrucțiunile limbajului de asamblare. Mihai Scorțaru este student la Universitatea Tehnică din Cluj. Poate fi contactat prin e-mail la adresa: scort@licj.soroscj.ro [cuprins] |