- -+----            - --             +
                       | 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ň