[ Pobierz całość w formacie PDF ]
Bogdan Drozdowski 205
Bogdan Drozdowski Język asembler dla każdego 2009-02-25
206 Bogdan Drozdowski
2009-02-25 Język asembler dla każdego Bogdan Drozdowski
Wykrywanie sprzętu
Niektóre programy nie tylko zajmują się przetwarzaniem danych, ale muszą też współpracować ze sprzętem,
na przykład wykorzystać port szeregowy czy równoległy do przesyłania danych (czy to na drukarkę, czy do
innego urządzenia). W tym artykule pokażę, jak wykrywać część urządzeń zainstalowanych w komputerze.
Dobrze mieć spis przerwań Ralfa Brown'a pod ręką.
Wykrywanie ilości zainstalowanej pamięci RAM
(przeskocz wykrywanie pamięci)
UWAGA: NIE należy badać pamięci RAM, zapisując do niej określone bity pod każdy możliwy adres i
sprawdzając, czy uda się odczytać te same bity (brak pamięci sygnalizowany jest odczytaniem FF). Część
urządzeń w komputerze (zwłaszcza PCI) jest mapowana do pamięci i zapisywanie do pewnych obszarów jest
równoznaczne z zapisywaniem do tych urządzeń, co może je poważnie uszkodzić!
Do odkrycia zainstalowanej ilości pamięci RAM można skorzystać z następujących funkcji BIOSu: int 15h z
EAX=0e820h, int 15h z EAX=0000E820h oraz int 12h (najlepiej w tej kolejności).
Pierwsza z nich korzysta z 32-bitowych rejestrów, więc dopiero od procesora 386 można sprawdzać, czy jest
dostępna. Kolejne uruchomienia tej funkcji zwracają informacje o kolejnych obszarach pamięci i ich typie,
tworząc tym samym BIOSową mapę pamięci. Ta funkcja przyjmuje następujące argumenty:
" EAX = 0000E820h
" EDX = 534D4150h (stała)
" ES:DI - adres bufora o następującej strukturze:
f& 8 bajtów na adres obszaru pamięci
f& 8 bajtów na długość tego obszaru pamięci
f& 4 bajty na typ obszaru pamięci
" ECX - długość bufora spod ES:DI w bajtach (minimum to 20)
" EBX = adres początkowy, od którego BIOS ma zacząć sprawdzanie. Na początku jest to zero.
Jeśli wywołanie się powiedzie, funkcja zwraca, co następuje:
" flaga CF=0
" wskazany bufor zostaje wypełniony danymi
" EBX = następny adres, skąd kopiować (podajemy go w EBX jako początkowy do kolejnego
wywołania) lub 00000000h jeśli koniec
" ECX = długość zwróconych informacji w bajtach
W przypadku niepowodzenia flaga CF=1. Przykładowe wwywołanie wygląda tak:
mov ax, cs
mov es, ax ; jeśli bufor jest w sekcji kodu
mov eax, 0e820h
mov edx, 534D4150h
xor ebx, ebx
mov ecx, 20
mov di, bufor
int 15h
Bogdan Drozdowski 207
Bogdan Drozdowski Język asembler dla każdego 2009-02-25
jc blad
; tu operujemy na danych
blad:
...
bufor:
b_adres dd 0, 0
b_dlugosc dd 0, 0
b_typ dd 0
Druga funkcja nie przyjmuje żadnych argumentów (poza numerem funkcji w AX) i zwraca ilość pamięci
rozszerzonej od 1 MB do 16 MB, w kilobajtach, w AX. Jeśli wywołanie się nie powiedzie, flaga CF=1.
Przykładowe wwywołanie wygląda tak:
mov ax, 0E801h
int 15h
jc blad
; tu operujemy na danych
blad:
Trzecia funkcja (przerwanie int 12h) w ogóle nie przyjmuje żadnych argumentów, a zwraca liczbę kilobajtów
ciągłej pamięci od bezwzględnego adresu 00000h.
Wykrywanie portów szeregowych i równoległych
(przeskocz wykrywanie portów)
Wykrywanie portów, o których wie BIOS, jest bardzo łatwe. Wystarczy zajrzeć do BDA (BIOS Data Area),
czyli segmentu numer 40h, zawierajacego dane BIOSu.
Adresy kolejnych portów szeregowych (maksymalnie czterech) jako 16-bitowe słowa można znalezć pod
adresami 0040h:0000h, 0040h:0002h, 0040h:0004h, 0040h:0006h (choć ten ostatni adres może służyć do
innych celów na nowszych komputerach), zaś adresy kolejnych portów równoległych (maksymalnie czterech)
jako 16-bitowe słowa znajdują się pod adresami 0040h:0008h, 0040h:000Ah, 0040h:000Ch, 0040h:000Eh.
Jeśli dodatkowo chcecie wykryć rodzaj portu szeregowego, polecam kod darmowego sterownika myszy dla
DOSa - CuteMouse (a szczególnie plik comtest.asm). Sterownik jest napisany w asemblerze i można go
pobrać oraz obejrzeć jego kod zródłowy za darmo.
Wykryć rodzaj portów równoległych można za pomocą układów nimi sterujących, na przykład Intel
82091AA Advanced Integrated Peripheral (porty 22h-23h). Kod dla tego układu może wyglądać następująco:
mov al, 20h ; numer rejestru, który chcemy odczytać
out 22h, al ; wysyłamy go na port adresu
out 0edh, al ; opóznienie
in al, 23h ; odczytujemy dane z portu danych
208 Bogdan Drozdowski
[ Pobierz całość w formacie PDF ]