Creeaza.com - informatii profesionale despre


Simplitatea lucrurilor complicate - Referate profesionale unice
Acasa » scoala » informatica » calculatoare
Redirectarea intreruperilor 8086

Redirectarea intreruperilor 8086


Redirectarea intreruperilor 8086

Notiuni generale

Sistemele 8086 poseda un numar de 256 de intreruperi. Fiecare intrerupere are asociata o rutina de cod numita Rutina de Tratare a Intreruperii (RTI), care se executa la aparitia intreruperii respective. Nu sunt definte toate cele 256 de intreruperi (nu exista rutine asociate cu toate cele 256 de intreruperi).

Marea majoritate a intreruperilor BIOS sunt initializate la pornirea sistemului. La incarcarea sistemului de operare, acesta defineste/redefineste, la randul sau unele intreruperi pentru a putea asigura serviciile sistem care ii sunt specifice (ex. DOS rescrie rutina asociata intreruperii 21h pentru a implementa serviciile specifice sistemului de operare DOS).

Rutinele unor intreruperi soft (BIOS si DOS) pot trata in mod diferentiat intreruperea generata in functie de o anumita valoare specificata intr-un registru. Spunem ca intreruperea respectiva ofera mai multe servicii sau functii.

Avand un numar limitat de intreruperi si un numar mare de rutine care trebuiesc implementate, sistemele si aplicatiile utilizator folosesc in general urmatoarea conventie:



La apel in registrul AH se va depune numarul functiei care se va folosi.

In restul registrilor se pun parametrii necesarii executiei functiei respective (a se vedea documentatia=>NG)

Rutina de tratare a intreruperii va verifica la fiecare apel numarul functiei care trebuie apelata si va preda controlul rutinei in cauza.

1. Redirectarea intreruperilor

Pentru memorarea punctelor de intrare a celor 256 de intreruperi sunt folosite adresele de memorie de la 0000h:0000h =>0000h : 0400h(exclusiv). Adresa unui handler de intrerupere este formata din:

Adresa de segment pe 16 biti

Offset pe 16 biti.

Asadar adresa unui handler de interupere are nevoie de 2*16 biti = 32 biti ( 2 cuvinte = 4 octeti ) pentru a putea fi memorata. Pentru a memora 256 de adrese este nevoie de 1024 octeti, adica exact spatiul de memorie de la adresa 0000:0000 pana la 0000:0400h.

Pentru a redirecta un handler de intrerupere este suficient sa memoram in locatia de memorie, unde ii este stocat punctul de intrare, adresa noului punct de intrare pentru handler-ul intreruperii respective.

Ex1:

Pentru a redirecta intreruperea 10h (functii video) cu un handler scris de noi se vor stoca la adresele:

0000:[4*10h+2] => Adresa Segment Nou handler

0000:[4*10h] => Offset-ul handler.

Imediat dupa memorarea adresei noului handler, controlul va fi transferat catre acesta de fiecare data cand se va genera un apel catre intreruperea 10h.

In general redirectarea unei intreruperi presupune:

Salvarea adresei vechiului handler intr-o zona de memorie.

Setarea adresei noului handler pentru intrerupere.

Sistemul DOS poseda doua functii care permit obtinerea adresei unui handler de intrerupere (vezi int 21h functia 35h), respectiv setarea unui nou vector de intrerupere (int 21h, functia 25h).

Ex2: Pentru recuperarea adresei handlerului intreruperii 10h si redirectarea lui spre un handler utilizator:

Addr_int10  dd ?

mov ah, 3510h

int 21h  ;intoarce in ES:BX adresa handler original

;salveaza adresa handler original

mov  word ptr [addr_int10+2], ES

mov word ptr [addr_int10], BX

;instaleaza noul handler de intrerupere

mov ax, 2510h

;se presupune ca noul handler este in segmentul de cod current. (rutina scrisa de utilizator)

mov ax, cs

mov ds, ax

mov dx, offset <handler>

int 21h

; noul handler de intrerupere este setat

Pentru a putea scrie un handler de intrerupere DOS care functioneaza corect este necesar sa stim urmatoarele:

