Ogólny zarys.
Wyróżniamy dwa tryby procesora: tryb rzeczywisty (16 bitowy) i tryb chroniony (32 bitowy).
Gdy włączamy kompa, to procesor uruchamia się w trybie rzeczywistym następnie uruchamia biosa (który właśnie jest 16Bitowy), a Bios następnie uruchamia boot loadera, a dopiero on uruchamia jądro systemu. A od systemu zależy czy pozostanie w trybie rzeczywistym czy przejdzie do trybu chronionego.
Tryb rzeczywisty
Jest od początku istnienia PC-ta, jak już wcześniej wspomniałem jest to tryb 16 bitowy. Przykładowy system to DOS. Pisanie systemu w tym trybie nie jest nawet takie trudne, dlatego że bios udostępnia bardzo wiele procedur, z których możemy korzystać, mniej więcej do obsługi karty graficznej, klawiatury, dysków itd. kto programował w asemblerze pod Dos-a to bardzo dobrze o tym wie.
Przerwania w trybie rzeczywistym.
Przerwania mogą być programowe lub sprzętowe. Programowe są wywoływane przez użytkownika, a sprzętowe przez sprzęt (zresztą jak sama nazwa wskazuje).
A jak to działa? W bardzo prosty sposób, na samym początku pamięci (adres 0x0000:0x0000) znajduje się tablica wektorów przerwań, która została załadowana przez Bios. Tablica wektorów przerwań to po prostu tablica par offset:segment. Przerwań może być maksymalnie 256. A teraz jakiś konkretny przykład: Użytkownik wciska klawisz klawiatury wywołuje przerwanie sprzętowe o numerze 09h, procesor przerywa swoją dotychczasowa prace (stąd właśnie ta nazwa „przerwanie”) Patrzy do tablicy wektorów przerwań gdzie znajduje się procedura obsługi przerwania i skacze do niej. W tym przypadku taka procedura ma za zadanie zapamiętać jaki klawisz został naciśnięty, po zakończeniu tej procedury, procesor wraca do zadania, które robił przed wywołaniem przerwania. I to jest cała filozofia.
Na koniec jeszcze kilka wzorów na obliczenie gdzie w tablicy znajduje się zapisany Segment i Offset konkretnego przerwania:
Segment = wartość przy 0x0000:numer_przerwania*4
Offset = wartość przy 0x0000:(numer_przerwania*4)+2
Znając to możemy przechwytywać przerwania i pisać własne procedury obsługi. Wykorzystywane jest to w bardzo w wielu celach np. do pisania wirusów czy do obsługi klawiatury w grach pod Dosa bo jak pewnie wielu zauważyło funkcja readkey nie jest do tego zbyt dobra. My przerwania będziemy wykorzystywać do komunikacji programu z systemem.
Adresy
Programując będziemy korzystać z adresów logicznych, a procesor automatycznie będzie go zmieniał na adres fizyczny. Czym się rożni adres logiczny od fizycznego opisuje poniżej:
adres fizyczny – (physical address) jest adresem najniższego poziomu. Podczas komunikacji procesora z układem obsługującym pamięć, na jego liniach adresowych wystawiany jest właśnie adres fizyczny. Wykorzystujemy go podczas komunikowania się z dowolnymi urządzeniami. W trybie rzeczywistym adres fizyczny jest 20 bitowy.
adres logiczny – (logical address) jest adresem złożonym z dwóch członów: identyfikatora segmentu i przemieszczenia w tym segmencie. Adres taki zapisujemy w postaci segment:offset. Adres logiczny powinien być wykorzystywany do zapisywania lub odczytywania danych, procesor automatycznie zamienia go na adres adres fizyczny.
adres segmentowy – (segment) jest pierwszą częścią adresu logicznego. Jeżeli został podany bez offset’u oznacza to, że wskazuje nie konkretną komórkę pamięci a cały blok.
adres relatywny – (offset) jest odległością od początku segmentu, lub jakiegoś bloku danych. Adres takiego segmentu musi być znany.
Pamięć
Niestety tryb rzeczywisty jest też bardzo ograniczony, mamy dostęp tylko do 1MB pamięci, która właściwie jest w części zajęta mniej więcej przez bios, więc nam zostaje tylko 640KB. Pamięć też jest podzielona na sektory po 64KB.
A tak mniej więcej wygląda pamięć w trybie rzeczywistym:
0x0000:0x0000 – tablica wektorów przerwań
0x0000:0x7C00 – tu zostaje załadowany boot-sector przez BIOS
0x1000:0x0000-0x9000:0xFFFF – pamięć użytkownika (najlepiej używać z tego przedziału)
0xA000:0x0000 – pamięć video karty VGA (tylko dla trybu graficznego)
0xB000:0x0000 – pamięć video karty Hercules Monochrome
0xB800:0x0000 – pamięć trybu tekstowego karty VGA
0xC000:0x0000-0xF000:0xFFFF – pamięć BIOSu i inne
Podstawowym ograniczeniem trybu rzeczywistego jest to, że procesor może wykorzystać jedynie niższe 20 bitów swojej magistrali adresowej, stąd właśnie to ograniczenie pamięci, o którym pisałem wcześniej. Niepraktyczne było tworzenie rejestrów 20 bitowych na przechowywanie adresów, więc projektanci INTELA podzielili przestrzeń adresowa na segmenty (po 64KB). Wiec do odwoływania się do pamięci używamy dwóch liczb 16 bitowych, pierwsza to adres segmentu druga to offset przesunięcia od początku segmentu.
Adres fizyczny mając parę 16bitowych rejestrów(segment i offset) możemy obliczyć następująco:
adres fizyczny = segment * 16 + offset
Pamięć PC podzielona jest na 4 logiczne obszary:
I. Conventional Memory – jest to pierwsze 640kb pamięci systemowej. Jest to obszar dostępny dla programisty. Adres : 0000h – 9FFFFh.
II. Upper Memory Area (UMA) – jest to wyższe 384 bajty pierwszego megabajta pamięci, bezpośrednio ponad pamięcią konwencjonalną. Jest ona zarezerwowana do użytku przez urządzenia systemowe oraz ROM razem ze sterownikami. Adres : A0000h – FFFFFh.
III. High Memory Area (HMA) – pierwsze 64kb drugiego megabajta pamięci, czyli pierwsze 64kb pamięci rozszerzonej, która może być dostępna w trybie rzeczywistym. Adres: 100000h – 10FFEFh.
IV. Extended Memory (pamięć rozszerzona) – jest to cała pamięć powyżej pierwszego megabajta. Dostęp do niej mamy jedynie w trybie chronionym. Adres 10FFF0h do końca pamięci operacyjnej.
Ze względu na błąd zrobiony przez firmę Intel możemy skorzystać jeszcze z 64KB, które znajdują się ponad tym 1MB jest to tak zwana pamięć HMA (high memory area).
HMA to pierwsze 65,520 bajtów (64kb odjąć 16 bajtów) pamięci rozszerzonej (tej powyżej granicy 1mb). Technicznie rzecz biorąc jest to adres od 100000h do 10FFEFh. Jest to szczególny obszar pamięci, gdyż jest to jedyny obszar pamięci rozszerzonej, z którego możemy korzystać w trybie rzeczywistym.
To wszystko, co tu opisałem ma bardzo duży wpływ na dzisiejsze procesory, ponieważ każdy nowy procek musi być kompatybilny z trybem rzeczywistym.
Autor: Michał Ślaga(Blind)