Přeskočit na obsah

Režim adresování

Z Wikipedie, otevřené encyklopedie

Režimy adresování (anglicky addressing modes) jsou významným aspektem architektury instrukční sady návrhů centrálních procesorových jednotek (CPU). V konkrétní architektuře instrukční sady se používají různé režimy adresování, které definují, jak instrukce strojového jazyka identifikují operand nebo operandy jednotlivých instrukcí. Režim adresování určuje, jak vypočítat efektivní paměťovou adresu operandu pomocí informací uložených v registrech, pomocí konstant, které jsou součástí strojové instrukce, nebo jinde.

Při programování počítačů jsou režimy adresování předmětem zájmu autorů překladačů a programátorů v jazyce symbolických adres.

Terminologie

[editovat | editovat zdroj]

Neexistuje žádný obecně přijatý způsob pojmenovávání různých režimů adresování. Různí autoři a výrobci procesorů mohou používat pro stejný režim adresování různé názvy nebo stejné názvy pro jiné režimy adresování. To, co je v jedné architektuře považováno za jedin režim adresování, může být v jiné architektuře realizováno dvěma nebo více režimy adresování. Například některé procesory s architekturou CISC, např. Digital Equipment Corporation (DEC) VAX-11, považují použití registrů nebo literálů (bezprostředních konstant) za zvláštní režimy adresování. Jiné procesory, např. IBM System/360 a jeho následníci a většina procesorů RISC, kóduje tyto informace zvláštním způsobem v instrukci. Zatímco některé stroje mají pro kopírování obsahu jednoho registru do druhého, kopírování konstanty do registru a kopírování obsahu paměti do registru tři různé instrukční kódy, na VAX-11 se jedná o jedinou instrukci „MOV“ s různými režimy adresování.