Apelul unui handler de intrerupere poate sa apara in orice moment in executia unui program (mai ales atunci cand este vorba de intreruperi sistem cum ar fi intreruperea de timp 08h sau cea de tastatura 09h, etc). In consecinta este necesar ca acesta sa aiba o durata de executie cat mai scurta in timp pentru a nu jena executia  programului intrerupt. Deasemenea un handler nu trebuie sa corupa zonele de date si stiva programelor intrerupte.

Continutul registrilor trebuie pastrat (salvat) pentru a putea permite la terminarea handlerului reluarea normala a excutiei programului intrerupt.

La intrarea in rutina de tratare a handler-ului, stiva folosita este stiva programului intrerupt. Handlerul va folosi in consecinta stiva programului intrerupt. In cazul in care codul handlerului aloca mult spatiu de memorie in stiva este posibil sa depaseasca dimensiunea maxima a acesteia si sa corupa continutul stivei. Se va aloca o stiva proprie in acest caz.

Este nevoie sa luam in considerare cazul in care handlerul intreruperii este reapelat inca o data in timpul in care el se afla in tratarea unui eveniment anterior (trebuie scris astfel incat sa fie reentrant) => handlerul se intrerupe pe sine insusi. Este nevoie sa se salveze intregul context pentru a putea relua executia (variabilele locale specifice handler-ului).

Intreruperea 21h (functii DOS) nu este reentranta => daca un program este intrerupt in mijlocul unui apel al unei functii DOS si daca handler-ul nostru apeleaza la randul sau functii DOS, acest lucru va duce probabil la blocarea sistemului. Intreruperea 21h nu este reentranta datorita faptului ca foloseste o stiva statica proprie. Deci intreruperea unei functii DOS in curs de executie si apelarea unei alte functii DOS va duce la distrugerea continutului stivei pentru functia DOS intrerupta.


In cazul in care redirectarea unei intreruperi se face doar pentru a adauga functionalitate sau a modifica una din functiile intreruperii se va apela si handlerul original pentru tratarea cazurilor pe care handlerul nostru nu le ia in considerare.

La terminarea programului (in afara cazului in care acesta ramane rezident) este absolut necesara refacerea vectorilor de intrerupere modificati. In caz contrar sistemul de operare va apela in continuare handlerul a carui zona de memorie nu mai este alocata si care va fi cel mai probabil modificata la lansarea in executie a urmatorului program. Consecinta va fi inghetarea sistemului datorita transferului controlului executiei catre o locatie de memorie invalida.

;acest program redirecteaza functie 00H a intreruperii 2Fh

; Se redirecteaza intreruperea de fapt dar handlerul gestioneaza

; doar functia 00h. Restul functiilor sunt transmise handlerului original.

assume cs:cseg, ds:cseg

cseg segment

;adresa vechiului handler pentru intreruperea 2Fh

oldInt dd ?

;mesajul care se va afisa atunci cand se apeleaza functia 00H a intreruperii 2Fh

mesaj db 'Functia 00h a intreruperii 2Fh a fost redirectata',10,13,'$'

handler proc far

; inhiba intreruperile

cli

; testeaza daca functia apelata este functia 00h

cmp ah, 00h

; daca nu apeleaza handlerul original

jne orig

; Functia apelata este functia 00h

; salveaza pe stiva continutul registrilor ce

; vor fi eventual modificati

push ax

push bx

push dx

push ds

; pune in registrul ds adresa segementului de cod

; datele sunt stocate aici in segmentul de cod [OldInt si mesajul]

push cs

pop ds

; afiseaza mesaj folosind functia 09h a intreruperii 21h

mov ah, 09h

mov dx, offset mesaj

int 21h

; reface registrii modificati

pop ds

pop dx

pop bx

pop ax

sti

; intoarcere din handlerul intreruperii

iret

orig:

; apeleaza handlerul original printr-un apel far [seg]:[offset]

call dword ptr cs:[oldInt]

sti

; Return far. Nu folosim iret deoarece registrul de flag-uri

; a fost deja scos de pe stiva de handler-ul original

; prin iret. iret ar fi incorect aici deoarece ar mai realiza

