- -+---- - -- +
| Chráněný režim (Protected Mode) |
+ ---- ----+- -
> Díl II. <
Nazdar znova!
Nejdřív bych se chtěl omluvit všem, co se čirou náhodou k tomuhle
seriálu dostali a chtěli pokračování (zdravím TiTania :))... Nějak
jsem zaspal a zapomněl na psaní - a pak už bylo pozdě :-(. Zato ale
tuhle lekci udělám trochu hutnější (aspoň doufám). Takže - připravte
si mozky, tužky, počítače nebo kdovícoještě a hurá na to!
. . .
Posledně jsem se jen tak letmo zmínil o tom, co to vlastně chrá-
něný režim je. Nevystihl jsem ani zdaleka všechny vlastnosti, ale kvů-
li tomu budu (a odteď už snad i pravidelně :) ) tvořit tyhle články.
. . .
Jedna z fajn věcí v tomhle režimu je i fakt, že můžete používat
celou fyzicky dostupnou paměť. O tom, že a jak jde využívat i paměť
fyzicky nedostupnou někdy příště... Ještě bych na začátek rád
podotknul, že tahle kapitola bude odrazová pro další vyprávění,
nelekejte se teda, pokud tady něco nenajdete... Prostě se nedá říct
úplně všechno najednou.
No a teď slíbený záběr na mozek:
[ ADRESOVÁNÍ PAMĚTI V CHRÁNĚNÉM REŽIMU ]
(část I.)
V reálném režimu je možnost adresovat maximálně 20 bitů - to zna-
mená něco kolem 1 MB. No, to vážně není nic moc... Adresování se pro-
vádí pomocí segmentů a offsetů, a to tak, že se segment vynásobí 16 a
přičte se offset. Vzorec vypadá takhle:
adresa_v_reálném_režimu = (segment x 16) + offset,
přičemž segment a offset jsou 16-bitové hodnoty. Maximální adresa, na
kterou je možné se teda dostat je (0ffffh * 16) + 0ffffh = 1114095
bajtů, v přepočtu je to něco málo přes 1 MB...
[ Ale to už určitě všichni víte (jinak odkazuji na články na tohle
téma ve Výhni, tuším č. 5). ]
Rozestavení adresy v reálném režimu je přinejmenším "zajímavé".
Autoři chráněného režimu si řekli, že takhle by to vážně nešlo a
vykoumali lepší přístup (no, jak pro koho... občas bych vraždil - viz.
níže).
Zkrátka už nejde zapisovat jen tak někam do paměti, nebo jen tak
z ní číst, ale na začátku programu/čtení/zápisu je nutné si uvědomit,
s jakou částí paměti se bude dělat. I když to zní možná dost složitě,
má to i svoje výhody - nemůže se vám stát, že by vám program "nechtě"
zapsal někam do pryč a vy se pak divili, proč to jednou jede, jednou
ne. O nechtěném zápisu se díky tomuhle opatření dozvíte prakticky
okamžitě. Těchle opatření, který si hlídají stabilitu systému je
interně zabudováno o něco víc, časem se k nim dostanu - dají se totiž
(pokud to někdo umí - a neříkám, že já to umím :)) ) použít na spoustu
dobrejch věcí... (a ačkoliv ani náhodou nechci říct, že Wokna jsou
dobrý, používaj tyhle finty taky... - ale stejně padaj :) ) Původně
měly sloužit (a slouží) k podpoře multitaskingu, takže co program, to
vlastní kus paměti a vlastní práva, nejvyšší práva má OS (možnost
zapisovat takřka všude).
V chráněném režimu neexistují segmenty! Alespoň ne takové, jaké je
znáte z reálného režimu. Ono je to vlastně s tím je jich omezením 1
MB logické, ale přesto to zdůrazňuji. Pokud děláte v nějakém
high-level jazyce, tak je to v podstatě jedno, protože většinu těchle
věcí skryje překladač, ale i tak se můžete setkat s odlišnostmi
real/protected mod. [U Borland Pascalu 7.0 je to například při přímém
přístupu do videoram, kdy se to musí řešit pomocí klíčového slova
SegA000 nebo SegB800, atd... Vysvětlení za moment.]
V PM (zkratka z Protected Mode - chráněný režim. Už mě to nebaví furt
vypisovat) se používá adresovací jednotka zvaná descriptor
segmentu, na kterou ukazuje tzv. selector, ke kterému se určitým
způsobem přičítá offset - jedině jeho význam se nezměnil... No a
abyste to všechno mohli pochopit, bude tu pár menších ASCII nákresů:
[ nákres deskriptoru ]
Tak, teď už víte, jak vypadá takový descriptor. Selector vlastně
nedělá nic jiného, než že na něj ukazuje do jakési tabulky těchto
descriptorů. Ty tabulky jsou dvě - GDT a LDT, tedy Global Descriptor
Table a Local Descriptor Table...
[ selektor ]
No a právě ten selector je hodnota, která se cpe do všech registrů,
které mají v reálném režimu význam segmentových... A pak už adresová-
ní funguje podobně jako v reálném režimu, jenomže se segment nenásobí
šestnácti, ale jednoduše se vezme z descriptoru počáteční adresa
descriptoru a k ní se přičte offset... [No a ty výše zmiňované
konstanty z BP70? To jsou selektory descriptorů přesně popisující da-
nou část paměti, takže SegA000 je vlastně descriptor začínající na
adrese 0A0000h, nějaké délce (já BP nedělal a ani to nijak nezjišťo-
val, takže nevím) a určitých právech (ta samá závorka jak předtím :)
).]
Pokud má někdo zájem o vzoreček, něco takového by tu bylo:
adresa_v_PM = (bázová adresa) + offset,
přičemž offset může mít maximálně tu hodnotu, jaká je velikost
segmentu. Pro shrnutí jsou tady šířky operandů v bitech:
+------------------+----------+----------------+
| | Procesor | Šířka v bitech |
+------------------+----------+----------------+
| bázová adresa | 80286 | 24 bitů, |
| | 80386+ | 32 bitů, |
| velikost segmetu | 80286 | 16 bitů, |
| | 80386+ | 16* bitů, |
| offset | 80286 | 16 bitů, |
| | 80386+ | 32 bitů. |
+------------------+----------+----------------+
* No, velikost je vždy 16 bitů, ale je možné ji v určitém
případě násobit 4 096. (viz. bit G u deskriptorů), takže je
maximální možná velikost buď 1 MB, nebo 4 GB.
Maximální adresa, kterou je možné vyždímat ze 286 je 16 MB, na
386 a výš už je poměrně obstojná - 4 GB (počítáno s bázovou adresou =
0 a offsetem 0ffffffffh). To je taky maximální hranice RAMky, kterou
si do počítače můžete namontovat (blbý, co? - co se dá dělat... :)) )
Pokud je mi známo u Pentií se zatím žádná vylepšení v tomhle směru
neobjevila.
Uff, jestli jste tohle pochopili hned napoprvé, nebo klidně i na-
podesáté, tak si můžete říct, že jste lepší než já... Mě to trvalo
asi půl roku, a i teď v tom mám někdy pořádnej zmatek... No a jestli
jste to nepochopili, nezoufejte. Příště bude pokračování a tam by se
mělo (snad :) ) pár věcí vyjasnit.
> Příklad <
No a teď už konečně další příklad - nečekejte od toho zázraky, je to
vlastně úplně to samý jako posledně, jenže tohle je pro 386 a výš.
Proč to píšu znova? Protože se tak dají testovat i jiné věci...
Počkejte si na další čísla, tam to rozeberu trochu víc. (včetně
speciálních registrů 386 a výš, i toho jednoho na 286...)
.386P
Mov Eax,Cr0 ; Cr0 do Eax...
; Eax je rozšířené Ax pro 386+
; Cr0 je speciální registr 386+
And Al,1 ; Otestujeme bit signalizující stav
; PM (bit č. 0)
; nebo je tady možnost použít i Test Al, 1 - jak kdo chce...
; vlastně tu jde jakákoliv instrukce, po které zjistíte stav 0-tého
; bitu (takhle je to asi nejjednodušší... doufám)
Jnz @V_Chráněném_režimu ; Jojo, jsme v PM
Tohle je pouze část kódu, kdyby měl někdo zájem o kompilovatelný
příklad, ma možnost si jeden takový exportovat.
Valor
za18@oasyl.tgm20-sy.hiedu.cz
(ale nevím, na jak dlouho :( )
výheň