Adresace
-=-=-=-=-=
"If a computer can't directly address all the RAM you can use, it's
just a toy."
-- anonymous comp.sys.amiga posting, non-sequitir
Běžně se v programech čísla větší, než 65536 moc nevyskytují
a proto 32 bitů moc důležitých není. Jedno z míst, kde opravdu
pomůže je adresace. 64KB paměti adresovatelných 16ti bytovým číslem
je prostě málo. Proto se vývojáři od intelu hluboce zamysleli
a vymysleli segmenty.
Celou paměť rozdělili po 64KB blocích. Adresace potom probíhá
tak, že zvolíte segment, který určuje blok a teprve potom offset,
který určuje vlastní pozici v segmentu. Je tak tedy možné adresovat
mnohem více paměti. Určování všech adres nadvakrát by ale bylo
pomalé a proto se rozhodli použít segmentové registry. Každý program
má nastavený například registr CS (code segment). Pozice v programu
se prostě potom určuje pomocí jednoho 16ti bitového čísla,
které určuje offset v segmentu CS. Podobně funguje registr DS
(data segment) pro data a další registry. Všechno funguje dobře,
pokud program není delší, než 64KB a nepoužívá více dat. V případě,
že program je delší, je nutné používat jinou instrukci pro skoky,
volání apod, které používají plné adresy (segment i offset)
a podobně u dat. Tyto instrukce jsou ale zase pomalejší.
BC se s tímto vypořadává zavedením nekolika pamětových modelů.
Jeden extrém je small, kde jsou všechny adresy krátké a není
tedy možné míd data či kód delší, než 64Kb a v druhém extrému
jsou zase všechny adresy dlouhé a kód je potom delší a pomalejší.
Máte ale k dispozici celou paměť. Většinou se ale používají různé
hybridní modely, kde některá data jsou blízko a jiná daleko.
K tomu se používají dva typy ukazatelů. Do C je potom nutné přidat
slovíčka far a near, pomocí kterých se rozlišuje mezi těmito typy.
Je také třeba víceméně zdvojit memorymanagement, zavédst farmalloc
pro alokaci vzdálených dat apod. I funkce přebírající jako parametr
ukazatel by měly být ve dvou verzích - pro far i near ukazatele.
Také se tím rozbije pointerová aritmetika - není možné míchat far a
near ukazatele. Prostě začne tím opravdové peklo.
Ale Intelové toto ještě zdokonalili. U XT použili pouze pár
prvních bitů v segmentu jako adresu a proto XT umí adresovat
pouze 640KB paměti. To ale brzo začalo být málo a proto se
do XT začaly přidávat hardwarové paměti EMS, které ale nebyly
běžně adresovatelné. Bylo z nich vidět pouze okénko 64KB a pomocí
speciálního ovladače se určovalo, kterou část paměti okénko
zobrazuje. Paměť tak byla pomalejší a práce s ní byla komplikovaná,
ale alespoň nějaká byla.
Korunu tomu všemu narazila 286. Zde intelové přišli na to, že
640KB paměti je málo, Rozhodli se proto zvětšit velikost segmentové
adresy. Protože ale XT paměť "wrapovali" (tedy aresa 1 bylo
to samé co adresa 640KB+1), přestaly by fungovat nějaké hypotetické
obskurdní aplikace přisupující na adresu 1 pomocí té delší.
Vymysleli tedy šílenost jménem A20 gate (ten zmíněný ignorovaný bit
je právě 21.). Program používající více, než 640KB RAM tedy napřed
A20 gate zapne a potom může adresovat dál. Běřně je ale A20 gate
vyplá a proto naše hypotetická aplikace by mohla dál fungovat myslíc
si, že je na XT.
To by ale nebylo tak strašné jako to, že existuje několik
způsobů přepínaní této brány. Dobrý ovladač je musí všechny znát.
Bežně se o ně stará v dosu HIMEM.SYS. Proto po jeho zavedení máte
k dispozici věc, co se jmenuje HMA (high memory area). Což je právě
místo nad 640KB, kde lze normálně provádět kód, pokud je A20 zaplá.
Bežně si tam sobecky vleze DOS a nikoho jiného tam nepustí.
286 ale už umí adresovat 16MB paměti dokonce pomocí několika
berliček (himemu) ji i používat. Pracuje se s ní samozřejmě úplně
jinak, než z přímo adresovatelnou dolní pamětí, nebo EMS. Proto
programy musí znát ještě další způsob jak pristupovat do paměti.
Snad Vás potěším, že právě 32 bitů toto řeší. 32 bitová adresa
je dost dlouhá na to, aby adresovala celou paměť. Proto není třeba
dělat žádné segmenty, offsety, XMS, EMS, UMB, HMA, far, near,
paměťové modely a další strašáky. Prostě pokud je jednou paměť
pořádně zinicalizována (to není tak jednoduché, už třeba díky A20
gatím), je možné pomocí jednoduché 32bitové adresy určit libovolné
místo v paměti stejně rychle, jako v případě small modelu v reálném
módu.
Díky tomu můžete na vše co se týká těchto věcí zapomenout.
Ve zdrojácích smazat všechna slova far a near a radovat se z toho,
že máte lineární paměť. Navíc tím padá omezení na velikost polí,
protože už není řádný důvod, aby pole byla omezena na 64KB. Proto
vám už nemusí naskočit virážka, pokud budete potřebovat nahrát 2MB
dat do paměti. Není nutné kvůli tomu psát nějaké ovladače XMS.
Prostě dáte malloc a je to :)
Další věc, která odpadá jsou overlaye. Protože velikost programu
už není omezena volnou dolní pamětí, můžete klidně odělat 2MB
program, aniž by bylo nutné ho nějak rozsekávat na kousky.
výheň