; o operatie pop pt flag-uri de pe stiva, ori acestea nu mai

; exista pe stiva.

retf

handler endp

start:

mov ax, cseg

mov ds, ax

; obtine adresa handler-ului original al intreruperii

mov ax, 352Fh

int 21h

;salveaza adresa handler-ului original

mov word ptr [oldInt+2], es

mov word ptr [oldInt], bx

; inactiveaza intreruperile pe perioada modificarii adresei handlerului

cli

; seteaza noua adresa a handlerului intr. 2Fh

mov ax, 252Fh

mov dx, offset handler

;ds este setat deja pe cseg

int 21h

sti

; apel intrerupere 2Fh cu functia 00h Va fi apelat handler-ul nostru

mov ah, 00h

int 2Fh

; restaureaza handlerul original al intreruperii 2Fh

mov ax, 252Fh

mov dx, word ptr [oldInt]

mov bx, word ptr [oldInt+2]

mov ds, bx

int 21h

mov ax,4c00h

int 21h

cseg ends

end start

Lucrarea de laborator trebuie sa contina atit un nou handler de intrerupere cit si un program de test care sa apeleze intreruperea redirectata (daca este cazul).

La al saselea apel sa se refaca vechiul handler.

1. Sa se redirecteze intreruperea 15h. Noul handler va trebui sa verifice daca functia este 88h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'Nu exista memorie extinsa !'

2. Sa se redirecteze intreruperea 12h. Noul handler va trebui sa afiseze  mesajul 'Memoria disponibila este ' si apoi cantitatea de memorie disponibila in Ko.

3. Sa se redirecteze intreruperea 18h. Noul handler va trebui sa afiseze  mesajul 'Unde este interpretorul Basic ? '.

4. Sa se redirecteze intreruperea 08h. Noul handler va trebui sa afiseze  mesajul 'Intreruperea de ceas a fost redirectata !' de 3 ori pe secunda.

5. Sa se redirecteze intreruperea 1Ah. Noul handler va trebui sa verifice  daca functia este 00h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'S-a citit contorul de ceas !'

6. Sa se redirecteze intreruperea 1Ah. Noul handler va trebui sa verifice  daca functia este 01h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'A fost redirectata intreruperea 1Ah !'

7. Sa se redirecteze intreruperea 14h. Noul handler va trebui sa verifice  daca functia este 00h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 's-au initializat parametrii pentru COM1 !'

8. Sa se redirecteze intreruperea 14h. Noul handler va trebui sa verifice  daca functia este 03h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'A fost redirectata intreruperea 14h !'

9. Sa se redirecteze intreruperea 13h. Noul handler va trebui sa verifice  daca functia este 01h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'Discul curent este in starea :' si apoi mesajul corespunzator starii discului.

10.Sa se redirecteze intreruperea 13h. Noul handler va trebui sa verifice daca functia este 02h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'A fost redirectata intreruperea 13h !'

11.Sa se redirecteze intreruperea 17h. Noul handler va trebui sa afiseze  mesajul 'Imprimanta este in starea :' si apoi mesajul corespunzator starii imprimantei.

12.Sa se redirecteze intreruperea 10h. Noul handler va trebui sa verifice daca functia este 0Fh, daca nu sa se apeleze vechiul handler iar daca  da, sa afiseze mesajul 'Modul video curent este :' si apoi mesajul corespunzator.

13.Sa se redirecteze intreruperea 10h. Noul handler va trebui sa verifice  daca functia este 00h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'A fost redirectata intreruperea 10h !'

14.Sa se redirecteze intreruperea 10h. Noul handler va trebui sa verifice daca functia este 02h, daca nu sa se apeleze vechiul handler iar daca da, sa afiseze mesajul 'Pozitia cursorului a devenit' urmat de noua pozitie a cursorului.

15.Sa se redirecteze intreruperea 00h. Noul handler va trebui sa afiseze mesajul 'S-a redirectat intreruperea 00h'.





Politica de confidentialitate


creeaza logo.com Copyright © 2024 - Toate drepturile rezervate.
Toate documentele au caracter informativ cu scop educational.