|
parte din deimpartit inainte de operatie sau la inmultiri pentru
|
səhifə | 42/55 | tarix | 07.05.2018 | ölçüsü | 4,6 Mb. | | #50260 |
| parte din deimpartit inainte de operatie sau la inmultiri pentru
a stoca unul dintre factorii operatiei,iar in operatiile I/O
acumulatorul contine datele transferate
DX -registrul de date se utilizeaza pentru memorarea datelor temporare
La operatiile de impartire si inmultire,contine bitii cei mai sem-
nificativi ai numarului reprezentat pe 16 biti.La operatiile de
I/O contine numarul de porturi care vor fi accesate pt.transfer.
CX -registrul contor se utilizeaza pentru a retine numarul de cicluri
sau de repetari ale unor instructiuni,numarul de salturi,rotatii
sau deplasari de memorie etc.Acest registru poate fi utilizat si
pentru memorarea temporara a datelor (dupa epuizarea AX si DX).
-317- [ dos.h - registrii 8086 ]
BX -registrul baza poate fi utilizat ca pointer spre baza de date
(de exemplu spre un obiect din baza de date).Poate fi utilizat
si pentru memorarea temporara a datelor.
BP -registrul pointer baza poate fi utilizat ca poiner spre baza de
date (spre segmentul din stiva),sau poate fi utilizat pentru
memorarea generala a datelor.
SI -registrul index sursa,poate fi folosit ca pointer pentru a indica
(indexa) un anumit articol dintr-un obiect(date) sau poate fi
utilizat pentru memorarea generala a datelor.Pentru siruri,indica
adrese sau vaori din cadrul sirului reprezentate pe 16 biti.
DI -registrul destinatie poate fi utilizat ca pointer spre un articol
dintr-un obiect(date),sau pentru memorarea generala a datelor.
Pentru siruri indica octeti sau valori pe 16 biti din sir.
SP -registrul pointer stiva indica locatia curenta din cadrul seg-
mentului de stiva.Introducerea unei valori mareste valoarea lui
SP cu 2(sau cu 4 la registrii pe 32 de biti).
IP -registrul pointer instructiune contine intotdeauna adresa instruc-
tiunii care va fi executata.Programatorul nu poate sa modifice
pointerul instructiune,sau sa-l acceseze direct.Pointerul este
modificat automat de instructiunile care controleaza fluxul de
date (apeluri,bucle,intreruperi etc.)
Registrul de indicatori(flags),este un registru pe 16 biti si controleaza
diverse instructiuni prin care reflecta starea curenta a procesorului.
Indicatorii comuni pentru toate procesoarele 8086 sunt:transport,paritate,
transport auxiliar,zero,semn,nivel de intrerupere,intrerupere,directie,
supraincarcare,nivel privilegiat I/O,nivel de ciclare,reluare,mod virtual
si control al alinierii.
In versiunea pe 32 de biti,informatiile sunt continute in registrul EFL:
CF Carry flag 0
PF Parity flag 2
AF Auxiliary carry 4
ZF Zero flag 6
SF Sign flag 7
TF Trap flag 8
IF Interrupt flag 9
DF Direction flag 10
OF Overflow flag 11
IO I/O privilege flag 12 si 13
NF Nested task flag 14
RF Resume flag 16
VM Virtual mode 17
AC Alignment check 18
Dupa executarea unei instructiuni,panoul de registrii va contine in cu-
loarea rosie indicatorii de stare care s-au modificat prin executarea
instructiunii.
Ceilalti registrii de procesor,nu apar in functiile din si au
fost prezentati doar pentru formarea unei idei generale despre arhitectura
procesorului 8086.Este bine sa nu apelati la registrii procesorului decat
sub supravegherea unei persoane autorizate,sau in urma unui studiu docu-
mentat al rezultatului scontat.
-318- [dos.h -bdosptr() si country() ]
FUNCTIA bdosptr()
-apeleaza o functie DOS
SINTAXA GENERALA este:
int bdosptr(int dosfun,void *argument,unsigned dosal);
Functia permite accesul la o serie de functii ale sistemului DOS.Se uti-
lizeaza pentru a apela functiile de sistem care necesita un argument de
tip pointer.Pentru functiile care necesita un argument numeric de tip int
se va utiliza functia bdos().Pentru informatii suplimentare consultati
referintele sistemului DOS.Pentru versiunile DOS cu memorie restransa
(small data models),parametrul *argument este reprezentat de registrul DX,
iar in versiunile cu memorie extinsa(large data models) este DS:DX.Functia
specificata prin dosfun,este cea din manualul de referinta(apelata prin
adresa de stiva la care este arhivata).
Functia returneaza valoarea registrului AX sau -1 in caz de esec.In caz
de esec,seteaza automat variabilele globale errno si _doserrno.
EXEMPLU: #include
#include
#include
char tampon[80]="C:\WINDOWS\EXEMPLE";
int test;
main()
{ test=bdosptr(0x3B,tampon,0);
perror("");
printf("registrul AX este: %d \n",test);
getcwd(tampon,80);
test=bdosptr(0x3B,tampon,0);
printf("test(AX)= %d directorul curent este: %s n",test,tampon);
sleep(5);
}
FUNCTIA country()
-returneaza informatii specifice fiecarei tari(conventii grafice)
SINTAXA GENERALA este:
struct COUNTRY *country(int xcode,struct country *cp);
Functia utilizeaza o structura de date de tip COUNTRY in care returneaza
conventiile grafice curente utilizate pentru a scrie data calendaristica,
punctul si virgula zecimala si simbolul monetar.Valorile setate de catre
aceasta functie depind de sistemul de operare.
Structura de tip COUNTRY (definita in dos.h) are forma generala:
struct COUNTRY { short co_date; /*formatul datei */
char co_curr[5]; /*simbolul monetar */
char co_thsep[2]; /*separatorul pt.mii */
char co_desep[2]; /*separatorul zecimal */
char co_dtsep[2]; /*separatorul datei */
char co_tmsep[2]; /*separatorul pt.timp */
char co_currstyle; /*stilul pt. moneda */
char co_digits; /*nr.digiti semnificativi*/
char co_time; /*formatul orei(timpul) */
long co_case; /* case map */
char co_dasep[2] /*separatorul datei*/
char co_fill[10] /*caracter pt.umplere */ }
-319- [ dos.h- ctrlbrk() ]
Pentru formatul datei specificat prin co_date se pot utiliza valorile:
0 -pentru formatul american (USA) al datei de tip month,day,year
1 -pentru tipul european al datei: day,month,year
2 -pentru tipul japonez al datei: year,month,day
iar pentru stilul simbolului monetar specificat prin co_currstyle:
0 -pentru ca simbolul monetar sa preceada valorile,fara spatii goale
1 -pentru ca simbolul monetar sa urmeze valorile,fara spatii goale
2 -pentru ca simbolul sa preceada valorile urmat de un spatiu gol
3 -pentru ca simbolul monetar sa urmeze valorile,dupa un spatiu gol
Functia returneaza argumentul pointerului cp,sau NULL in caz de eroare.
EXEMPLU: #include
#include
#include
struct country rom;
int s,z;
main()
{ s=12355
z=75;
country(0,&rom);
printf("Tara este USA: \n");
printf("Suma din cont este: %d%s%d %s\n",s,rom.co_desep,z,rom.co_curr);
strcpy(rom.co_curr,"LEI");
strcpy(rom.co_desep,",");
strcpy(rom.co_thsep,".");
printf("Tara este ROMANIA: \n");
printf("simbolul monetar este: %s \n",rom.co_curr);
printf("separatorul pentru mii este: %s \n",rom.co_thsep);
printf("separatorul zecimal este: %s \n",rom.co_desep);
printf("Suma din cont este: %d%s%d %s\n",s,rom.co_desep,z,rom.co_curr);
printf(" ... apasati orice tasta ... \n");
getch();
}
In versiunea DOS,tipul de structura COUNTRY se va specifica cu litere mici
(country).Este bine sa utilizati simbolurile grafice doar pentru afisarea
sumelor de bani(in caz contrar,rutinele de calcul pot fi complicate).
FUNCTIA ctrlbrk()
-seteaza numarul de manipulare al tastei control-break(Pause)
SINTAXA GENERALA este: void ctrlbrk(int (*handler)(void));
Functia seteaza o noua rutina de tratare a intreruperii prin control-break
la functia spre care pointeaza *handler.Vectorul nivelului de intrerupere
0x23 va fi modificat pentru a apela noua functie desemnata prin *handler.
Functia desemnata nu va fi apelata direct ci prin intermediul unui nivel
de intrerupere DOS care apeleaza functia respectiva.Functia specificata
prin *handler poate sa execute un numar oarecare de apeluri la sistemul
de operare si nu este obligatoriu sa returneze o valoare (poate utiliza
longjmp pentru salt la un punct arbitrar din program-[doar in C++]).
Daca functia apelata returneaza zero,programul va fi intrerupt,iar pentru
orice alta valoare,programul va fi oprit din executie (si reluat cu Esc.).
Functia ctrlbrk() nu returneaza nici o valoare.
-320- [ dos.h - delay() ]
EXEMPLU: #include
#include
int x,y;
int stop(void)
{ printf("RESETARE ! \n");
setcbrk(1);
}
main()
{ setcbrk(0);
x=getcbrk();
printf("Controlul intreruperilor este setat: %d \n",x);
ctrlbrk(stop);
stop();
y=getcbrk();
printf("Controlul a fost resetat: %d \n",y);
sleep(5);
}
In versiunea Turbo C,functia apelata prin ctrlbrk() nu transfera controlul
la noua functie,motiv pentru care am apelat-o si direct.Incercati sa
dezvoltati un exemplu care sa apeleze corect functia.
FUNCTIA delay()
-suspenda executia programului pentru perioada specificata
SINTAXA GENERALA este: void delay(unsigned milliseconds);
Functia suspenda executia programului pentru un numar de milisecunde egal
cu cel specificat prin argument.Functia are o acuratete de 1 milisecunda
(nu necestia recalibrare).Este extrem de utilizata pentru programarea
animatiilor si a jocurilor pe calculator.Functia poate fi influentata de
functiile globale care modifica nivelurile de intrerupere DOS (poate fi
inactivata de enviroment).
Functia nu returneaza nici o valoare.
EXEMPLU: #include
#include
int x;
main()
{ for(x=1;x<25;x++)
{ printf("x= %d \n",x);
sound(x*100);
delay(x*450);
nosound();
delay(500); };
for(x=25;x>1;x--)
{ printf("x= %d \n",x);
sound(x*200);
delay(x*500);
nosound();
delay(500); };
sleep(3);
}
Incercati sa scrieti o aplicatie in care sa deplasati o imagine grafica
(cerc,patrat,etc.) cu intarziere prin delay() (adica un desen animat).
-321- [ dos.h - disable() ]
FUNCTIA disable()
-dezactiveaza intreruperile
SINTAXA GENERALA este: void disable(void);
Functia inactiveaza intreruperile.Este destinata pentru a facilita ope-
ratiile de intrerupere hardware,prin solutii flexibile.Se utilizeaza
cuplata cu enable() care activeaza intreruperile de hardware.Pentru
unitatile externe,se accepta doar intreruperile NMI=non-maskable interrupt
Functia nu returneaza valori(nu este depanabila).
EXEMPLU: #include
#include
#include
#define INTR 0x2c
void interrupt (*oldhandler)();
int count;
void interrupt handler()
{ disable();
sleep(1);
enable();
count++;
oldhandler();
}
main()
{ count=0;
oldhandler=getvect(INTR);
setvect(INTR,handler);
while (count <20)
{ handler();
printf("count is %d \n",count);
};
setvect(INTR,oldhandler);
sleep(3);
return 0;
}
Este bine sa nu apelati niveluri de intrerupere,decat daca stiti exact ce
anume doriti sa obtineti.Pentru a putea citi si interpreta mai usor pro-
gramele care contin astfel de functii,trebuie sa stiti ca functiile DOS
pot fi apelate prin intreruperea 0x21 (INT 21).Principalele functii care
pot fi apelate prin INT 21 si echivalentul lor in Windows (WIN 32 API)
sunt:
FUNCTIE OPERATIE WIN 32
0EH Select disk SetCurrentDirectory
19H Get current disk GetCurrentDirectory
2AH Get date GetDateAndTime
2BH Set date SetDateAndTime
2CH Get time GetDateAndTime
2DH Set time SetDateAndTime
36H Get disk free space GetDiskFreeSpace
39H Create directory CreateDirectory
3AH Remove directory RemoveDirectory
3BH Set current dirrectory SetCurrentDirectory
3CH Create handle CreateFile
-322- [ dos.h - dosexterr() ]
FUNCTIE OPERATIE WIN 32
3DH Open handle CreateFile
3EH Close handle CloseHandle
3FH Read handle ReadFile
40H Write handle WriteFile
41H Delete file DeleteFile
42H Move file pointer SetFilePointer
43H Get file attributes GetAttributesFile
43H Set file attributes SetAttributesFile
47H Get current directory GetCurrentDirectory
4EH Find first file FindFirstFile
4FH Find next file FindNextFile
56H Change directory entry MoveFile
57H Get file date/time GetDateAndTimeFile
57H Set file date/time SetDateAndTimeFile
59H Get extended error GetLastError
5AH Create unique file GetTempFileName
5BH Create new file CreateFile
5CH Lock file LockFile
5CH Unlock file UnlockFile
67H Set handle count SetHandleCount
FUNCTIA dosexterr()
-arhiveaza informatii extinse despre ultima eroare DOS
SINTAXA GENERALA este: int dosexterr(struct DOSERROR *eblkp);
Functia utilizeaza o structura de tip DOSERROR (definita in dos.h) pentru
a prelua si arhiva informatiile extinse referitoare la ultima eroare DOS.
Structura are forma generala(in C++):
struct DOSERROR { int de_exterror; /*eroarea extinsa */
char de_class; /*clasa erorii */
char de_action; /*actiunea */
char de_locus; /*locusul erorii */ }
Valorile se obtin prin apelarea functiei DOS 0x59 (vezi mai sus).Daca
de_exterror returneaza zero,inseamna ca nu exista erori DOS.
Functia returneaza valoarea pentru de_exterror.
EXEMPLU: #include
#include
FILE *fp;
struct DOSERROR info;
main()
{ fp=fopen("perror.dat","r");
dosexterr(&info);
printf("Informatiile detailiate pentru eroarea DOS sunt:\n");
printf("Eroarea extinsa este: %d \n",info.exterror);
printf("Class: %d \n",info.class);
printf("Action: %d \n",info.action);
printf("Error Locus: %d \n",info.locus);
getch(); }
In versiunea Turbo C,membrii structurii DOSERROR sunt: exterror,class,
action si locus (fara prefixul de_ ,dar de acelasi tip ).
Puteti utiliza functia,pentru depanarea aplicatiilor si programelor.
-323- [ dos.h-dostounix() si __emit__() ]
FUNCTIA dostounix()
-converteste data si ceasul la formatul UNIX
SINTAXA GENERALA este: long dostounix(struct date *d,struct time *t);
Functia preia datele din structurile de tip date si time si efectueaza
conversia la tipul unix de reprezentare a datei si a timpului.Structurile
de tip date si time sunt prezentate la functiile getdate() si gettime().
Data arhivata in structuri trebuie sa fie mai recenta decat Jan 1 1980.
Functia returneaza versiunea UNIX a datei si timpului:numarul de secunde
care au trecut de la 1 Ianuarie 1970,ora 00:00:00 (GMT).
EXEMPLU: #include
#include
#include
#include
#include
#include
time_t t;
struct time timp;
struct date data;
struct tm *locala;
main() {
getdate(&data);
gettime(&timp);
printf("Data= %d %d %d \n",data.da_day,data.da_mon,data.da_year);
printf("ORA= %d %d %d \n",timp.ti_hour,timp.ti_min,timp.ti_sec);
t=dostounix(&data,&timp);
printf("timpul unix= %ld \n",t);
locala=localtime(&t);
printf("In format UNIX data si ora sunt: \n");
printf("%s \n",asctime(locala));
printf(" ...apasati orice tasta... \n");
getch();
}
daca nu utilizati functiile din time.h,datele pot fi preluate si intr-o
variabila de tip long,fara a mai apela la date de tip time_t.
FUNCTIA __emit__()
-insereaza valori literale direct in liniile de cod
SINTAXA GENERALA este: void __emit__(argument,...);
__emit__() este o functie inline care permite inserarea de valori literala
direct in liniile de cod,in momentul compilarii.Se utilizeaza pentru a
genera instructiuni in limbaj masina,fara a mai apela la un asamblor sau
la limbajul de asamblare(codul masina apeleaza direct resursele hardware,
fara a mai necesita un interpretor de limbaj).In general,argumentele uti-
lizate cu __emit__() sunt instructiuni de un byte,dar functia se poate
utiliza si pentru a forma instructiuni mai complexe.Este bine sa nu uti-
lizati aceasta functie,decat daca sunteti familiarizati cu codul masina al
procesoarelor de tip 8086.Orice amplasare gresita a byte-ului care speci-
fica functia apelata va determina o eroare de interpretare,care poate
duce la blocarea procesorului cu date inoperante(calculatorul nu mai poate
functiona decat dupa eliberarea memoriei de RAM).Compilatorul si interpre-
torul C si C++ nu analizeaza daca functia solicitata este corecta,ci o
-324- [ dos.h -__emit__() si FP_OFF() ]
aplica direct,orice modificare a registrilor si a memoriei de RAM fiind
pe raspunderea utilizatorului.Functia trebuie sa contina cel putin un
argument,dar se poate utiliza orice numar de argumente.
ATENTIE:-argumetul functiei va fi aplicat ca atare,fara sa mai fie con-
vertit sau interpretat.
Argumentele utilizate trebuie sa respecte anumite reguli.Astfel,argu-
mentele trebuie sa fie sub forma unor expresii care pot initializa obiecte
statice(deci se pot utiliza cinstante de tip int si float sau adrese ale
unor obiecte statice).Valorile acestor expresii,vor fi scrise in codul
obiectului aflat in executie,in momentul apelarii,exact ca si cand ar fi
fost utilizate pentru a initializa datele.Se pot utiliza si adresele
pentru un parametru variabil sau auto,sau pentru offsetul unei constante.
Numarul de bytes ce va fi amplasat in codul obiect rezultat va fi deter-
minat de tipul de data al argumentului (vezi formatul datelor),cu exceptia
urmatoarelor situatii:
-daca se utilizeaza o constanta de tip signed int (0x90) care este
cuprinsa in intervalul 0-255 (caracterele ASCII),aceasta va fi considerata
ca si un caracter.
-daca se utilizeaza un parametru variabil sau auto,si este cuprins in
limitele -128 la 127,se va scrie un singur caracter iar daca valoarea
este in afara intervalului se va scrie un cuvant(2 bytes).
Un singur byte se va apela astfel: __emit__(0x90);
Daca doriti sa scrieti un cuvant,dar valoarea transferata sa fie mai mica
Dostları ilə paylaş: |
|
|