|
Unul din marile avantaje ale unui calculator fata de orice alta masina creata de om este capacitatea sa de a raspunde la un numar mare de sarcini imprevizibile. Cheia acestor posibilitati o constituie ceea ce numim intreruperi.
Cu ajutorul acestora, calculatorul poate sa opreasca temporar o sarcina pe care o executa si sa comute pe o alta, ca raspuns la intreruperea intervenita (cum ar fi de exemplu apasarea unei taste sau primirea unor date pe place de retea). Acest mecanism face ca sistemul de calcul sa fie foarte flexibil, permitand raspunsul imediat la un eveniment extern, a carui tratare poate fi foarte urgenta, prin intreruperea sarcinii curente si reluarea acestei sarcini dupa ce s-au rezolvat cerintele impuse de intrerupere.
Notiunea de intrerupere presupune suspendarea programului in curs de executie si transferul controlului catre o anumita specializata, numita rutina de tratare a intreruperii. Mecanismul dupa care se face acest transfer este in esenta de tip apel de procedura, ceea ce inseamna ca se revine in programul intrerupt, din locul in care acesta a ramas, dupa ce s-a terminat rutina de tratare a intreruperii.
Clasificarea intreruperilor se poate face dupa mai multe criterii. O posibila clasificare este data in figura 1.
Fig. 1.
Intreruperile software apar in urma executiei de catre microprocesor a unor instructiuni cum ar fi INT, DIV, IDIV, fiind deci cauzate de catre software.
Intreruperile hardware interne apar ca urmare a unor situatii speciale in care se poate afla procesorul (cum ar fi executia pas cu pas in cazul depanarii programelor).
Intreruperile hardware externe sunt provocate de semnale electrice, care in ultima instanta sunt aplicate de catre dispozitivele periferice pe intrarile INT si NMI ale microprocesorului.
Intreruperile externe dezactivabile se aplica pe intrarea INT si sunt luate in considerare numai daca bistabilul IF (Interrupt Flag) din registrul indicatorilor de conditii are valoarea 1.
Intreruperile externe nedezactivabile au loc la aplicarea unui semnal corespunzator pe intrarea NMI (Non Maskable Interrupt) si sunt luate in considerare intotdeauna. Un exemplu pentru folosirea intrarii NMI este semnalizarea caderii tensiunii de alimentare.
Aceste intreruperi sunt controlate de unul (la PC original) sau mai multe circuite specializate (la AT si celelalte calculatoare), numite controlere de intreruperi, de tipul Intel 8259. Acest circuit are menirea de a culege cereri de intrerupere de la mai multe dispozitive, de a stabili o prioritate a cererilor (in cazul in care exista mai multe cereri de intrerupere simultane) si in final de a transmite un semnal de intrerupere pe pinul INT al microprocesorului si un semnal de identificare al dispozitivului periferic care a facut cererea.
Figura 2 ilustreaza schema de intreruperi a microprocesorului 80386 folosita in calculatoarele AT si urmatoarele. Observam modul de legare in cascada a controlerelor de intreruperi. La microprocesoarele anterioare (8086, 8088) era prezent un singur circuit 8259.
Fig. 2.
Daca la una din liniile IRQ0-IRQ15 (IRQ = Interrupt Request) se primeste o cerere de intrerupere de la un dispozitiv periferic (s-a apasat o tasta, trebuie sa se faca un ciclu de refresh al memoriei etc.), acest semnal este analizat de controlerul 8259 si in final acesta va genera o intrerupere pe linia INT catre microprocesor. Daca in microprocesor bistabilul IF are valoarea 1 (adica intreruperile hardware externe sunt activate), microprocesorul va trimite inapoi controlerului un semnal INTA (Interrupt Acknowlege - recunoastere intrerupere), prin care il anunta ca intreruperea este recunoscuta si acceptata. In continuare, controlerul de intrerupere va depune pe magistrala de date un octet special, numit octet type, care va identifica tipul (nivelul) intreruperii. Controlerul de intrerupere 8259 avand 8 intrari pentru intreruperi de la echipamente, va putea sa trimita 8 valori diferite, fiecare indentificand in mod unic una din cele 8 intrari. Se mai spune ca acest controler poate furniza 8 vectori de intrerupere, identificati prin octetul type, iar sistemul de intreruperi la microprocesoarele Intel este un sistem vectorizat.
Cum cu un octet (8 biti) se pot efectua 256 combinatii diferite, vor putea exista 256 valori diferite ale octetului type. Deci intr-un sistem pot exista maximum 256 nivele de intrerupere diferite. Pentru fiecare nivel (valoare a octetului type) se poate asocia o procedura (rutina sau subprogram) de deservire a intreruperii respective. Deci putem avea maximum 256 proceduri.
Adresele acestor rutine sunt trecute intr-o asa-numita tabela a vectorilor de intreruperi, care se afla in primii 1024 octeti ai memoriei RAM (primul Ko). Datorita faptului ca fiecare rutina de intrerupere se poate afla in alt segment, pentru a identifica adresa unei rutine trebuie sa-i furnizam adresa de segment (2 octeti) si adresa offsetului (inca 2 octeti), deci o adresa va ocupa 4 octeti. Cum sunt 256 intreruperi posibile, spatiul de memorie ocupat de tabela este 256 4 = 1024 = 1Ko. Se observa ca modul in care sunt memorate adresele (cu 2 octeti pentru offset) corespunde microprocesoarelor pe 16 biti, respectiv modului real al microprocesoarelor pe 32 biti. De altfel, orice microprocesor pe 32 biti intra in modul real la pornire (adica la punerea sub tensiune). Astfel, sistemul de intreruperi functioneaza in acelasi mod indiferent de tipul procesorului.
In figura 3 se da o reprezentare a modului in care este ocupata memoria sistemului cu tabela vectorilor de intreruperi. Amplasarea se realizeaza in functie de octetul type, care da nivelul de intrerupere.
Adrese
Octet type
0-3
0
4-7
1
1020-1023
255
Fig. 3.
Am vazut ca acest octet poate lua 256 valori diferite.
Valoarea octetului type inmultita cu 4 va furniza adresa din memorie unde se gaseste vectorul de intrerupere (adresa rutinei de intrerupere) pentru nivelul furnizat de octetul type.
Recapituland, la aparitia unei intreruperi in microprocesor au loc urmatoarele actiuni:
- se salveaza in stiva registrii (E)FLAGS, CS si (E)IP, in aceasta ordine
- se sterg bistabilii IF si TF (adica se blocheaza executia altei intreruperi in timpul executiei programului pentru intreruperea in curs, iar TF blocheaza executia pas cu pas a rutinei de intrerupere)
- se furnizeaza microprocesorului un octet (8 biti in gama 0-255), numit si octet type, care identifica nivelul asociat intreruperii
- se executa un salt la adresa de inceput a rutinei de tratare a intreruperii (folosind tabela vectorilor de intrerupere), de unde se incepe executia rutinei corespunzatoare de tratare a intreruperii
Fiecare componenta a calculatorului care poate sa aiba nevoie de microprocesor la un moment dat are propriul sau nivel de intrerupere. Tastatura, ceasul intern, unitatile de disc, imprimantele, placa de retea etc., toate acestea au fiecare un nivel de intrerupere rezervat. La apasarea unei taste se genereaza intreruperea de tastatura, la fiecare 55 milisecunde se genereaza intreruperea de ceas, a carei rutina de tratare actualizeaza ceasul intern, discul trimite o intrerupere cand este terminat un transfer iar imprimanta cand nu are hartie, placa de retea cand primeste un pachet de date adresat ei s.a.m.d. Deci observam ca activitatea microprocesorului se desfasoara intr-o permanenta posibilitate de a fi 'intrerupta' de altcineva, care are mai mare nevoie de microprocesor decat aplicatia ce ruleaza.
Interesant este ca intreruperile nu au facut parte din conceptul primelor calculatoare. La inceput calculatoarele au fost folosite fara acest mecanism. Astazi este greu de imaginat un calculator fara sistem de intreruperi implementat in cadrul sau hardware si software.
Conceptul de intrerupere s-a dovedit atat de eficient si util, incat a fost adaptat la o mare varietate de alte necesitati ale calculatorului. Pe langa intreruperile hardware, despre care tocmai am vorbit, exista si intreruperi care sunt generate chiar in interiorul CPU, ca urmare a faptului ca s-a intamplat ceva ce nu are sens - de exemplu s-a incercat o impartire la zero. In acest caz se genereaza o intrerupere interna, numita si exceptie.
Aceasta categorie de intreruperi nu apare pe neasteptate, precum cele hardware descrise anterior. Ideea care sta la baza intreruperilor a fost extinsa astfel incat acestea (intreruperile) sa fie utilizate si de catre programe, pentru a solicita servicii executate de alte programe din calculator. Intreruperile de acest tip se numesc intreruperi software. Dupa cum am vazut, atunci cand se construieste un calculator exista un set de programe interne integrate intr-o memorie ROM (Read Only Memory), care formeaza asa-numitul BIOS. Daca programele de aplicatii au nevoie de functii oferite de BIOS, modul de apelare a acestora il constituie intreruperile software.
Serviciile BIOS sunt puse la dispozitia programului de aplicatie prin executia unei instructiuni de intrerupere software de tipul INT n, unde n reprezinta nivelul de intrerupere solicitat. Intreruperile software functioneaza la fel ca si celelalte tipuri de intrerupere, cu o singura diferenta: ele nu sunt declansate de un eveniment neasteptat sau aleatoriu, ci sunt produse intentionat de catre program cu un anumit scop.
Sistemele de operare folosesc de asemenea intreruperi software pentru apelul unor functii necesare derularii programelor de aplicatie sub controlul sau direct. Aceste functii ale BIOS sau ale sistemului de operare, apelate prin intermediul intreruperilor, sunt tratate de catre procesor ca subprograme care, dupa ce se termina, redau controlul programului apelant. Programul care face apel la o asemenea functie nu are nevoie sa cunoasca adresa de memorie a rutinei corespunzatoare, ci este suficient sa indice numarul intreruperii alocate acelei functii si eventual parametrii auxiliari, necesari functiei. Aceste intreruperi sunt standardizate de catre BIOS si respectiv de catre sistemul de operare.
Vom mai face cateva observatii asupra modului de functionare a intreruperilor intr-un calculator.
Ultima instructiune dintr-o rutina de intreruperi este instructiunea IRET (Interrupt Return) care are rolul de a restaura in ordine inversa ceea ce a fost salvat in stiva, adica (E)IP, CS si registrul (E)Flags, redand controlul programului principal.
Daca rutina de intreruperi lucreaza cu registrii procesorului si distruge valorile continute in acestea, revine in grija programatorului ca aceste valori sa fie salvate explicit in stiva, prin instructiuni de tip PUSH, la inceputul rutinei de tratare a intreruperii, iar la sfarsit, inainte de terminare, sa fie refacuti acesti registri prin instructiuni POP corespunzatoare. Astfel, programul care a fost intrerupt isi reia lucrul cu valorile care erau in registrii procesorului la momentul intreruperii sale.
Dupa cum am vazut, imediat ce s-a declansat o intrerupere indicatorul IF este trecut pe 0, ceea ce inseamna ca intreruperile hard care pot surveni din acel moment sunt dezactivate. De aceea este indicat sa se utilizeze cat mai repede posibil o instructiune de tip STI (Set Interrupt) care activeaza din nou sistemul de intreruperi - bineinteles, daca programul rutinei de intrerupere nu executa o portiune in care nu are voie sa fie intrerupta.
Tabela vectorilor de intreruperi, dupa cum am vazut, este plasata in memoria RAM (deci cea in care se poate sterge si inscrie alta valoare). Aceasta face ca adresele rezervate in tabela pentru desemnarea rutinelor de tratare a intreruperilor sa poata fi schimbate chiar de unele programe si eventual utilizatorii sa-si scrie propriile programe pentru tratarea unor intreruperi. Aceasta poarta de intrare in sistemul de operare prin intermediul intreruperilor este folosita si de unele programe rauvoitoare cum ar fi virusii, caii troieni etc. De obicei aceste programe 'fura' o intrerupere, adica isi introduc in tabela de intrerupere, in locul adresei normale de pana atunci, propria lor adresa de inceput. La declansarea normala a intreruperii respective se lanseaza acest program 'pirat', care poate realiza diverse actiuni distructive - ceea ce poate avea un efect catastrofal asupra integritatii datelor in calculator. Pe cat de puternic este sistemul de intreruperi in activitatea unui pocesor, pe atat de mare poate fi pericolul folosirii necorespunzatoare a acestuia de catre programe rau intentionate.
Sistemele de operare mai noi (Windows, Linux, OS/2) limiteaza accesul la partea de hardware tocmai din aceasta cauza. Programele de aplicatie nu mai pot accesa hardware-ul in mod direct, ci numai prin intremediul sistemului de operare, care blocheaza astfel un eventual apel rau intentionat, asigurand astfel un mai mare grad de siguranta.