Samotný termín „režim adresování“ je možné interpretovat v užším slova smyslu jako „způsob jak se v instrukci počítá adresa operandu ve vnitřní paměti“ nebo v širším smyslu jako „způsob přístupu k operandu“. V první interpretaci se instrukce, které z paměti nečtou ani do ní nezapisují (např. „přičti konstantu k obsahu registru"), nepovažují za instrukce používající nějaký „režim adresování“. Druhá interpretace u strojů jako je VAX, kde lze pomocí bitů určujících režim operandu specifikovat registr nebo konstantu. Pouze první interpretace platí pro instrukce, jakými je např. „načti efektivní adresu“.

Níže popisované režimy adresování jsou rozděleny na režimy pro adresování kódu a režimy adresování dat. Většina počítačových architektur tento rozdíl zachovává, ale existují i architektury, které umožňují, aby (téměř) všechny režimy adresování byly použity v jakémkoli kontextu.

Níže uvedené instrukce slouží pouze pro ilustraci režimů adresování a nemusí odrážet symbolické názvy instrukcí použité na jakémkoli určitém počítači.

Některé počítače, např. IBM 709 a RCA 3301,[1] mají místo jednoho pole, které by obsahovalo režim adresování, zvláštní pole pro nepřímé adresování a indexování.

Počet režimů adresování

[editovat | editovat zdroj]

Různé architektury procesorů se výrazně liší tím, kolik režimů adresování poskytuje jejich hardware. Snížení počtu režimů adresování přináší některé výhody, i když v některých případech může vyžadovat několik instrukcí navíc, případně použití dalšího registru.[2][3] Ukázalo se,[4][5][6] že návrh procesorů s pipeliningem je mnohem snazší, pokud má procesor pouze jednoduché režimy adresování.

Většina RISC procesorů používá jenom asi pět jednoduchých režimů adresování, zatímco CISC procesory např. DEC VAX supermini mají více než deset režimů adresování, z nichž některé jsou dosti složité. Sálové počítače IBM System/360 měly pouze tři režimy adresování; několik dalších se objevilo na System/390.

Pokud procesor používá pouze několik málo režimů adresování, může být požadovaný režim adresování zakódován v instrukčním kódu (jako u IBM System/360 a jeho následníků a většina RISC procesorů). Pokud má procesor velké množství režimů adresování, bývá pro výběr režimu vyhrazeno několik bitů. DEC VAX dovoluje několik paměťových operandů pro téměř všechny instrukce a proto rezervoval několik bitů každého operandu pro indikaci, jaký režim adresování se má použít pro daný operand. Oddělení bitů, které udávají režim adresování, od bitů udávajících operaci v operačním kódu přispívá k ortogonalitě instrukční sady.

I na procesoru s mnoha režimy adresování, měření skutečných programů[7] ukazuje, že jednoduché režimy adresování uvedené níže tvoří přibližně 90 % nebo více všech používáných režimů adresování. Protože většina takových měření je založena na kódu generovaného překladači vyšších programovacích jazyků, odráží to do určité míry omezení používaných překladačů.[8][7][9]

Důležitý případ použití

[editovat | editovat zdroj]

V některých instrukčních sadách, např. v Intel x86 nebo IBM/360 a jejich následníci, existuje instrukce načti efektivní adresu (anglicky Load effective address),[10][11] které provedou výpočet efektivní adresy operandu, ale místo přístupu k paměťové lokaci uloží získanou adresu do registru. To může být užitečné např. pro předávání adresy prvku pole podprogramu. Může jít také o chytrý způsob, jak v jedné instrukci provést více výpočtů než obvykle; například použití takové instrukce s režim adresování „báze+index+posunutí“ (podrobnosti níže) umožňuje v jedné instrukci sečíst obsah dvou registrů s konstantou a výsledek uložit do dalšího registru.

Jednoduché režimy adresování kódu

[editovat | editovat zdroj]

V této části jsou uvedeny některé jednoduché režimy adresování kódu. Názvosloví se na různých platformách může lišit.

Absolutní nebo přímý

[editovat | editovat zdroj]
   +----+------------------------------+
   |skok|           adresa             |
   +----+------------------------------+
   (Efektivní PC adresa <- adresa)

Efektivní adresou pro absolutní adresu instrukce je přímo adresní parametr bez jakýchkoli úprav.

PC-relativní

[editovat | editovat zdroj]
   +----+------------------------------+
   |skok|           posunutí           |    relativní skok
   +----+------------------------------+
   (Efektivní PC adresa <- adresa další instrukce + posunutí, posunutí může být záporné)

Při relativním adresování vůči programovému čítači se efektivní adresa získá přičtením posunutí k adrese další instrukce. Posunutí je v tomto případě obvykle číslo se znaménkem, aby se bylo možné odkazovat nejen za právě prováděnou instrukci ale i před ni.[12]

Tento způsob adresování je zvlášť užitečný pro specifikaci cíle skoku, protože cíl skoku nebývá od instrukce skoku příliš vzdálen (ve vyšších programovacích jazycích většina větví příkazů if a těl while cyklů není příliš dlouhá). Měření skutečných programů napovídá, že osmi až desetibitové posunutí je dostatečně velké pro přibližně 90 % podmíněných skoků.[13]

Další výhodou adresování relativního vůči PC je, že kód může být pozičně nezávislý, tj. může být zavedený kamkoli do paměti bez potřeby upravovat adresy.

Některé verze tohoto režimu adresování se mohou podmíněně odkazovat na dva registry ("skok, jestliže reg1=reg2"), jeden registr ("skok pokud reg1 není 0") nebo žádné registry a implicitně se odkazují na nějaký dříve nastavený bit v status registru. Viz také podmíněné provádění níže.

Registrové nepřímé

[editovat | editovat zdroj]
   +-------+-----+
   |jumpVia| reg |
   +-------+-----+
   (Efektivní PC adresa = obsah registru 'reg')

Efektivní adresa při registrovém nepřímém adresování je adresa v zadaném registru. Například (A7) udává, že se má použít paměť, jejíž adresa je v adresním registru A7.

Výsledkem je přenesení řízení na instrukci, jejíž adresa je v zadaném registru.

Mnoho RISC strojů, i CISC architektura IBM System/360 a následníci, mají instrukce volání podprogramů, které ukládají návratovou adresu do adresního registru; pro návrat z podprogramu se pak používá registrový nepřímý režim adresování.

Sekvenční režimy adresování

[editovat | editovat zdroj]

Sekvenční provádění

[editovat | editovat zdroj]
   +------+
   | nop  |              proveď následující instrukci
   +------+
   (Efektivní PC adresa = adresa další instrukce)

Po provedení sekvenční instrukce CPU pokračuje následující instrukcí.

Sekvenční provádění není na mnoha architekturách považováno za režim adresování.

Většina instrukcí na většině architektur procesorů jsou sekvenční instrukce. Protože většina instrukcí jsou sekvenční instrukce, návrháři CPU často doplňují vlastnosti, které úmyslně snižují výkonnost skokových instrukcí, aby sekvenční provádění instrukce bylo rychlejší.

Podmíněné větvení naplní PC s jedním ze dvou možných výsledků podle podmínky; většina architektur procesorů používá nějaký jiný režim adresování pro „provedené“ skoky a sekvenční provádění pro „neprovedené“ skoky.

Mnoho vlastností moderních procesorů – prefetch instrukcí a složitější pipelining, provádění mimo pořadí, atd. – udržují klam, že každá instrukce skončí dřív, než se začne zpracovávat další, a dává stejné výsledky, i když skutečné zpracování instrukcí procesorem takto neprobíhá.

Každý „základní blok“ takových sekvenčních instrukcí vykazuje časovou i prostorovou lokalitu referencí.

Procesory, které nepoužívají sekvenční provádění

[editovat | editovat zdroj]

Procesory, které nepoužívají sekvenční provádění s programovým čítačem jsou extrémně vzácné. U některých procesorů je v každé instrukci určena adresa další instrukce. Takové procesory mají instrukční ukazatel, do kterého se ukládají zadané adresy; nejedná se o programový čítač, protože není třeba jej inkrementovat. Mezi takové stroje patří počítače s bubnovou pamětí, například IBM 650, stroj SECD, Librascope LGP-30 a RTX 32P.[14]

Jiné architektury počítačů zacházejí mnohem dále, a snaží se vyhnout úzkému hrdlu von Neumannovy architektury různými alternativami programového čítače.

Podmíněné provádění

[editovat | editovat zdroj]

Některé architektury procesorů mají podmíněné instrukce (např. ARM, která neumožňuje podmíněně provádět všechny instrukce v 64bitovém režimu) nebo podmíněné instrukce načítání (např. x86), které v některých případech mohou odstranit potřebu podmíněného větvení, kdy při provedení instrukce skoku musí dojít k vyprázdnění instrukční fronty. Instrukce např. 'porovnání' se používají pro nastavení podmínkového kódu a následující instrukce obsahují test tohoto podmínkového kódu, aby se zjistilo, zda mají být provedeny nebo ignorovány.

Přeskočení následující instrukce

[editovat | editovat zdroj]
   +------+-----+-----+
   |skipEQ| reg1| reg2|    přeskočení následující instrukce jestliže reg1=reg2
   +------+-----+-----+
   (Efektivní PC adresa = další instrukce adresa + 1)

Přeskočení následující instrukce (anglicky skip) lze považovat za speciální druh PC-relativního režim adresování s pevným posunutím o „+1“. Stejně jako adresování relativní k PC mají některé procesory nějakou variantu tohoto režimu adresování, který se odkazuje buď pouze na jeden registr ("přeskoč, jestliže reg1=0") nebo na žádný registr, pouze na některý dříve nastavený bit ve stavovém registru. Jiné procesory mají instrukce, které testují určitý bit v určitém bytu ("přeskoč, jestliže bit 7 registru reg12 je 0").

Na rozdíl od jiných podmíněných větvení nevyžaduje instrukce „skip“ vyprázdnění a nové naplnění instrukční fronty, ale jen ignorování další instrukce.

Jednoduché režimy adresování dat

[editovat | editovat zdroj]
   +------+-----+-----+-----+
   | mul  | reg1| reg2| reg3|      reg1 := reg2 * reg3;
   +------+-----+-----+-----+

Tento „režim adresování“ neobsahuje efektivní adresu a na některých počítačích není považován za režim adresování.

V tomto příkladu jsou všechny operandy v registrech a výsledek se ukládá také do registru.

Báze plus posunutí

[editovat | editovat zdroj]
   +------+-----+-----+----------------+
   | load | reg | báze|    posunutí    |  reg := RAM[báze + posunutí]
   +------+-----+-----+----------------+
   (Efektivní adresa = posunutí + obsah of zadaného bázového registru)

Posunutí je obvykle 16bitová hodnota se znaménkem (ale 80386 rozšířil posunutí na 32 bitů).

Pokud je posunutí nula, jedná se o registrové nepřímé adresování; efektivní adresa je rovna hodnotě bázového registru.

Na mnoha RISC procesorech má registr 0 pevnou hodnotu nula. Pokud je registr 0 použit jako bázový registr, jde o absolutní adresování. Pokud je posunutí 16 bitová hodnota, lze přistupovat pouze k malé části paměti (64 KB).

16bitové posunutí se může zdát nedostatečné v porovnání s velikostí paměti současných počítačů (proto 80386 jej rozšířilo na 32bitové). Mohlo by to být horší: sálové počítače IBM System/360 používaly pouze 12bitové posunutí bez znaménka. Díky principu lokality referencí, který říká, že většina programů se během krátkého časového intervalu obvykle odkazuje na několik málo nevelkých oblastí v paměti.

Tento režim adresování má těsnou souvislost s indexovaným absolutním režimem adresování.

Příklad 1: Uvnitř podprogramu se zpravidla používají parametry a lokální proměnné, jejichž velikost zřídka překračuje 64 KB, na což stačí jeden bázový registr (ukazatel rámce). Pokud se jedná o metodu třídy v objektově orientované jazyce, pak bude potřeba druhý bázový registr, který ukazuje na atributy aktuálního objektu (this, nebo self v některých vyšších programovacích jazycích).

Příklad 2: Pokud bázový registr obsahuje adresu složeného typu (záznamu či struktury), lze posunutí použít pro výběr položky z tohoto záznamu (většina záznamů nebo struktur má velikost menší než 32 kB).

Bezprostřední/literal

[editovat | editovat zdroj]
   +------+-----+-----+----------------+
   | add  | reg1| reg2|    konstanta   |    reg1 := reg2 + konstanta;
   +------+-----+-----+----------------+

Tato metoda uložení hodnoty neobsahuje efektivní adresu a na mnoha počítačích není považován za režim adresování.

Konstanta může být se znaménkem nebo bez znaménka. Například move.l #$FEEDABBA, D0 přesune bezprostřední hexadecimální hodnotu „FEEDABBA“ do registru D0.

Místo použití operandu z paměti je hodnota operandu uvedena přímo v instrukci. Na počítačích DEC VAX může být velikost operandu 6, 8, 16 nebo 32 bitů.

Andrew Tanenbaum uvádí, že 98 % všech konstant v programu se vejde do 13 bitů (viz Filozofie návrhu RISC).

Implicitní

[editovat | editovat zdroj]
   +------------------+
   | smaž bit přenosu |
   +------------------+
   +------------------+
   |vynuluj akumulátor|
   +------------------+

Režim implicitního adresování (X86 jazyk symbolických adres) explicitně neuvádí efektivní adresu zdrojového nebo cílového operandu (někdy obou).

Zdrojová (pokud je použita) nebo cílová efektivní adresa (případně obě) vyplývají z operačního kódu.

Implicitní adresování bylo poměrně běžné na starších počítačích (do poloviny 70. let 20. století). Takové počítače měly obvykle pouze jeden registr, se kterým bylo možné provádět aritmetické instrukce – akumulátor. Takové akumulátorové stroje se implicitně téměř v každé instrukci odkazovaly na akumulátor. Například operaci < a := b + c; > lze provést posloupností instrukcí < load b; add c; store a; > – cíl (akumulátor) je implicitní v každé instrukci „load“ a „add“; zdroj (akumulátor) je implicitní v každé instrukci „store“.

Pozdější počítače obecně měly více než jeden univerzální registr nebo pozici v RAM, které mohly být zdrojem, cílem nebo obojím pro aritmetické operace, proto pozdější počítače potřebovaly nějaké jiné režimy adresování pro zadání zdroje a cíle aritmetických instrukcí.

Některé z instrukcí x86 používají implicitní registry pro jeden z operandů nebo výsledků (násobení, dělení, počítání podmíněného skoku).

Mnoho procesorů (např. x86 a AVR) má speciální registr nazývaný ukazatel zásobníku, který se implicitně inkrementuje nebo dekrementuje při ukládání dat na zásobník nebo vybírání dat ze zásobníku, přičemž efektivní adresa je (implicitně) uložená v tomto ukazateli zásobníku.

Mnoho 32bitových počítačů (např. 68000, ARM nebo PowerPC) má více než jeden registr, který lze používat jako ukazatel zásobníku – a pro implementaci zásaobníku používá režim nepřímého adresování registrem s autoinkrementací.

Některé současné architektury procesorů (například IBM/390 a Intel Pentium) obsahují některé instrukce s implicitními operandy pro zachování zpětné kompatibility se staršími procesory.

Instrukce, které mění příznak uživatelského nebo systémového režimu, bit povolení přerušení, atd., na mnoha počítačích implicitně udávají určitý registr, který tyto bity obsahuje. To zjednodušuje hardware potřebný pro zachycení těchto instrukcí, aby splňovaly Popekovy a Goldbergovy virtualizační požadavky – na takovém systému trap logicky nepotřebuje kontrolovat operand (nebo výslednou efektivní adresu), ale pouze operační kód.

Některé procesory byly navrženy tak, že každý operand je vždy implicitně zadaný v každé instrukci – procesory bez operandů.

Jiné režimy adresování kódu nebo dat

[editovat | editovat zdroj]

Absolutní/Přímý

[editovat | editovat zdroj]
   +------+-----+--------------------------------------+
   | load | reg |         adresa                       |
   +------+-----+--------------------------------------+
   (Efektivní adresa = adresa zadaná v instrukci)

Tento režim adresování vyžaduje prostor v instrukci pro poměrně velkou adresu. Často je dostupný na CISC strojích, které mají instrukce s proměnnou délkou, např. x86.

Některé RISC stroje mají speciální instrukci Load Upper Literal, která načte 16 nebo 20bitovou konstantu do horní poloviny registru. Registr pak může být použit jako bázový registr při adresování mechanismem báze a posunutí s 16 nebo 12bitovou přímou hodnotou posunutí pro získání úplné 32bitové adresy.

Indexovaný absolutní

[editovat | editovat zdroj]
   +------+-----+-----+--------------------------------+
   | load | reg |index|         adresa                 |
   +------+-----+-----+--------------------------------+
   (Efektivní adresa = adresa + obsah zadaného indexregistru)

Tento režim adresování vyžaduje prostor v instrukci pro poměrně velkou adresu. Adresa může být adresou začátku pole nebo vektoru a index může být použit pro výběr požadovaného prvku pole. Procesor může škálovat indexregistr pro různé velikosti prvků pole.

Tento režim adresování je víceméně stejný jako „báze plus posunutí“, ale posunutí je v tomto případě dostatečně velké pro dosažení libovolného místa v paměti.

Příklad 1: Uvnitř podprogramu může programátor definovat řetězec jako lokální konstantu nebo statickou proměnnou. Adresa řetězce je uložena jako adresní konstanta v instrukci. Posunutí, pomocí kterého se vybírá konkrétní znak řetězce pro použití v dané iteraci smyčky, je uloženo v indexregistru.

Příklad 2: Programátor může definovat několik velkých polí jako globální nebo třídní proměnné. Adresa začátku pole je zadána adresní konstantou (případně změněnou při zavádění programu relokační zavaděč) v instrukci, která s polem pracuje. Pro výběr, se kterou položkou pole se bude pracovat (posunutí), se používá indexregistr. Instrukce v smyčce mohou používat stejný registr pro čítač smyčky i pro posunutí v jednom nebo více polích.

Báze plus index

[editovat | editovat zdroj]
   +------+-----+-----+-----+
   | load | reg | báze|index|
   +------+-----+-----+-----+
   (Efektivní adresa = obsah zadaného bázového registr + obsah zadaného indexregistr)

Bázový registr může obsahovat adresu začátku pole nebo vektoru a pomocí indexu lze vybírat požadovaný prvek pole. Procesor může škálovat indexregistr pro různé velikosti prvků pole. Tento režim lze používat pro přístup k prvkům pole předávaného jako parametr.

Báze plus index plus posunutí

[editovat | editovat zdroj]
   +------+-----+-----+-----+----------------+
   | load | reg | báze|index|       posunutí |
   +------+-----+-----+-----+----------------+
   (Efektivní adresa = posunutí + obsah zadaného bázového registru + obsah zadaného indexregistru)

Bázový registr může obsahovat adresu začátku pole nebo vektoru záznamů, indexem lze vybrat požadovaný záznam a posunutím lze vybrat položku v tomto záznamu. Procesor může míra indexregistr umožnit pro velikost každého pole prvek.

Škálovaný

[editovat | editovat zdroj]
   +------+-----+-----+-----+
   | load | reg | báze|index|
   +------+-----+-----+-----+
   (Efektivní adresa = obsah zadaného bázového registru + škálovaný obsah zadaného indexregistru)

Bázový registr může obsahovat adresu začátku pole nebo vektor datová struktura a index může obsahovat posunutí jeden určitý pole prvek požadovaný.

Tento režim adresování dynamicky škáluje hodnotu v indexregistr podle velikosti prvku pole; pokud například prvky pole jsou čísla s pohyblivou řádovou čárkou s dvojnásobnou přesností zabírající 8 bytů, pak hodnota z indexregistru se před použitím při výpočtu efektivní adresy znásobí osmi. Škálovací faktor je obvykle omezen na mocniny dvou, takže místo násobení lze použít bitový posun.

Registrový nepřímý

[editovat | editovat zdroj]
   +------+------+-----+
   | load | reg1 | báze|
   +------+------+-----+
   (Efektivní adresa = obsah bázového registru)

Několik počítače mít toto jako různých režim adresování. Mnoho počítačů používá báze plus posunutí pouze s hodnotou posunutí 0. Například (A7)

Registrový nepřímý s autoinkrementem

[editovat | editovat zdroj]
   +------+-----+-------+
   | load | reg | báze  |
   +------+-----+-------+
   (Efektivní adresa = obsah bázového registru)

Po určení efektivní adresy je hodnota v bázovém registru zvětšena o velikost datové položky, ke které se má přistupovat. Například (A7)+ provede přístup na adresu uloženou v adresním registru A7, a pak zvýší hodnotu ukazatele A7 o 1 (obvykle 1 slovo). Uvnitř smyčky lze tento režim adresování použít pro průchod přes všechny prvky pole nebo vektoru.

Ve vyšších programovacích jazycích se často uplatňuje myšlenka, že funkce, které vracejí výsledek nesmějí mít vedlejší efekty (nepřítomnost vedlejší efektů usnadňuje pochopení a validaci programu). Vedlejším jevem v tomto režimu adresování je změna obsahu bázového registru. Pokud následující přístup k paměti způsobí chybu (například stránka chyba, chyba sběrnice, adresa chyba) vedoucí k přerušení, pak bude restartování instrukce mnohem problematičtější, protože může být potřeba obnovit stav jednoho nebo více registrů do situace před započetím instrukce.

Existovaly nejméně dvě architektury procesorů, u nichž se objevily implementační problémy při zotavení z přerušení, při použití tohoto režimu adresování:

  • Motorola 68000 (adresa je reprezentována 24bitovou hodnotou). Mohly mít jeden nebo dva autoinkrementovací registrové operandy. Procesory 68010 a vyšší vyřešily tento problém ukládáním vnitřního stavu procesoru sběrnice nebo adresa chyby.
  • DEC VAX-11 mohl mít jako operandy až 6 autoinkrementovacích registrů. Přístup ke každému operandu může způsobit dva výpadky stránky (pokud jsou operandy na hranici stránky). Samotná instrukce může být dlouhá až 50 bytů, a sama může také překračovat hranice stránky!

Registrový nepřímý s autodekrementem

[editovat | editovat zdroj]
   +------+-----+-----+
   | load | reg | báze|
   +------+-----+-----+
   (Efektivní adresa = nový obsah bázového registru)

Před určením efektivní adresy je hodnota v bázovém registru zmenšena o velikost datové položky který je, aby byla přistupovat.

Uvnitř smyčky lze tento režim adresování použít pro průchod pozpátku všemi prvky pole nebo vektoru. Tento způsob adresování spolu s autoinkrementací umožňuje implementovat zásobník.

Viz diskuze o vedlejších efektech při autoinkrement režim adresování.

Nepřímé adresování

[editovat | editovat zdroj]

Jakýkoli z režimů adresování zmíněných v tomto článku může mít zvláštní bit pro indikaci, že se má provést nepřímé adresování, tj. že na vypočítané adrese se nenachází operand, ale jeho adresa (obvykle hodnota o velikosti slova, která obsahuje skutečnou efektivní adresu).

Nepřímé adresování může být použito pro kód nebo pro data. Pomocí něho lze snáze implementovat ukazatele, reference nebo manipulátory (handles) a může také usnadnit volání podprogramů, které nejsou jinak adresovatelné. Další přístupy do paměti použité při nepřímém adresování však způsobují ztrátu výkonu.

Některé starší minipočítače (například DEC PDP-8, Data General Nova) měly pouze několik málo registrů a omezený rozsah přímého adresování (8 bitů). Použití nepřímého adresování bylo u nich prakticky jediným způsobem, jak obsáhnout větší rozsah paměti.

Polovina z osmi adresovacích režimů DEC PDP-11 se nazývá odložená (anglicky deferred); zápis @Rn je nepřímé adresování registrem, jak je definováno výše. Režimy predecrement deferred @-(Rn), postincrement deferred @(Rn)+ a indexed deferred @nn(Rn) ukazují na adresy v paměti, které obsahují adresa operandu. Odložené režimy PDP-11 používající programový čítač poskytují jeho absolutní a PC-relativní adresovací režimy.

PC-relativní

[editovat | editovat zdroj]
   +------+------+---------+----------------+
   | load | reg1 | báze=PC |     posunutí   |
   +------+------+---------+----------------+
   reg1 := RAM[PC + posunutí]
   (Efektivní adresa = PC + posunutí)

Relativní adresování vůči programovému čítači lze použít pro naplnění registru „konstantou“ umístěnou v programu v blízkosti aktuální instrukce. Tento režim adresování můžeme považovat za speciální případ adresování „báze plus posunutí“, v němž je jako bázový registr použit programový čítač (PC).

Několik procesorů podporuje reference na data relativní vůči programovému čítači:

MOS 6502 a jeho deriváty používaly relativní adresování pro všechny instrukce větvení. Tento režim používaly pouze tyto instrukce, skoky používaly různé jiné režimy adresování.

Velmi pokročilý 8bitový mikroprocesor Motorola 6809 navržený v roce 1978 také podporuje a PC-relativní adresní režim.

64bitová architektura x86-64 a 64bitová architektura ARMv8-A[15] používaly režimy adresování relativní vůči PC nazývané "„RIP-relative" in x86-64 and "„literal" in ARMv8-A.

Architektura PDP-11, architektura VAX-11 a 32bitové architektury ARM podporují adresování relativní vůči PC díky zahrnutí PC do sady univerzálních registrů.

Při použití tohoto režimu adresování překladač typicky umisťuje použité konstanty do zvláštní sekce datových konstant umístěné bezprostředně před podprogramem nebo bezprostředně za podprogramem, který tyto konstanty používá, aby se zabránilo provádění těchto konstant jako instrukcí.

Tento režim adresování, který vždy načítá data z paměti nebo ukládá data do paměti a pak sekvenčně padá pomocí pro provádění další instrukce (efektivní adresa ukazuje na data), se nesmí zaměňovat s „PC-relativními skoky“ které data z paměti nečtou ani do paměti neukládají, ale místo toho předávají řízení programu na některou jinou instrukci se zadaný posunutím (efektivní adresa ukazuje na proveditelnou instrukci).

Zastaralé režimy adresování

[editovat | editovat zdroj]

Dále uvedené režimy adresování byly používány na procesorech vyrobených v letech 1950–1980, a na většině současný procesorů už nejsou dostupné. Tento seznam není zdaleka úplný; existovalo mnoho jiných zajímavých a zvláštních režimů adresování, například absolutní-minus-logický-OR dvou nebo tří indexregistrů[16][17].

Víceúrovňové nepřímé adresování

[editovat | editovat zdroj]

Je-li velikost slova větší než adresa, je možné tu část informace ve slově, která neobsahuje adresu, použít pro příznak nepřímého adresování, který bude indikovat další úroveň nepřímého adresování. Tento příznak bývá nazýván bit nepřímosti (anglicky indirection bit) a výsledný ukazatel je taggovaný ukazatel, jehož indirection bit udává, zda jde o přímý ukazatel nebo nepřímý ukazatel. Je potřeba zajistit, aby se řetěz nepřímých adres neodkazoval na sebe sama; pokud k tomu dojde, vznikne nekonečný cyklus při vyhodnocování adresy.

Procesory počítačů IBM 1620, Data General Nova, řady HP 2100 a NAR 2 měly takové víceúrovňové nepřímé adresování a mohly tak vstoupit do nekonečné smyčky vyhodnocování adresy. Režim nepřímého adresování paměti na počítači Nova ovlivnil vynález nepřímého vláknového kódu.

Počítač DEC PDP-10 s 18bitovými adresami a 36bitovým slova umožňoval víceúrovňové nepřímé adresování s možností použít v každý fázi také indexregistr. Před dekódováním každého adresového slova byl dotazován systém prioritních přerušení.[18] Vyhodnocování nepřímé adresy by tedy nebránilo provádění obslužných rutin zařízení, včetně případné obsluhy vypršení časového úseku preemptivního multitaskingového plánovače. Se smyčkovou instrukcí by se zacházelo jako s jakoukoli jinou úlohou s velkými nároky na procesor.

Paměťově mapované registry

[editovat | editovat zdroj]

Na některých počítačích byly registry procesoru zpřístupněné na vybraných adresách paměti. U některých počítačů, např. IBM 650,[19][pozn. 1] IBM 7070,[20][pozn. 2] byly tyto adresy na konci adresního prostoru, na jiných byly použity adresy na jeho začátku, obvykle prvních 8 nebo 16 slov paměti (například ICL 1900, DEC PDP-10). Díky tomu nebyly potřeba zvláštní instrukce „přičtení registru k registru“ – stačilo použít instrukce „přičíst obsah paměti k registru“.

Protože přístup k registrům byl rychlejší než ke skutečné paměti, bylo možné využívat tuto oblast pro zrychlení běhu programu – v případě prvních modelů PDP-10, které neměly žádnou cache, se malá smyčka, jejíž kód byl umístěný do prvních několika slov paměti (kde byly adresovatelné rychlé registry, pokud byly nainstalované) vykonávala mnohem rychleji než v paměti tvořené feritovými jádry.

Pozdější modely DEC řady PDP-11 mapovaly registry na adresy v prostoru vstupů/výstupů, což mělo především umožnit vzdálenou diagnostiku. Matoucí bylo, že 16bitové registry byly mapovány na dvě po sobě jdoucí 8bitové bytové adresy.

Nepřímé adresování paměti s autoinkrementem

[editovat | editovat zdroj]

Minipočítač DEC PDP-8 měl osm speciálních lokací (na adresách 8 až 15). Při přístupu k paměti pomocí nepřímého adresování těchto lokací byly tyto lokace po použití automaticky inkrementovány.[21] To usnadňovalo postupné procházení paměti ve smyčce bez potřeby používat nějaké registry pro zpracování adresy.

Minipočítač Data General Nova měl 16 speciálních paměťových lokací na adresách 16 až 31.[22] Při přístupu k paměti pomocí nepřímého adresování, byly lokace 16 až 23 před použitím automaticky inkrementovány a lokace 24 až 31 byly před použitím automaticky dekrementovány.

Adresování nultou stránkou

[editovat | editovat zdroj]

Procesory Data General Nova a rodiny mikroprocesorů Motorola 6800 a MOS Technology 6502 měly velmi málo vnitřních registrů. Aritmetické a logické instrukce se většinou prováděly s hodnotami v paměti místo použití vnitřních registrů. V důsledku toho mnoho instrukcí vyžadovalo dvoubytovou (16bitovou) hodnotu pro odkaz na operand v paměti. Protože operační kódy těchto procesorů měly velikost pouze 8 bitů, paměťové adresy mohly zabírat značnou část kódu.

Návrháři těchto procesorů použili částečnou náhradu známou jako adresování „nulté stránky“. Prvních 256 bytů paměti (s adresami $0000 – $00FF; označovaných jako stránka "„0") bylo možné používat pomocí jednobajtových absolutních nebo indexovaných paměťových adres. Tím se zkrátila doba provedení instrukce o jeden hodinový cyklus a délka instrukce o jeden byte. Ukládání často používaných dat v této oblasti mohlo zkracovat a zrychlovat programy.

V důsledku toho byla nultá stránka používána jako sada registrů. Na mnoha systémech to však mělo za následek vysoké zatížení nulté stránky paměti operačním systémem a uživatelskými programy, což omezovalo její využití, protože volný prostor byl omezený.

Adresování přímou stránkou

[editovat | editovat zdroj]

Adresování pomocí nulté stránky bylo u několika pozdějších 8bitových procesorů jako WDC 65816, CSG 65CE02 a Motorola 6809 vylepšeno. Nový režim, známý jako adresování „přímou stránkou“, přidal schopnost umístit 256bytovou nultou stránku jinam než na začátek paměti (posunutí $0000) na jiné místo v rámci prvních 64 KB paměti.

CSG 65CE02 umožňuje umístit přímou stránku na jakékoli 256bytové hranici v prvních 64 KB paměti uložením hodnoty 8bitového posunutí v novém registru báze stránky (B). Procesor Motorola 6809 k tomu používá registr přímé stránky (DP). WDC 65816 postoupil o krok dále a umožnil, aby přímá stránka byla umístěna na jakékoli adrese v rámci prvních 64 KB paměti uložením hodnoty 16bitového posunutí do zvláštního registru D (direct).

Díy tomu může adresování přímou stránkou používat větší počet programů než u starších procesorů, které umožňovaly pouze režim adresování pomocí nulté stránky.

Škálovaný index s kontrolou mezí

[editovat | editovat zdroj]

Podobá se adresování škálovaným indexem; instrukce však má dva zvláštní operandy (typicky konstanty) a hardware kontroluje, že hodnota indexu je v těchto mezích.

Další varianta používá pro kontrolu mezí vektor deskriptory; to usnadňuje implementaci dynamicky alokovaných polí při zachování plné kontroly mezí.

Nepřímý na bit pole uvnitř slovo

[editovat | editovat zdroj]

Některé počítače měly speciální režimy nepřímého adresování podpolí uvnitř slova.

GE/Honeywell řady 600 umožňoval nepřímé adresování 6bitových anebo 9bitových znaků v 36bitovém slově.

Počítač DEC PDP-10 také používal 36bitová slova. Měl speciální instrukce, které umožňovaly zacházet s paměti jako s posloupností bitových polí nazývaných byty o velikosti 1 do 36 bitů. Deskriptor sekvence o délce jednoho slova nazývaný anglicky byte pointer obsahoval adresu aktuálního slova v posloupnosti, bitovou pozici v rámci slova a velikost každého bytu. Procesor měl instrukce pro načtení a uložení bytů pomocí tohoto deskriptoru a inkrementaci deskriptoru, aby ukazoval na další byte (byty nemohly překračovat hranici slova). Většina softwaru firmy DEC používala pět 7bitových bytů ve slově (ASCII znaky), s jedním nepoužitým bitem ve slově. Implementace jazyka C musely používat čtyři 9bitové byty na slovo, protože funkce 'malloc' v jazyce C předpokládá, že velikost hodnoty typu int je větší než velikost hodnoty typu char;[23] skutečný násobek je dán systémově závislým operátorem sizeof, který se vyhodnocuje v době překladu.

Index další instrukce

[editovat | editovat zdroj]

Procesory počítačů Elliott 503,[24] Elliott 803,[24][25] a Apollo Guidance Computer používaly pouze absolutní adresování a neměly žádné indexové registry. Instrukční sada tedy neobsahovala žádné nepřímé skoky nebo skoky pomocí registrů. Místo toho mohly přičíst obsah aktuálního paměťového slova k další instrukci. Přičtení malé hodnoty k další instrukci před jejím provedením může například změnit JUMP 0 na JUMP 20, což funguje jako indexovaný skok. Instrukce se přitom mění za běhu a v paměti zůstává nezměněna, tj. nejedná se o samomodifikující kód. Pokud hodnota přičtená k další instrukci byla dostatečně velká, mohl být změněn i operační kód instrukce i nebo adresa uložená v instrukci.

  1. Použité adresy na 650: 8000 – přepínače na konzoli, 8001 – distributor, 8002 – spodní část akumulátoru, 8003 – horní část akumulátoru
  2. Použité adresy na 5K nebo 10K 7070: 00xx – indexregistr xx, 9991 – akumulátor 1, 9992 – akumulátor 2, 9993 akumulátor 3, 9995 – programový registr (pouze z konzole), 9999 – instruction counter (pouze z konzole)

V tomto článku byl použit překlad textu z článku Addressing mode na anglické Wikipedii.

  1. System Reference Manual - RCA 3301 REALCOM EDP. [s.l.]: Radio Corporation of America, September 1967. Dostupné online. 94-16-000-1. 
  2. CHOW, F.; CORRELL, S.; HIMELSTEIN, M.; KILLIAN, E.; WEBER, L. How many addressing modes are enough? [online]. MIPS Computer Systems, Inc., 1987. Dostupné online. [nedostupný zdroj]
  3. HENNESSY, John L.; HOROWITZ, Mark A. An Overview of the MIPS-X-MP Project [online]. 1986. ... MIPS-X používá jediný režim adresování: obsah bázového registru plus posunutí. Tento jednoduchý adresní režim umožňuje zahájit výpočet efektivní adresy velmi brzo .... Dostupné online. 
  4. SQUIRE, Jon. Lecture 19, Pipelining Data Forwarding [online]. Dostupné online. 
  5. High Performance Computing, Notes of Class 11 (Sept. 15 and 20, 2000) - Pipelining [online]. [cit. 2014-02-08]. Dostupné v archivu pořízeném dne 2013-12-27. 
  6. SHEN, John Paul; LIPASTI, Mikko H., 2004. Modern Processor Design. [s.l.]: McGraw-Hill Professional. Dostupné online. ISBN 9780070570641. 
  7. a b HENNESSY, John L.; PATTERSON, David A. Computer Architecture: A Quantitative Approach. [s.l.]: Elsevier, 2002-05-29. Dostupné online. ISBN 9780080502526. S. 104. C54x má 17 režimů adresování dat, nepočítaje přístup k registrům, ale čtyři režimy, které se vyskytují v MIPS představují 70 % režimů. Na režimy s automatickou inkrementací a dekrementací, která se vyskytují v některých architekturách RISC, připadá dalších 25 % použití. Tyto údaje byly získány z měření statických instrukcí v knihovně 54 DSP funkcí pro jazyk C kódovaných v jazyk symbolických adres.. 
  8. Dr. Sofiène Tahar. Instruction Set Principles: Addressing Mode Usage (Summary) [online]. 3 programy měřené na stroji se všemi adresními režimy (VAX) ... 75 % tvoří použití posunutí a bezprostřední adresy. Dostupné v archivu pořízeném z originálu dne 2011-09-30. 
  9. Ali-Reza Adl-Tabatabai; Geoff Langdale; Steven Lucco; Robert Wahbe, 1995. Proceedings of the ACM SIGPLAN 1996 conference on Programming language design and implementation - PLDI '96. [s.l.]: [s.n.]. ISBN 0897917952. DOI 10.1145/231379.231402. S2CID 2534344. Kapitola Efficient and Language-Independent Mobile Programs, s. 127–136. 79 % všech prováděných instrukcí by mohlo být nahrazeno instrukcemi RISC nebo složeno z RISC instrukce pouze pomocí základní kombinace blokových instrukcí.. 
  10. , 1968. IBM System/360 Principles of Operation. [s.l.]: IBM, září 1968. Dostupné online. A22-6821-7. S. 135. 
  11. IBM. z/Architecture Principles of Operation, LA instruction. [s.l.]: [s.n.] Dostupné online. 
  12. MAXFIELD, Max. Building a 4-Bit Computer: Assembly Language and Assembler [online]. 2019. Kapitola Addressing modes. Dostupné online. 
  13. Kong; PATTERSON, David A. Instruction set Design [online]. 1995. Dostupné online. 
  14. KOOPMAN, Philip, 1989. Architecture of RTX 32P [online]. 1989. Dostupné online. 
  15. Introduction to ARMv8 64-bit Architecture [online]. quequero.org, 2014-04-09. Dostupné online. 
  16. 704 Electronic Data-Processing Machine Manual of Operation. [s.l.]: IBM, 1955. Dostupné online. 
  17. Reference Manual IBM 7090 Data Processing System. [s.l.]: IBM, 1962. Dostupné online. 
  18. , 1968. DEC-10-HMAA-D: PDP-10 KA10 Central Processor Maintenance Manual. 1. vyd. Maynard, Massachusetts: Digital Equipment Corporation, prosinec 1968. Dostupné online. S. 2–11. Obrázek 2-9: Výpočet efektivní adresy: test „PI RQ ?“. 
  19. , 1955. 650 magnetic drum data-processing machine - manual of operation. [s.l.]: [s.n.], červen 1955. Dostupné online. 22-6060-2. S. 9. 
  20. Reference Manual - IBM 7070 Data Processing System. [s.l.]: [s.n.], January 1960. Dostupné online. A22-7003-0. S. 252. 
  21. JONES, Douglas. Reference Instructions on the PDP-8 [online]. [cit. 2013-07-01]. Dostupné online. 
  22. FRIEND, Carl. Data General NOVA Instruction Set Summary. [s.l.]: [s.n.] Dostupné online. 
  23. "C Reference: funkce malloc()"] [online]. Dostupné online. [nedostupný zdroj]
  24. a b BROOKS, Dave. Some Old Computers [online]. [cit. 2024-04-03]. Dostupné v archivu pořízeném z originálu dne 2014-11-01. 
  25. PURVIS, Bill. Some details of the Elliott 803B hardware [online]. [cit. 2024-04-03]. Dostupné v archivu pořízeném dne 2008-06-16. 

Související články

[editovat | editovat zdroj]

Externí odkazy

[editovat | editovat zdroj]