Rezidentné programy |
||
| <= | => | |
Veľká skupina programov je schopná pracovať na pozadí prevádzanej úlohy. Patria medzi ne ovládače (myši, klávesnice, . . .), utility (hodiny, antivírová kontrola, sťahovače obrazoviek, . . .), vírusy (bez komentáru). Týmto programom pridávame označenie rezidentné.
Ich základnou vlastnosťou je ich neustála prítomnosť v pamäti počítača a schopnosť sa vyvolať, ak je to nutné. Z toho vyplývajú i požiadavky na ne: malá dĺžka kódu (musí obsadiť čo najmenej pamäti) a nezávislosť na spustených aplikáciách.
Činnosť týchto programov na pozadí aplikácií zaručuje ich volanie spolu s obsluhami prerušení. Ak teda dôjde k nejakej udalosti (stlačenie klávesy, prijatie dát na port, uplynutie určitej doby, . . .), je volané prerušenie obsluhujúce túto udalosť. Po tejto obsluhe (,alebo pred ňou) prebehne i časť rezidentného programu pripojeného k nej. Aby k tomu došlo, musí tvorca rezidentného programu zmeniť adresu v tabuľke vektorov prerušení na adresu svojho podprogramu. Pritom si starú adresu obsluhy uschová, aby mohol zaistiť volanie pôvodnej obsluhy udalosti. Je len na tvorcovi, či starú obsluhu bude volať alebo nie (ak ju ale nezavolá, môžu sa vyskytnúť problémy). Programátor sa tiež môže rozhodnúť, v ktorej časti svojho programu bude obsluhu volať (napr. nemôžem čítať aký kláves bol stlačený, keď ešte neprebehla obsluha klávesnice). Rezidentný program má tieto časti:
Najčastejšie sa pre rezidentné programy používajú prerušenia:
Na aké prerušenie rezident pripojíme, závisí do značnej miery na tom, čo má robiť a na čo má reagovať. Občas je dobré si v obsluhe jedného prerušenia nastaviť premenné a v závislosti na ich stave vykonať (alebo nevykonať) určitú činnosť v obsluhe iného prerušenia. Často si ani neuvedomíme, že náš podprogram pripojený k určitému prerušeniu, ho nepriamo volá. Dôjde tak k zacykleniu. Toho sa čiastočne vyvarujeme tým, že všetky činnosti, spojené so vstupmi a výstupmi, prevádzame sami a nevoláme “Céčkové” procedúry (napr. výstup na obrazovku realizujeme priamym zápisom do VRAM, použitie printf vedie k chybe).
#include <dos.h>
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
// redukujeme veľkosť haldy a zásobníka, aby v pamäti zaberal menej miesta
extern unsigned _heaplen = 1024; // veľkosť haldy (heap)
extern unsigned _stklen = 512; // veľkosť zásobníka (stack)
void interrupt ( *oldhandler)(__CPPARGS);
void interrupt hodiny(__CPPARGS) { // nová obsluha prerušenia
asm {
JMP zac // preskoč dáta
label vid dword
DW 156,0xB800 // adresa miesta VRAM, kde budú hodiny
}
zac:
asm MOV CL,2 // hodiny, minúty, sekundy (cy3lus)
c1 : // začiatok cyklu
asm {
LES BX,CS:[offset vid] // naber adresu premennej slovo do BX
XOR AH,AH // vymaž hornú polovicu registra AX
MOV AL,CL // naber do dolnej polovice AX krok i
SHL AL,1 // vynásob, AL:=AL*2
SUB BX,AX // odčítaj od BX obsah AX
OUT 0x70,AL // pošli na CMOS adresu čítanej slabiky
SHL AL,1 // vynásob, AL:=AL*2
SUB BX,AX // odčítaj, to ovplyvní tvar výstupu
IN AL,0x71 // prečítaj z CMOS obsah čítanej slabiky
MOV DL,AL // skopíruj obsah tejto slabiky do AH
SHR DL,4 // desiatky posuň do dolnej polovice AH
AND AX,0xF // odstráň zbytočné bity
AND DX,0xF
OR AX,0x1F30 // urob prevod do ASCII, pridaj atr.
OR DX,0x1F30
MOV ES:2[BX],AX // nastav jednotky vo VRAM
MOV ES:[BX],DX // nastav desiatky vo VRAM
DEC CL // znížiť CL
JNS c1 // koniec cyklu
MOV WORD PTR ES:[154],0x1F00+'.' // vo VRAM oddeľ sekundy a minúty
MOV WORD PTR ES:[148],0x1F00+'.' // vo VRAM oddeľ minúty a hodiny
}
asm PUSHF
oldhandler(); // zavolaj pôvodnú obsluhu
asm POPF
}
int main(void) {
oldhandler = getvect(0x1C); // čítaj adresu súčasnej obsluhy
setvect(0x1C, hodiny); // na jej miesto daj adresu našej obsluhy
// _psp je začiatočná adresa programu v pamäti. Vrchol zásobníka je koniec
// programu. Použitím _SS a _SP spolu môžeme zistiť koniec zásobníka.
keep(0, (_SS + (_SP/16) - _psp)); // ukonči s tým, že program zostane v pamäti
return 0;
}
Uvedený program číta pri obsluhe prerušenia 0x1C stav hodín z pamäti CMOS. Po prepočte
adries a úprave znakov z BCD kódu do ASCII je informácia o čase zobrazená
v pravom hornom rohu obrazovky. Hlavný program má za úlohu len zmenu adresy
pôvodnej obsluhy na našu.
Rezidentné programy |
||
| <= | => | |