V predchadzajucej lekcii sme si vysvetlili ako sa adresuje pamet - ako sa vytvara 20-bitova adresa z dvoch 16-bitovych zloziek. V dnesnej lekcii si blizsie vsimneme tieto 16-bitove zlozky adresy - odkial sa beru a akeho typu mozu byt.

   Pri zapisovani nejakej konkretnej adresy v pameti sa nezvykne pisat priamo jej 20-bitova adresa, ale jej 16-bitove zlozky oddelene dvojbodkou [zvycajne v sestnastkovej sustave]. Napriklad namiesto adresy 9F123 sa napise 9F00:0123.

   Pozornemu citatelovi urcite neunikla jedna zaujimava skutocnost. Ked si vsimneme sposob vypoctu 20 bitovej adresy, zistime, ze k jednej konkretnej 20 bitovej adrese mozeme dojst viacerymi sposobmi. Tak napriklad adresu 9F123 v predchadzajucom priklade mozno vyjadrit nielen hodnotami 9F00:0123, ale aj inymi hodnotami, ako napr. 9000:F123, 9F10:0023, 9E00:1123, 9011:F013... Moznosti je skutocne neurekom. Ktoru z tychto moznosti volit ? Vzdy, v kazdom programe vsetky adresy v pameti patria do nejakych segmentov [adresovanych segmentovymi registrami CS,DS,ES,SS] Preto pre skupinu adries patriacich do jedneho konkretneho segmetu berieme ich segmentovu zlozku ako adresu na ktorej zacina dany segment [hodnotu v segmentovych registroch] a potom ich offsetovu cast ako posunutie v ramci tohto daneho segmentu. Napriklad ak sa pri behu programu adresuje pametove miesto na adrese A5123 a jeho segmentova cast adresy sa berie z registra DS v ktorom je hodnota A000, tak potom sa adresa tohto pametoveho miesta zapisuje hodnotami A000:5123.

   Pri samotnom vypocte adresy pri vykonavani instrukcie sa segmentova zlozka moze vziat z priameho operandu instrukcie [napriklad pri instrukcii JMP FAR - daleky medzisegmentovy skok - s priamym operandom] alebo z niektoreho segmentoveho registra [castejsi pripad]. Ktory segmentovy register sa konkretne pouzije, zavisi od sposobu tvorby offsetovej zlozky adresy, ale tento vyber je mozne v niektorych pripadoch zmenit pomocou tzv. segmentoveho "override" prefixu.

   Moznosti ako ziskat offsetovu zlozku adresy je ovela viac. Vsetky tieto moznosti sa suhrnne nazyvaju odbornym pojmom "Effective address" - skratene EA. Offsetova cast adresy moze byt dana jednym z nasledujucich sposobov:

SPOSOB TVORBY OFFSETUPRIKLAD INSTRUKCIE
1samotny displacementMOV AL,[INKREMENT]
2bazovy registerMOV AL,[BX]
3indexovy registerMOV AL,[SI]
4bazovy register + displacementMOV AL,[BP+posun]
5indexovy register + displacementMOV AL,[DI+posun]
6bazovy register + indexovy registerMOV AL,[BX+SI]
7bazovy register + indexovy register + displacementMOV AL,[BP+DI+posun]

   Ako bazovy register moze byt pouzity jeden z registrov BX alebo BP, indexovy register moze zase byt SI alebo DI. Displacement je odborny termin pre konstantu, ktora vyjadruje akesi posunutie. V pripade 1 znamena priamo offsetovu zlozku adresy.

   Ak sa na tvorbe offsetovej zlozky adresy podiela bazovy register BP, tak segmentova zlozka adresy sa berie zo segmentoveho registra SS, vo vsetkych ostatnych pripadoch je urcena registrom DS. Avsak toto stantartne nastavene mozno lahko zmenit pomocou tzv. segmentoveho prefixu, ako to tu uz bolo spomenute. Napriklad ak mame premennu INKREMENT umiestnenu nie v segmente na ktory ukazuje register DS, ale v segmente adresovanom registrom ES, a tym padom chceme aby sa segmentova zlozka adresy zobrala z tohto registra ES, zapiseme instrukciu presuvajucu obsah tejto premennej do registra AL takto:

MOV AL,ES:INKREMENT

   Ako sa jednotlive sposoby vytvarania offsetu daju v praxi vyuzit ? Prvy sposob so samotnym displacementom je najvhodnejsie pouzivat pri adresacii jednoduchych nestrukturovanych premennych, samotny register [indexovy alebo bazovy] je vhodne pouzivat ak potrebujeme pristupovat do roznych bufferov a casti pamete umiestnenych v osobitnych segmentoch. Register + displacement sa dobre vyuzije pri adresacii roznych tabuliek, kde displacement je zaciatok tabulky v ramci daneho segmentu a v registri je index alebo poradove cislo nejakeho prvku v tabulke. Ak aj displacement nahradime registrom [kombinacia bazovy register + indexovy register] mozme vytvorit univerzalnejsiu rutinku, ktora bude chciet na vstupe bazovu adresu tabulky a potom index prvku v tabulke. Posledny, nazlozitejsi sposob [bazovy register + indexovy register + displacement] sa da v velkou vyhodou pouzit napriklad v takom pripade, ze mame strukturovanu tabulku, ktorej prvky su tiez nejake zlozitejsie struktury [napr. dalsie tabulky]. Vtedy displacement moze ukazovat na zaciatocnu adresu tabulky v ramci daneho segmentu, bazovy register moze ukazovat na nejaky prvok tejto zlozitej tabulky a indexovy register moze adresovat udaje este v ramci tohto prvku. Ale nikde nie je napisane ze to tak musi byt a konkretne pouzitie tychto jednotlivych sposobov adresacie pameti zavisi od programatora.

Nazad na obsah , predchadzajuca a dalsia lekcia