Programowanie Główna arrow pascal arrow Przechwytywanie przerwań i pisanie programów rezydentnych (TSR)


Przechwytywanie przerwań i pisanie programów rezydentnych (TSR)
Powinieneś znać: Przerwania, Pamięć komputera
Przerwanie jest to mówiąc w skrócie procedura zawarta w pamięci komputera
z przyporządkowanym numerem od 00 do FFh. Mimo, ze może być ich nawet FF
najczęściej używane są te do 30h. Sam DOS podczas ładowania
przyporządkowuje im poszczególne procedury. I tak na przykład przerwanie
10h używane jest do zmiany trybów graficznych, a przerwanie 1Ch wskazuje
na procedurę, którą zegar systemowy uruchamia 18 razy na sekundę. Czasami
zdarza się, że musimy przechwycić jakieś przerwanie, czyli ustawić je tak,
aby wykonywało naszą procedurę. Do czego to się przyda?

Zastosowanie 1 - wewnątrz naszego programu

Załóżmy, że piszesz program, który działa w trybie tekstowym i chcesz, aby
non - stop w prawym górnym rogu ekranu widniała aktualna godzina. Gdybyś
nie czytał tego mądrego tekstu to prawdopodobnie w setce miejsc w
programie wstawiłbyś pokazywanie zegarka, co i tak byłoby zawodne.
Zdecydowanie prościej jest przechwycić przerwanie 1Ch i 18 razy na sekundę
wyświetlać zegarek w prawym górnym rogu ekranu. Gdy to zrobimy możemy
normalnie pisać program, a system co chwila będzie odświeżać czasomierz,
bez zbytnich zmian w programie! Jak to zrobić? Bardzo prosto. Najpierw
powinniśmy napisać procedurę wyświetlającą zegarek. Nie powinna ona
korzystać z write i innych tego typu funkcji (tak to już jest z
procedurami podpinanymi pod przerwanie), więc najlepiej zrobimy, jeśli
zegarek umieścimy od razu w pamięci komputera. Najpierw napiszmy procedurę
stawiającą literę na ekranie:

1
2
3
4
procedure Znak(x,y:integer;ch:char);
begin
Mem[$B800:120*(y-1)+x*2-2]:=Ord(Ch);
end;


(Jeśli nie rozumiesz tej procedury to nie martw się - nie ma większego
znaczenia)
Teraz pora zaprogramować zegarek. Procedurka jest banalna - pobiera czas
systemowy, a następnie wyświetla godzinę.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Uses DOS;
{Tutaj wstaw procedure Znak}
procedure Zegar;
var h,m,s,s100:word;
st:string;
begin
gettime(h,m,s,s100);
str(h,st);
Znak(69,1,'[');
Znak(70,1,st[1]);
ZNak(71,1,st[2]);
Znak(72,1,':');
str(m,st);
Znak(73,1,st[1]);
ZNak(74,1,st[2]);
Znak(75,1,':');
str(s,st);
Znak(76,1,st[1]);
ZNak(77,1,st[2]);
Znak(78,1,']');
end;


To jest dosyć oczywiste. Najpierw pobieramy czas do zmiennych h,m,s,s100,
a następnie po kolei zamieniamy te zmienne na string i literka po literce
wyświetlamy na ekranie. Zegarek wygląda ładnie, ale ma jedną wadę - nie
rusza się. Gdybyś chciał napisać program, który działa i równocześnie
wyświetla zegar to musiałbyś umieścić tą procedurę w pętli, lub coś w tym
stylu. Jako, że jest to uciążliwe podepniemy ją pod przerwanie 1Ch, które
wykonywane jest na tyle szybko, że zegarek będzie zawsze pokazywał
odpowiedni czas. Jak to zrobimy?
Przede wszystkim trzeba powiedzieć kompilatorowi, że procedura,
którąą piszemy będzie podpięta pod przerwanie. Robimy to dodając
słówko kluczowe interrupt po nazwie procedury:

1
procedure Zegar;interrupt;


Poza tym, kiedy chcemy przechwycić przerwanie musimy wydać odpowiednie
polecenie. Jest to SetIntVec(X,Y) z modułu DOS. Parametr X oznacza
numer przerwania (u nas $1C), a Y to wskaźnik do procedury (@Zegar):

1
2
3
4
5
6
7
8
9
10
11
12
begin
SetIntVec($1C,@Zegar);
Writeln('Ten genialny program od tej pory będzie wywietlać godzinę
systemową;');
Writeln('Niezależnie od tego, co będziemy robić. Np. Podczas readln:');
readln;
Writeln('Czy delaya');
Delay(10000);
Writeln('Raz przechwyciłe przerwanie i już nie musisz się nim
przejmować!!!!');
readln;
end.


Przepisz teraz ten program, skompiluj go, obejrzyj wyniki, pozmieniaj co
nieco (np. niech przy parzystych sekundach : zegarka się nie wyświetlał) i
kiedy stwierdzisz, że znasz temat przejdź dalej..


Zastosowanie 2 - pisanie programów TSR (Terminate And Stay Resident)

Dawno, dawno temu, kiedy na Ziemi rządziły dinozaury nasi przodkowie
korzystali z DOS'a. W tym oto systemie przechwytywanie przerwań miało dużo
więcej zastosowań, niż dzisiaj. Otóż można było napisać programy, które
mimo, że kończyły swoje działanie (system wracał do znaku zachęty C:>)
siedziały nadal w pamięci, a dokładniej - procedury, które były podpięte
pod przerwania zostawały w pamięci i taki np. zegarek z poprzedniego
przykładu wyświetlał się nadal, nawet, jeśli były uruchamiane inne
programy.
Na tej zasadzie działała większość wirusów (podpinały się pod przerwanie
zapisujące dane do pliku), sterowniki do myszek itp. W dzisiejszych
czasach jest to praktycznie bezużyteczna technologia, gdyż pod Windowsem
przerwań się praktycznie nie używa, ale mimo wszystko czasem się przydaje. Aby pozostawić program w pamięci powinieneś po przechwyceniu wszystkich
przerwań wywołać polecenie Keep(0);. Zadziała ono podobnie do Halt, ale
przerwania pozostaną w pamięci komputera. Jest to jednak w dobie Windowsa
dosyć nieprzydatne zagadnienie..

site copyright © http://www.e-kursy.com
pozycjonowanie i optymalizacja | statusygg | kamerki internetowe | pozycjonowanie kraków | kolokacja
KUCHNIE | Gry planszowe | Car audio | Narzędzia pozycjonujące | pozycjonowanie | Wycieczki Chorwacja | kredyt samochodowy | Nieruchomości Szczecin | Dębica Navigator | Krzesła