|
|
səhifə | 44/55 | tarix | 07.05.2018 | ölçüsü | 4,6 Mb. | | #50260 |
| EXEMPLU: #include
#include
int x;
main()
{ for (x=1;x<15;x++)
{ printf("INT=%d Intrerupere= %x \n",x,getvect());
sleep(1);
};
}
FUNCTIA getverify()
-returneaza statusul pentru steguletul de verificare al sistemului
SINTAXA GENERALA este: int getverify(void);
Functia returneaza o valoare int care indica statusul steguletului de
verificare al sistemului.Steguletul controleaza introducerea de date pe
disc.Daca steguletul este OFF,scrierea pe disc se poate face fara verifi-
care,iar daca steguletul este ON,orice introducere de date va fi verifi-
cata pentru a se asigura ca datele sunt in format corect.
Functia returneaza 0 daca steguletul este setat OFF sau 1 daca este ON.
Steguletul este de fapt un registru de procesor reprezentat prin un tampon
de memorie,iar la unele sisteme de operare este reprezentat si grafic,sub
forma de stegulet de avertizare (de unde si numele).
EXEMPLU: #include
#include
main()
{
if (getverify())
printf("Steguletul de avertizare DOS este ON ! \n");
else
printf("Steguletul de avertizare este OFF ! \n");
sleep(3);
}
In etapa actuala,functia a pierdut din interes,deoarece scrierea pe disc
a datelor se face exclusiv cu programe care verifica automat formatul de
scriere al datelor.Functia poate fi utilizata in continuare,atunci cand
se utilizeaza conversii de date de la un format la altul,sau atunci cand
datele sunt introduse pe disc de catre copii si incepatori.Atentie,rese-
tarea repetata a registrilor,poate genera erori ale memoriei RAM.
-333- [ dos.h -harderr() ]
FUNCTIA harderr() si _harderr() [in versiunea C++]
-determina o eroare de hardware in programul curent
SINTAXA GENERALA este: void harderr(int (far *handler)());
Functia determina o eroare de hardware si invoca apoi codul de manipulare
a erorii(handler),ori de cate ori se apeleaza intreruperea 0x24 (vezi DOS)
La orice intrerupere 0x24,handler va apela functia spre care pointeaza.
Functia va fi apelata cu urmatoarele argumente:
void far handler(unsigned deverr,unsigned errval,unsigned far *devhdr);
unde:
-deverr este codul de eroare al unitatii(transferat de DOS in registrul AX)
-errval este valoarea erorii(codul)(transferat de DOS in registrul DI)
-devhdr este un pointer far spre capul de citire al unitatii care a cauzat
eroarea (transferat de DOS in perechea de registrii BP:SI)
Functia utilizeaza aceste argumente in loc sa apeleze direct registrii din
CPU (unitatea centrala de procesare)(pentru a evita confuziile).
Daca exista o eroare de disc,deverr returneaza 0 in bitul 15 din byte,iar
in caz contrar,eroarea nu a fost generata de catre discul de memorie.
Daca exista o unitate de disc,offset-ul 0x00FF din deverr va indica unita-
tea de disc care a generat eroarea prin 0=A,1=B,2=C...etc.
Functia pointata de handler nu este apelata direct,ci prin intermediul
unei intreruperi DOS care apeleaza functia.Se poate utiliza orice apel DOS
intre 1 si 0xC,restul apelurilor vor corupe sistemul DOS.In mod expres,nu
pot fi apelate functiile standard C de I/O sau UNIX-emulat de I/O.
Functia handler nu returneaza nici o valoare (doar argumentele de mai sus)
si trebuie parasita utilizand functiile hardretn() sau hardresume().
Functia harderr() nu returneaza nici o valoare (nu este depanabila).
Nu se recomanda utilizarea functiei,decat de catre profesionisti,deoarece
riscati sa corupeti iremediabil sistemul de operare.Pentru orice eroare
de hardware este indicat sa apelati la un specialist.
EXEMPLU: #include
#include
int drive,eroare,nr;
unsigned deverr,errval,*devhdr;
int cod(deverr,errval,devhdr)
{ drive=deverr & 0x00FF;
eroare=errval & 0x00FF;
nr=devhdr;
hardresume(1);
hardretn(2);
};
main()
{ harderr(cod);
printf("Unitatea cu eroare este: %u \n",drive);
printf("Eroarea este: %u \n",eroare);
printf("codul de tratare a erorii este: %u \n",cod);
sleep(3);
}
Functia se poate utiliza pentru programe de revizie si depanare automata,
sau pentru a verifica daca exista o discheta in unitatea floppy,etc.Nu
incercati sa aplicati functia,decat daca cunoasteti in amanuntime sistemul
de operare DOS sub care apelati functia (pot exista diferente de versiune)
-334- [hardresume(),hardretn() si inp() ]
FUNCTIA hardresume() si [_hardresume() in C++ ]
-revine in DOS dupa un apel harderr()
SINTAXA GENERALA este: void hardresume(int rescode);
Dupa stabilirea erorii de hard prin harderr(),revenirea in sistemul DOS
se poate face cu hardresume().Valoarea returnata de functie poate contine
una dintre urmatoarele valori:
HARDERR_ABORT -paraseste programul invocand intreruperea DOS 0x23
HARDERR_IGNORE -ignora eroarea
HARDERR_RETRY -repeta operatia
HARDERR_FAIL -operatia nu a reusit
Functia nu returneaza valori si nu returneaza la apelant.
EXEMPLU: vezi harderr()
FUNCTIA hardretn()
-returneaza eroarea stabilita prin harderr() direct in aplicatie
SINTAXA GENERALA este: void hardretn(int retn);
Functia se utilizeaza pentru a returna direct in aplicatia care a facut
apelul harderr(),rezultatul apelarii functiei (revine din functia handle
direct in aplicatie,in timp ce hardresume() returneaza in DOS).
Daca functia DOS care a cauzat eroarea este mai mica decat 0x38 si este o
functie care poate indica tipul de eroare,atunci functia hardretn() va
returna in aplicatie setand registrul AL la 0xFF.Daca functia DOS este mai
mica decat 0x38,argumentul functiei (retn) va fi ignorat.
Daca functia DOS este egala sau mai mare cu 0x38,argumentul retn va fi
setat la valoarea codului de eroare si va fi returnat in aplicatie prin
setarea registrului AX la valoarea respectiva (retn).Deasemenea se va
seta si registrul falg (stegulet),pentru a semnaliza ca aplicata respec-
tiva a generat o eroare de hardware.
Functia nu returneaza valori.
EXEMPLU: vezi harderr()
FUNCTIA inp()
-citeste un byte de la un port hardware
SINTAXA GENERALA este: int inp(int portid);
Functia citeste un byte de la un port hardware(de comunicatie,I/O etc.)
Functia lucreaza ca o instructiune 8086 IN.
Functia returneaza valoarea citita.
EXEMPLU: #include
#include
int port;
int rezultat;
main()
{
port=1;
outport(1,77);
rezultat=inp(port);
printf("Byte citit= 0x%X \n",rezultat);
sleep(3); };
Se utilizeaza mai ales pentru comunicatia cu alte unitati de procesare
sau cu unitati externe de prelucrare a datelor si pentru operatiile de
intrare/iesire a datelor (I/O) etc.
-335- [ inport() inportb() si int86() ]
FUNCTIA inport()
-citeste un cuvant (2 bytes) din portul hardware
SINTAXA GENERALA este: int inport(int portid);
Functia este identica cu intructiunea 8086 IN.Citeste un cuvnat din portul
specificat prin portid,dupa cum urmeaza:-primul byte(low byte=inferior)
din portul specificat prin portid iar cel de al doilea byte(high byte=su-
perior) din portul portid+1.
Functia returneaza valoarea citita (valoarea int a caracterului ASCII).
EXEMPLU: #include
#include
int port;
int rezultat;
main()
{ port=1;
outport(1,'ab');
rezultat=inport(port);
printf("Cuvant citit = 0x%X \n",rezultat);
sleep(3);
}
Observati ca valoarea pentru a (62) apare in bitul cel mai semnificativ,
iar pentru b (61) apare in bitul mai putin semnificativ(Last In First Out)
FUNCTIA inportb()
-citeste un byte din portul hardware
SINTAXA GENERALA este: unsigned char inportb(int portid);
Functia este un macro si citeste un byte din portul hardware specificat
prin portid.Daca doriti sa fie citita ca o functie simpla,puteti fie sa nu
includeti fila la preprocesare sau sa anulati definitia cu #undef
inportb(). In unele versiuni,inp() este asimilata (identica) cu inportb().
Functia returneaza valoarea citita.
EXEMPLU: #include
#include
int port;
unsigned char rezultat;
main()
{ port=1;
outport(port,65);
rezultat=inportb(port);
printf("Byte citit = %c \n",rezultat);
sleep(3);
}
FUNCTIA int86()
-intrerupere software 8086
SINTAXA GENERALA este:
int int86(int intno,union REGS *inregs,union REGS *outregs);
Functia executa o intrerupere software 8086 de tipul celei specificate
prin intno(orice intrerupere 8086).Inainte de a executa intreruperea,
functia copiaza valorile din inregs in registri iar dupa executarea intre-
ruperii (functiei DOS) copiaza valorile curente din registri procesorului
in outregs si statusul registrului carry flag in x.cflag.
-336- [ dos.h - int86x() ]
Atat pentru inregs cat si pentru outregs se vor utiliza uniuni de tip
REGS (vezi tipuri de date definite in ),eventual se va putea uti-
liza aceeasi uniune de tip REGS in care datele se actualizeaza la fiecare
intrerupere(se declara un singur pointer).
Functia returneaza valoarea finala a registrului AX,dupa executarea intre-
ruperii specificate.Daca intervine o eroare,carry flag va fi setata la o
valoare diferita de zero si se va seta variabila _doserrno la un cod de
eroare (care poate fi apelat pentru depanare).De remarcat faptul ca pot
exista si erori care nu seteaza carry flag,dar care seteaza variabila
_doserrno.
EXEMPLU: #include
#include
#include
union REGS reg1;
int x,y,z;
movetoxy(x,y)
( reg1.h.ah=2;
reg1.h.dh=y;
reg1.h.dl=x;
reg1.h.bh=0;
int86(0x10,®1,®1);
}
main()
{ clrscr();
for (z=10;z<21;z++)
{ movetoxy(35,z);
printf("Hello ! \n");
sleep(1);
};
}
FUNCTIA int86x()
-interfata pentru intrerupere generala 8086
SINTAXA GENERALA este:
int int86x(int intno,union REGS *inregs,union REGS *outregs,struct *segr);
Functia este similara cu int86,dar in plus fata de aceasta utilizeaza si
o structura de tip SREGS,specificata prin segr in care copiaza si regstrii
pentru segmente ds si es inainte de a executa intreruperea.Prin aceasta
operatie suplimentara,programul poate utiliza si pointeri far,pentru a
indica (in cazul versiunilor de program cu memorie extinsa) segmentul de
memorie care urmeaza sa fie utilizata pentru executarea intreruperii.
Dupa executarea intreruperii,copiaza registrii in outregs,carry flag si
in plus reseteaza registii de segment DS si ES la valorile corespunzatoare
Functia se deosebeste de int86() prin faptul ca permite apelarea unei
intreruperi software 8086 care utilizeaza o valoare DS diferita de cea
a segmentului implicit,si/sau poate accepta argumente in ES (adica poate
utiliza memoria extinsa pentru executarea intreruperii).
Functia returneaza valoarea finala a registrului AX (dupa intrerupere).
In caz de eroare,functia seteaza carry flag si _doserrno,la fel ca si
int86().
EXEMPLU: vezi int86() (eventual incercati sa apelati memoria extinsa)
-337- [ dos.h-intdos() si intdosx() ]
FUNCTIA intdos()
-este interfata pentru o intrerupere generala DOS
SINTAXA GENERALA este: int intdos(union REGS *inregs,union REGS *outregs);
Functia executa o intrerupere DOS 0x21 pentru a apela functia DOS speci-
ficata(cea arhivata in uniunea inregs de tip REGS,in membrul h.ah).
Dupa revenirea din inreruperea de tip DOS 0x21,functia copiaza valorile
actuale ale registrilor in uniunea outregs (tot de tip REGS) si respectiv
copiaza si registrul flags(x.cflag) in membrul x.flags.In caz ca x.cflag
este setat pozitiv,indica faptul ca a intervenit o eroare.
Se poate utiliza aceeasi uniune,pentru ambele argumente ale functiei(atat
pentru inregs cat si pentru outregs),caz in care datele vor fi actualizate
la fiecare apel al functiei.
Functia returneaza valoarea finala a registrului AX (dupa efectuarea in-
treruperii si salvarea registrilor).Daca steguletul de avertizare carry
flag a fost setat la o valoare oarecare,indica o eroare,care seteaza si
variabila globala _doserrno.Nu toate erorile seteaza si registrul flag,
atfel incat este posibil sa existe erori si atunci cand steguletul de
avertizare nu este setat (pentru control verificati variabila errno).
Tipul de data REGS este declarat in fila de antet (vezi REGS).
EXEMPLU: #include
#include
#include
union REGS reg1;
char x,y;
main()
{ x='a';
reg1.h.ah=0x10;
reg1.h.dh=y;
reg1.h.dl=x;
reg1.h.bh=0;
intdos(®1,®1);
printf("%c \n",reg1.h.dl);
sleep(3);
}
In exercitiu,functia apeleaza 0x10 (registrul ah) pentru a citi datele din
registri.Pentru a mentine valoarea citita puteti declara si utiliza si
o a doua uniune de tip REGS (de exemplu reg2).
FUNCTIA intdosx()
-interfata pentru o intrerupere generala de tip DOS.
SINTAXA GENERALA este:
int intdosx(union REGS *inregs,union REGS *outregs,struct SREGS *segregs);
Functia executa o intrerupere de tip 0x21 pentru a apela o functie DOS.
Functia DOS apelata este cea specificata in uniunea inregs in membrul h.ah
Functia este identica cu intdos,cu deosebirea ca utilizeaza si o structura
de tip SREGS in care arhiveaza registrii pentru segmente si apoi reseteaza
registrul DS.Dupa executarea intreruperii,copiaza registrii si carry flag
in uniunea outregs (la fel ca intdos() ).
Functia intdosx() este utila in versiunile de program cu memorie extinsa,
deoarece permite apelarea unor functii DOS care au valoarea DS diferita de
cea implicita pentru segmentul de date (arhivate in memoria extinsa)si/sau
-338- [ dos.h - intr() ]
accepta argumente in registrul ES (registrii de segment se arhiveaza in
structura segregs de tip SREGS,de unde pot fi preluati la nevoie).
Atat uniunile de tip REGS cat si structura de tip SREGS sunt declarate in
fila de antet (vezi tipurile de date si constantele dos.h)
Daca se utilizeaza aceeasi structura atat pentru inregs cat si pentru
outregs,datele se vor actualiza la fiecare apel.
Functia returneaza valoarea finala a registrului AX (dupa intrerupere).
Daca x.cflag este setat la o valoare,inseamna ca a intervenit o eroare si
se seteaza automat si _doseerno.Pot exista si erori care nu seteaza carry
flag,dar care seteaza variabila globala _doserrno (sau errno).
EXEMPLU: #include
#include
#include
union REGS reg1;
struct SREGS seg1;
char x,y;
main()
{ x='7';
reg1.h.ah=0x10;
reg1.h.dh=y;
reg1.h.dl=x;
reg1.h.bh=0;
intdosx(®1,®1,&seg1);
printf("x= %c \n",reg1.h.dl);
printf("Registrii de segment sunt: \n");
printf("%u %u %u %u \n",seg1.es,seg1.cs,seg1.ss,seg1.ds);
sleep(3); }
FUNCTIA intr()
-interfata alternativa pentru o intrerupere de tip DOS
SINTAXA GENERALA este: void intr(int intno,struct REGPACK *preg);
Functia este o alta alternativa pentru a executa o intrerupere de tip DOS.
Functia apeleaza direct procesorul (din familia 8086) pentru a executa
intreruperea specificata prin intno.Inainte de executie,functia copiaza in
registrii procesorului datele arhivate in structura preg de tip REGPACK ,
iar dupa executarea intreruperii actualizeaza structura preg cu datele din
registrii.Structura de tip REGPACK este declarata in fila antet
astfel: struct REGPACK { unsigned r_ax,r_bx,r_cx,r_dx;
unsigned r_bp,r_si,r_di,r_ds,r_es,r_flags; }
Functia nu returneaza nici o valoare (structura REGPACK se actualizeaza).
EXEMPLU: #include
#include
struct REGPACK r1;
int x,y;
main()
{ x=64;
for (y=1;y<6;y++)
{ r1.r_ax=x >> y;
intr(0x10,&r1);
printf("Registrul AX are valoarea: %d \n",r1.r_ax);
sleep(2); }; }
-339- [ dos.h-keep() si MK_FP() ]
FUNCTIA keep() si _dos_keep() [C++]
-intrerupe executia si returneaza comanda la DOS,programul ramane rezident
SINTAXA GENERALA este: void keep(unsigned char status,unsigned size);
Functia este asemanatoare cu exit(),dar desi returneaza comanda la sis-
temul de operare,programul intrerupt ramane rezident in memorie (TSR=
terminate and stay rezident) cu statusul specificat prin status si cu o
lungime egala cu cea specificata prin size(size specifica numarul de para-
grafe (linii de program) care raman stocate in memorie.Restul memoriei va
fi eliberata pentru alte operatii.
Functia se utilizeaza pentru a instala programe care raman rezidente in
memorie si continua executia in background (de exemplu ceasul sistemului).
Aceste programe sunt denumite TSR si sunt din ce in ce mai mult utilizate
pentru diverse scopuri (verifica formatul,programe antivirus,receptioneaza
mesaje,transmit mesaje,monitorizeaza temperatura procesorului etc.)
Functia utilizeaza intreruperea DOS 0x31.Inainte de a intrerupe aplicatia,
functia executa toate functiile de iesire specificate prin atexit(),eli-
bereaza toate tampoanele(flushall()) si reseteaza vectorii de intrerupere
modificati prin codul de start.
Daca nu dispuneti de memorie extinsa,este bine sa limitati sau chiar sa
evitati programele TSR,deoarece reduc memoria de operare si implicit
complica executia aplicatiilor.Programele TSR se instaleaza de obicei in
memoria extinsa (SIMM-uri,DIMM-uri,Cache etc.) pentru a nu influenta in
nici un fel executia programelor.
Functia nu returneaza nici o valoare (nu este depanabila).
EXEMPLU: #include
int x;
main()
{ for (x=1;x<30;x++) {
nosound();
delay(900);
sound(500);
sleep(1);
if (x>3)
keep(1,20); };
/* Inchideti fereastra (cu Alt X) pentru a intrerupe sunetul */
}
In exemplul de mai sus,aplicatia este intrerupta dupa 3 secunde,dar sune-
tul ramane rezident (TSR).Pentru a intrerupe sunetul trebuie sa eliberati
memoria de operare (cu o rutina automata),sau mai simplu,inchideti fe-
Dostları ilə paylaş: |
|
|