Sistemul de operare MS-DOS este monotasking, ceea ce inseamna ca un singur program poate rula la un moment dat. Totusi, sistemul permite ca in memorie
sa ramina mai multe programe(TSR), care urmeaza a fi activate la producerea unui eveniment extern, de obicei provenind de la tastatura. Astfel, cu toate ca la un moment dat se executa instructiunile unui singur program, se face o comutare rapida de la un program la altul. Utilitarul PRINT.COM, de exemplu, realizeaza tiparirea (in "backround") in timp ce in DOS putem executa un program
(programul in prim plan-"foreground"). In acest caz cele doua programe se executa
simultan, in aparenta. Pentru realizarea aparentei de simultaneitate PRINT se acorda cu transele de timp (time-slices) din timpul executiei programului din prim plan. l3c12ct
Acest lucru este posibil intrucit de 18 ori pe secunda, un program este intrerupt, iar partea rezidenta a comenzii PRINT este activata in perioadele de intrerupere.
Acest principiu il folosesc si programele TSR.
Scrierea de programe rezidente sigure nu este o treaba tocmai usoara, si in plus apare problema utilitatii unui astfel de program. De exemplu, putem concepe un TSR care sa afiseze la activare caracterele ASCII cu codurile corespunzatoare, sau sa realizam un screen saver, si ideile pot merge mai departe, crescind complexitatea aplicatiei.
Doua programe, ambele parind a se executa simultan, nu sint niciodata executate in paralel sub MS-DOS. Acestea sint transate in bucati mai mici care sint executate una dupa alta. Viteza de executie si trecerea de la unul la altul
(context switching) sint astfel alese incit sa apara senzatia de simultaneitate.
Exista totusi facilitati pentru a asigura existenta unui rudiment de multitasking.
Evident sistemul de operare este capabil sa inceapa executia cite unui program.
Aceste programe, numite rezidente vor "coexista" in memoria urtilizator,
iar la producerea unui eveniment acestea vor putea fi activate. Datorita unui astfel
de mecanism exista posibilitatea ca in timpul executiei unui program sa fie activat, executat si incheiat un TSR sau o succesiune de astfel de programe.
In principiu un "TSR" este un program activat si lansat in executie
de anumite evenimente specifice si care la terminare ramin rezidente in memoria
volatila (RAM) a sistemului. Astfel de evenimente pot fi : apasarea unei taste, scurgerea unui interval de timp, un semnal pe interfata seriala. Cind evenimentul asteptat a aparut, programul rezident va prelua controlul. Daca in acel moment se executa un program oarecare, acesta va fi intrerupt. Functiile de sistem
BIOS sint nereentrante, la fel si multe din functiile de sistem DOS. Functiile nereentrante folosesc de obicei date statice, care la un nou apel (mai inainte ca vechiul
apel sa se fi terminat), ar fi distruse (vom reveni).
O regula elementara pe care trebuie sa o satisfaca mecanismul unui astfel de program este aceea ca nu trebuie sa afecteze executia corecta a altor programe, inclusiv cele de tip "TSR" existente deja. Un program "TSR"
se scrie la fel ca toate celelalte, dar la sfirsitul executiei trebuie sa-si manifeste propria
dorinta de a ramine in memorie. Pentru aceasta ultima instructiune executata trebuie
sa fie apelul functiei DOS Fn 31h.
Conflicte intre programe.
Ideea de interventie in sistemul de intreruperi pentru emularea unui sistem multitasking e interesanta dar, in practica, trebuie respectate anumite reguli, pentru a nu compromite functionarea generala a masinii.
Atunci cind DOS foloseste programe ca PRINT.COM el nu face apel decit la situatii foarte simple si fara riscuri.
Programele si notiunile legate de ele
In memorie gasim:
-codul intreruperilor
-zonele de date
-programul in curs
Acest program este dependent de o serie de parametri in legatura cu registrii
procesorului, memorie, anumite variabile ale DOS. Se urmareste incarcarea in
memorie a mai multor programe si trecerea de la unul la altul avind in vedere mai multe conditii:
-ar trebui sa "suspendam" executia unui program pentru a executa
un altul
(rezident)
-ar trebui sa revenim la vechi program fara daune
Parasirea primului program este in legatura cu sistemul de intreruperi.
Este clar ca toate programele apeleaza intreruperile, sau sint intrerupte de
altele
(apeluri ce nu sint in legatura cu programul in curs). Daca in al doilea program redirijam intreruperile, primul va executa instructiunile celui de-al doilea program. Un program cuprinde : instructiuni, zona de date, zona de stiva. Fiecare
din cele trei elemente e situat intr-un segment de memorie, segment reperat
de cite un registru al microprocesorului (CS,DS,SS,IP).
Trebuie salvat CS:IP pentru a memora (in stiva) instructiunea primului program la care trebuie sa revenim. Inainte de terminarea programului rezident e importanta restaurarea registrilor (CS:IP) pentru predarea controlului primului program. Daca CS:IP nu au fost scosi din stiva, sistemul va efectua instructiunile de la aceasta adresa , ceea ce va duce la blocaj.
O proasta gestiune a stivei implica probleme ca :
-saturarea stivei (depunerea in stiva a mai multor elemente decit e posibil)
-distrugerea stivei (este antrenata distrugerea valorilor deja existente).
Un subprogram sau o intrerupere care doreste folosirea stivei va trebui :
-sa prezerve SS si SP si sa restabileasca stiva originala inainte de sfirsit
-sa modifice SS si SP caci ei pointeaza la stiva interna
Nereentranta sistemului de operare MS-DOS
MS-DOS este un sistem mono-task si in consecinta , acesta nu poate raspunde la un moment dat decit la o singura cerere de serviciu DOS. Un "TSR" poate fi activat de un eveniment extern in orice moment. Exista posibilitatea
ca
DOS , in acest moment sa execute o functie sistem (de exemplu deschiderea unui fisier de catre programul aflat in executie). In momentul tratarii unei functii de intrerupere INT 21H . MS-DOS-ul salveaza variabilele de lucru nu in stiva programului, ci intr-o zona numita "stiva interna". Mai precis, in
una din cele trei stive interne corespunzatoare functiei tratate:
-o stiva pentru functiile de la 1 la 0CH (aceste functii sint in legatura
cu afisajul si cu tastatura)
-o stiva pentru tratarea tuturor celorlalte functii
-o ultima stiva (auxiliara) pentru tratarea erorilor critice
Deci vor aparea probleme daca "TSR" reclama servicii DOS , deoarece
aceasta a doua cerere va distruge zona de lucru. Trebuie atentie ca la activarea "TSR", serviciul DOS din programul principal sa-si fi incheiat rutina de tratare.
Solutii oferite pentru realizarea unui "TSR"
**Cum un program rezident poate sti daca o functie a sistemului este in curs de executie.
O prima solutie ar consta in examinarea unei variabile (IN_DOS) pusa de DOS pe 1 daca se executa una din functiile de intrerupere INT 21H (o valoare
0 inseamna ca nu este accesat nici un serviciu DOS). Functia Fn DOS 34 returneaza adresa acestei variabile in ES:BX.
Toate aceste informatii nu sint documentate oficial. Multe din aplicatiile reale si de mare succes pe piata (MS-DOS-ul s-a impus si prin aceste aplicatii), se bazeaza pe aceasta informatie. Microsoft este obligata sa suporte toate consecintele (altfel spus nu poate schimba nici functia si nici semnificatia acestei variabile in toate versiunile de DOS compatibile).
Intr-o functie de intrerupere va trebui sa testam acest indicator.
Daca aceasta variabila este zero (DOS-ul este pe nivel 0 de apel servicii) vom putea "fara grija" sa lansam o operatie mai sofisticata cu apeluri
DOS.
Din nefericire lucrurile nu sint chiar asa de simple deoarece :
-in cazul erorilor grave (de exemplu citirea unei dischete sau o eroare de paritate pe disc), aceasta variabila ia valoarea 0 (DOS nu este inca pregatit sa primeasca o noua cerere)
-daca sintem in modul linie de comanda (COMMAND.COM in starea de asteptare, stare care poate dura destul de mult) variabila IN_DOS ia valoarea 1, iar
DOS-ul poate accepta in aceste conditii sa execute anumite functii.
Revenim la prima situatie. In cazul erorilor grave, DOS-ul repune pe zero variabila IN_DOS si pozitioneaza pe unu o alta variabila numita
DOS_CRITICAL_ERROR. Dupa versiunea 3.1 a MS-DOS-ului acest indicator se gaseste in caracterul imediat urmator variabilei IN_DOS. O alta modalitate de a gasi
aceasta variabila este apelul functiei Fn DOS 5D06H (returneaza adresa variabilei).
Daca IN_DOS este pozitionat pe 1, un program rezident nu poate apela o functie DOS. Ne vom gasi in aceeasi situatie daca IN_DOS va fi 0, iar
DOS_CRITICAL_ERROR va fi diferita de 0 .
In cel de-al doilea caz, in modul linie de comanda, sistemul se gaseste sub controlul direct al interpretorului de comenzi. Pentru citirea caracterelor introduse de la tastatura, COMMAND.COM-ul apeleaza functia
Fn DOS 0AH ,ceea ce este materializat de sistem prin pozitionarea mereu a variabilei
IN_DOS pe 1. In acest moment DOS-ul lucreaza pe prima sa stiva interna. Astfel, putem apela, fara nici o retinere, orice functie DOS al carei numar este mai mare de Fn DOS 0CH (acest serviciu de sistem utilizeaza stiva normala).
Cum se poate sesiza si materializa existenta unei astfel de situatii?
Prima solutie ar fi interceptarea intreruperii INT 21h , verificind permanent continutul registrului AH si in ai mentine valoarea intr-o variabila proprie
"TSR"-ului .
O alta solutie consta in a intercepta intreruperea INT 28h (numita DOS
IDLE INTERRUPT). Partea din DOS care trateaza functia Fn 0AH genereaza cu regularitate o intrerupere INT 28h. Aceasta intrerupere poate fi utilizata pentru ca in tratarea sa sa se activeze programul "TSR" .
Altfel spus : variabila IN_DOS este pe 1 dar o functie DOS cu numar mai mare ca Fn DOS 0CH poate fi apelata .
Totusi trebuie luat in considerare faptul ca un "TSR" nu trebuie sa
perturbe programul din prim plan . Pentru aceasta trebuie luate niste precautii :
-o prima regula consta in a nu intrerupe nici o operatie cu discul (exceptie facind o operatie de foarte scurta durata, gen intrerupere de ceas sau tastatura)
Exista momente de timp la care in sistem se executa operatii critice din punct de vedere al timpului de executie. O astfel de operatie este si cea cu discul care odata initiata trebuie terminata intr-un timp bine determinat. In general operatiile cu discul (prin intermediul intreruperii INT 13h,sint lansate de
DOS folosind o functie INT 21h. Dar nimic nu interzice unui program sa intercepteze
INT 13h si sa notam intr-o variabila globala daca o intrerupere INT 13h este in curs de executie.
-activarea, executia si terminarea unui "TSR" trebuie sa se faca fara
nici o modificare in contextul sistemului de operare. In executia programului "TSR" trebuie sa se faca o salvare a vechiului continut al stivei programului care a fost intrerupt, deoarece acest program poate fi chiar sistemul de operare.
Aceasta salvare este necesara pentru ca DOS foloseste stive proprii aflate la adrese fixe.
-in cazul in care in "TSR"" se realizeaza apelul la o functie
DOS se va distru ge vechiul continut al stivei DOS, ceea ce va impiedica rularea corecta a opera tiilor intrerupte la activarea "TSR"-ului.
-un rezident acceseaza deseori un fisier. Pentru fiecare fisier deschis DOS-ul asociaza un numar pe care il salveaza in PSP-ul programului. In caz de activare a unui rezident, DOS-ul, daca nu se iau masuri, continua sa acceseze PSP-ul
pro gramului ce se executa in prim plan. Adresa PSP-ului este considerata ca un
in dicator al programului in curs de executie. Inainte de a utiliza o functie de
gestiune fisier, trebuie sa comutam acest indicator pe PSP-ul "TSR".
Acest lu cru trebuie sa se faca deoarece DOS ar salva numarul asociat fisierului accesat in PSP-programului aflat in prim plan.
-evident "TSR"-ul are obligativitatea ca la sfirsitul executiei sale
sa resta bileasca indicatorul de proces modificat.
-o ultima precautie : un program rezident foloseste stiva programului intrerupt.
Daca aceasta este supradimensionata nu vor apare probleme. Cazurile de blocaj prin depasirea capacitatii stivei se vor evita prin bascularea pe o stiva inter na proprie "TSR"-ului.
Schema de program rezident
Atit din punctul de vedere al utilizatorului, cit si al programatorului, se pot pune in evidenta patru etape majore ce privesc un program TSR:
1. Instalarea
2. Activarea
3. Executia
4. Dezinstalarea
Un program rezident TSR contine doua parti : una rezidenta si cealalta nonreziden ta. In partea programului ce va ramine rezidenta in memorie va trebui sa dezvoltam urmatoarele proceduri:
-detectarea evenimentului extern
-test al stabilitatii sistemului
-activarea
-returul la program
Partea non-rezidenta a programului e consacrata pregatirii si instalarii programului in memorie. Va trebui sa programam:
-verificarea ca programul nu este deja instalat in memorie
-salvarea adresei PSP-ului, a DTA-ului, a flagului IN_DOS si a registri lor de segment
-salvarea adreselor intreruperilor modificate
-instalarea intreruperilor noastre
-instalarea in mod rezident
Procedura de activare a programului rezident contine : modificarea contextului, apelul rezidentului, refacere context :
-modificarea registrilor de segment
-bascularea la stiva proprie si salvarea celei a DOS-ului
-salvarea adresei PSP, DTA
-instalarea propriului PSP, DTA
-salvarea adreselor si instalarea intreruperilor noastre
Returul la program contine :
-restaurare registri segment
-restaurare stiva, PSP, DTA
-restaurare intreruperi
Distingem urmatoarele 3 module:
1. Nucleu de instalare rezidenta
-Verifica daca programul a mai fost instalat in memorie
-daca da-*exit.
-daca nu-*corupe vectorii
*il face rezident
2. Nucleu de lansare rezidenta
-Testeaza conditia de activare
-Testeaza conditiile DOS
3. Executia propriu-zisa
-disable interrupts
-"TSR"activ (pozitioneaza un flag pe 1)
-salveaza stiva DOS
-salveaza toti registrii
-salveaza DTA, PSP
-pozitioneaza PSP,DTA
-salvare ecran
-actiunea propriu-zisa
-reface contextul.
Reluam concret toate fazele :
INSTALAREA
Daca programul a fost deja instalat in memorie, nu are nici un sens sa-l mai instalam inca o data, si nu trebue permisa o noua instalare. Pentru a veri fica daca programul este sau nu rezident, se redirecteaza INT 2FH, care ofera un standard pentru scrierea programelor rezidente. La iesirea din INT 2fh,AL=0 daca programul nu este instalat si AL=0ffh daca programul este deja rezident.
Pentru a lasa programul rezident, se foloseste functia DOS 31h, ocupind memorie suficienta atit pentru TSR, cit si pentru programul care se va lansa in activare (in DX, nr. de paragrafe necesar). Inainte de apelul acestei functii, este necesar sa determinam adresa PSP-ului programului TSR, pentru a plasa la activare environment-ul TSR-ului programului ce se va lansa, si pentru a actualiza
(tot la activare) adresa PSP-ului curent (aceasta e considerata un indicator
al procesului in curs de executie). In continuare, cind spunem "adresa PSP-ului", ne referim la adresa de segment a acestuia.
ACTIVAREA
Chiar daca evenimentul de tastatura asteptat s-a produs, activarea progra mului nu trebuie sa se faca in orice conditii. In primul rind, activarea se face numai daca modul de afisare curent este alfanumeric, pentru a putea salva usor continutul memoriei ecran.
Datorita faptului ca MS-DOS nu este reentrant, se face activarea programu lui numai daca nu este in executie o functie DOS. Functia DOS 34h permite obti nerea in ES:BX a adresei variabilei IN_DOS, care indica nivelul de apeluri de functii DOS. Daca variabila are valoarea 0 , nu exista un apel de functie
DOS in executie.
INT 28h este utilizata pentru a realiza activarea progranului TSR , chiar daca variabila IN_DOS are o valoare mai mare decit 1. Evident, activarea se face daca exista o cerere de activare care nu a putut fi satisfacuta.
Activarea programului nu trebuie sa se faca in timp ce sistemul de operare este in cursul tratarii unei erori critice. Apelul functiei Fn DOS 5Dh, subfunctia
6 (in AL se incarca codul de subfunctie 6), permite obtinerea in ES:BX a adre sei variabilei DOS_CRITICAL_ERROR, care are o valoare diferita de 0 daca sistemul trateaza o eroare critica.
Programul gestioneaza un indicator IN_BIOS, pentru a nu permite activarea sa in momentele in care tocmai se executa INT 05H, 09H, 10H, 13H. Imediat dupa apel incrementeaza o variabila publica, executa procedura originala, dupa care
decrementeaza variabila. In momentul activarii, daca acea varibila este pozitiva, inseamna ca tocmai se executa o procedura BIOS, deci nu ar fi indicata executia programului TSR. Oricum, se constata practic ca nu este necesara gestionarea activitatilor BIOS, daca respectam sectiunile de cod critice (functiile 8700H
si
8701H ale INT 2AH,vezi exemplul de mai jos).
Mai trebuie tinut cont si de intrruperile hardware active in momentul executiei programului TSR: controllerul programabil de intreruperi (PIC 8259A)
nu permite decit tratarea secventiala a intreruperilor, deci cind se activeaza programul TSR trebuie sa cunoastem ce intreruperi hard sunt active si eventual sa trimitem un semnal de EOI (end of interrupt), astfel incit sa permitem continuarea normala a activitatii lui 8259A.
Intrucit programul rezident lanseaza la activare un alt program in executie (care poate efectua operatii cu discul,etc) este necesara parcurgerea urmatorilor pasi:
-salvarea adresei PSP-ului programului intrerupt
-salvarea adresei zonei de transfer a discului(DTA) curente
-actualizarea adresei PSP-ului curent comunicand DOS-ului ca procesul activ (in curs de executie) este programul TSR
-se seteaza adresa zonei DTA la un buffer local
Dupa ce programul lansat si-a incheiat executia, se fac urmatoarele operatii:
-actualizarea adresei PSP-ului curent, comunicand DOS-ului ca procesul activ este programul intrerupt
-se reface adresa zonei DTA, cu valoarea salvata
Aflarea adresei PSP-ului programului intrerupt se face apeland functia
Fn DOS 62H (in BX se obtine adresa PSP-ului). Pentru aflarea adresei PSP-ului programului TSR se apeleaza aceasta functie inainte de a lasa programul rezident prin apelul functiei Fn DOS 31H (KEEP).
Actualizarea adresei PSP-ului curent se face cu ajutorul functiei Fn DOS 50H
(BX va trebui sa contina adresa noului PSP).
Salvarea adresei zonei DTA se face apeland functia Fn DOS 2fH (in ES:BX se obtine adresa), iar modificarea adresei DTA se face cu functia Fn DOS 1AH
(DS:DX trebuie sa contina noua adresa).
Ca o ultima cerinta, in executia programului TSR trebuie sa se faca o salvare a continutului stivei programului intrerupt (64 cuvinte), deoarece acest program poate sa fie chiar sistemul de operare. Aceasta salvare este necesara, pentru ca un eventual apel de functie DOS va distruge continutul stivei DOS, ceea ce va impiedica reluarea corecta a operatiilor intrerupte la activarea programului TSR.
EXECUTIA
Inainte de lansarea in executie a programului specificat, se face o salvare a ecranului, a pozitiei cursorului si a starii driverului de mouse. Dupa incheierea executiei se revine la starea initiala.
DEZINSTALAREA
Daca s-a manifestat o cerere de dezinstalare ea trebuie satisfacuta numai in cazul in care intreruperile redirecteaza flag-urile apoi registrii CS si
IP, in aceasta ordine.
1. Se seteaza pe zero flag-urile T(trap) si I(interrupt).
2. Se identifica adresa subrutinei de tratare a intreruperii. In acest scop, fiecare intrerupere are asociat un numar, intre 0 si
255, numit tip. Acesta este folosit ca si un index in tabloul vectorilor de intreruperi. Fiecare pozitie din acest tablou contine adresa de tratare a unei intreruperi.
3. Se incarca in CS,IP adresa subrutinei din pozitia corespunza -toare a tabloului vectorilor de intrerupere. Se executa rutina de tratare a intreruperii pina la intilnirea instructiunii IRET.
4. Se revine din intrerupere prin scoaterea de pe stiva a primelor trei cuvinte care se incarca in IP,CS si flag-uri in aceasta ordine. Inaintea apelului vechii intreruperi, ordinea Flaguri-Seg -ment-Offset se transforma in Segment-Offset-Flaguri. Apelind vechea intrerupere cu Call, dupa executia acesteia vor ramine pe stiva numai doua cuvinte, si anume Segment-Offset. Terminind noua intrerupere cu RET, totul e ok. Aceasta metoda, are marele avantaj ca ne elibereaza de sarcina gestionarii flag-urilor, stiut fiind ca anumite intreruperi returneaza prin intermediul acestora anumite informatii care nu trebuie sa se piarda.
Exemplu :
Ca o exemplificare acelor de mai sus, se prezinta un program TSR (t1.c) care se activeaza odata la cca 1 minut,si afiseaza mesajul "Hello,world"
pe ecran.
Programul este stabil, cu toate ca foloseste pentru afisare functia printf(),
(cei care au incercat sa programeze TSR-uri in C stiu ce inseamna).
Procedura myproc() poate fi extinsa cu functii de acces la fisiere sau orice alte functii DOS sau BIOS.
Programul poate fi completat cu handler-e pentru CTRL-C, CTRL-BREAK si pentru erori critice (intreruperile 1BH,23H,24H). Altfel, se poate intimpla
ca programul intrerupt sa se trezeasca tratind o exceptie de care nu este responsabil.
Pentru a oferi un mijloc de comunicatie cu alte programe sau cu copii ale lui insusi in program ar trebui tratata si intreruperea 2FH.
Este foarte important ca programul dat ca exemplu sa fie compilat cu modelul tiny, pentru ca functia keep() sa primeasca dimensiunea corecta a partii rezidente de program. In alte modele, trebuie avute in vedere repartitia de memorie a segmentelor de cod, date si stiva,specifica fiecarui model de memorie.
/*********************** T1.C *****************************************/
#pragma -mt // tiny model
#include <dos.h>
#include <stdio.h>
#define INTR 0x1C //intreruperea de ceas extern unsigned _heaplen=1024; extern unsigned _stklen =1024; void interrupt(* oldtimer)();
//prototipul vechii proceduri de tratare a intr. 1CH unsigned int (far *dosflag); //steagul de reentranta DOS int myPSP; //PSP al programului rezident unsigned myDTAs,myDTAo; //DTA (offset si segment) al prog. rezident unsigned oldSS,oldSP; // stiva progr. interupt unsigned mySP; //indicator stiva al programului rezident union REGS reg; //pentru apelul int86() struct SREGS segreg; //pentru apelul int86x() int inTimer =0; //este 1 cind suntem in procedura timer() int contor =0; //masoara intervalele de timp
/* procedura myproc() este apelata o data pe minut; o putem adapta unor scopuri specifice */ void myproc()
A printf("\n\r Hello,world!\n\r");
S
/* procedura timer() trateza intreruperea 1CH,care executa de 18.2 ori pe secunda*/ void interrupt timer()
A unsigned hisPSP; // pastreza PSP al progr intrerupt unsigned hisDTAo,hisDTAs; //pastreaza DTA al progr intrerupt int res;
oldtimer(); //intii executa procedura originala if(contor) contor--; //masoara intervalul de timp else if(!inTimer) //ca sa evitam reentranta
A inTimer++; reg.x.ax=0x8700; //informez DOS ca incep sectiunea critica int86(0x2A,®,®); if(!reg.x.cflag)
A outp(0x20,0x0B); //verif. intreruperi hard active res=inp(0x20); if(!(res & 0xFE) && !(dosflaga0i & 0xff))
A outp(0x20,0x20) ; //reset controller 8259A
//inlocuim stiva prog. intrerupt cu stiva proprie asm cli; oldSS=_SS; oldSP=_SP;
_SS=_CS; if(oldSS !=_CS) //daca nu se executa
_SP=mySP; // acest program asm sti;
reg.h.ah=0x62; //salvez PSP al prog. intrerupt int86(0x21,®,®); hisPSP=reg.x.bx;
reg.h.ah=0x2f; //salvez DTA al prog. intrerupt int86x(0x21,®,®,&segreg); hisDTAo=reg.x.bx; hisDTAs=segreg.es;
reg.h.ah=0x50; // pun PSP al prog. rezident reg.x.bx=myPSP; int86(0x21,®,®);
asm push ds reg.h.ah=0x1a; // pun DTA al prog. rezident reg.x.dx=myDTAo; segreg.ds=myDTAs; int86x(0x21,®,®,&segreg); asm pop ds
myproc(); // execut actiunea reg.h.ah=0x50; //restaurez PSP original reg.x.bx=hisPSP; int86(0x21,®,®);
asm push ds reg.h.ah=0x1a; //restaurez DTA original reg.x.dx=hisDTAo; segreg.ds=hisDTAs; int86x(0x21,®,®,&segreg); asm pop ds
asm cli;
_SS=oldSS; // restaurez stiva originala
_SP=oldSP; asm sti; contor= 1080; // armez contor de timp
reg.x.ax=0x8701; //sfarsit sectiune critica int86(0x2A,®,®);
S inTimer--;
S
S
S
/*procedura main() -instaleaza procedura de intrerupere timer() si termina rezident */
int main(void)
A reg.h.ah=0x34; // aflam adresa steag reentranta DOS int86x(0x21,®,®,&segreg); dosflag=(unsigned far *) MK_FP(segreg.es, reg.x.bx); oldtimer=getvect(INTR); //preia intreruperea de timp setvect(INTR,timer); reg.h.ah=0x62; //citeste PSP propriu int86(0x21,®,®); myPSP=reg.x.bx; reg.h.ah=0x2f; //citeste DTA propriu int86x(0x21, ®, ®, &segreg); myDTAo=reg.x.bx; myDTAs=segreg.es; asm cli; mySP=_SP; //citeste indicator de stiva proprie asm sti; keep(0,(_SS + ((_SP+160)/16) -_psp)); return 0;
S
/*******************************************************************/
Exercitii :
-descrieti fazele realizarii unui program rezident TSR
-care sunt constringerile in realizarea unui TSR
-care sint posibilitatile de implementare a unui TSR
-modificati exemplul dat astfel ca sa realizati un screen-saver
-modificati t1.c astfel ca sa afiseze la apasarea unor taste informatii tip SYSINFO despre sistem
-studiati programul t2.asm si prezentati functiile sale si modul de realizare