Režimy adresování () 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 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 jeden 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, 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í 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. Ukázalo se, ž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ů 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čů.
Důležitý případ použití 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 (), 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 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ý +----+------------------------------+ |skok| adresa | +----+------------------------------+
(Efektivní PC adresa <- adresa)
Efektivní adresou pro absolutní adresu instrukce je přímo adresní parametr bez jakýchkoli úprav.
PC-relativní +----+------------------------------+ |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.
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ů.
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é +-------+-----+ |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í
Sekvenční provádění +------+ | 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í 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.
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í 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 +------+-----+-----+ |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 () 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
Registr +------+-----+-----+-----+ | 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í +------+-----+-----+----------------+ | 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í 16bitová hodnota, lze přistupovat pouze k malé části paměti (64 KB).