instrukce strojového kódu pro řízení běhu programu From Wikipedia, the free encyclopedia
Skok (anglicky jump nebo branch odkazující na to, že se pomocí podmíněných skoků provádí větvení programu[pozn. 1]) je instrukce, která narušuje obvyklý způsob provádění počítačového programu po instrukcích v tom pořadí, v jakém jsou zapsány (sekvenčně). Zatímco po provedení jakékoli jiné instrukce se pokračuje prováděním instrukce následující, po provedení skoku se pokračuje instrukcí na jiné určené adrese. Skokem lze realizovat buď přeskočení nebo opakování části programu.
Skoky jsou základní prostředek k větvení programu – rozhodnutí, která část programu se má provádět, na základě výsledku předcházejícího výpočtu. Aby větvení mohlo být ovlivňováno i jinak než nastavením různých cílových adres skoku, používají se podmíněné skoky:
Pomocí kombinace jednoho podmíněného a jednoho nepodmíněného skoku lze vytvořit dvoucestné větvení programu (jestliže je splněna podmínka, proveď první větev, jinak druhou větev – konstrukce if
podmínka then
první větev else
druhá větev), nebo cyklus, jehož provádění je řízeno zadanou podmínkou (pokud je splněna podmínka, proveď tělo cyklu a jdi znovu na vyhodnocení podmínky – konstrukce while
podmínka do
tělo cyklu).
Nedisciplinovaným používáním instrukcí skoku lze vytvořit programy, jejichž chování je velmi obtížné zkontrolovat (u vlastních programů) nebo zjistit (u cizích programů). Vyšší programovací jazyky se proto snaží používání libovolných skoků omezit nebo zcela znemožnit zaváděním programových konstrukcí (strukturované programování).
V instrukčním kódu většiny procesorů je skok implementován změnou hodnoty v registru čítače instrukcí. Cílová adresa skoku může být zadána jako parametr instrukce skoku, nebo může být předem nastavena ve vybraném registru procesoru nebo na vybraném místě vnitřní paměti. U podmíněných skoků se rozhoduje o provedení skoku podle hodnoty vybraného bitového příznaku, obsahu zvoleného registru nebo buňky paměti, případně podle výsledku určité operace (sniž hodnotu registru o 1 a pokud není výsledek 0, proveď skok).
U moderních procesorů je podmíněný skok kvůli pipeliningu, kterým se vyznačuje superskalární architektura, velice „drahá“ operace z hlediska času zpracování – procesor zpracovává několik instrukcí současně nebo dokonce provádí instrukce na přeskáčku (instruction scheduling), takže pro zrychlení výpočtu by potřeboval vědět, která instrukce bude za skokem následovat, ještě dříve než je možné vyhodnotit splnění podmínky skoku. Některé RISCové procesory (např. SPARC) to řeší pravidly typu „ještě dvě instrukce za skokem se provedou bez ohledu na výsledek podmínky skoku“, obvyklejším řešením je odhadnout (s využití informací o předchozích průchodech danou částí programu), která varianta skoku nastane, a v případě omylu zahodit rozpracované instrukce ze špatné větve, vyprázdnit instrukční frontu a načíst do ní instrukce ze správné větve.
Aby se omezilo množství položek, které je potřeba v programu modifikovat při jeho zavedení na jinou adresu v paměti, realizují se některé skoky přičtením hodnoty do registru čítače instrukcí (autorelativní adresování). Navíc protože v programech jsou poměrně časté skoky o malý počet instrukcí, může mít přičítaná hodnota mnohem menší rozsah než celá adresa, čímž lze v instrukci ušetřit několik bajtů místa. Proto mohou být k dispozici různé druhy skoků:
Část (RISCových) procesorů ARM pro podmíněné skoky používá princip ignorování následující instrukce, kombinované právě s instrukcí skoku. Mezi instrukcemi, které mají vyhodnocovat určité podmínky, jsou i varianty těch, které mají za úkol ignorovat následující instrukci, pokud je podmínka vyhodnocena jako pravdivá. Samotné ignorování této instrukce (ve které je tato instrukce vykonána jako instrukce NOOP – no operation) je implementováno jedním z příznaků v procesoru, který se v tomto případě nastavuje a nuluje se po vykonání každé další instrukce. Pokud je touto následující instrukcí instrukce skoku, lze tak implementovat podmíněný skok (pro případy, kdy podmínka v předchozí instrukci není splněna).
Aby bylo možné vytvářet podprogramy, procesory jsou vybavovány dalšími instrukcemi, které provádějí skoky v programu. Pro volání podprogramů (po jejichž vykonání je potřeba se vrátit na instrukci následující za voláním podprogramu) se používají instrukce, které před provedením skoku uloží adresu následující instrukce (návratová adresa z podprogramu). K uložení této adresy se mohou používat univerzální nebo speciální registry nebo paměť. Vzhledem k tomu, že volání podprogramů lze vnořovat, pro ukládání návratových adres se používá datová struktura zásobník.
Jako zvláštní případ volání podprogramu lze chápat i programové přerušení (interrupt). Přerušení obvykle nemá jako parametr přímo adresu obslužné rutiny přerušení, ale jenom číslo přerušení v tabulce (vektoru) přerušení. Navíc se při jeho vyvolání obvykle provádí další činnosti (např. zákaz dalšího přerušení a vstup do privilegovaného režimu).
Při programování v assembleru a strojovém kódu architektury x86 se také rozlišuje, zda cílová adresa skoku leží ve stejné oblasti (segmentu) paměti. Skoky tak lze dělit na:
Od procesoru 80286 přibývá možnost instrukcí skoku změnit úlohu (přepnout proces), což lze označit jako skok ještě delší než dlouhý; u procesoru 80386 přibývá možnost změnit stránkování paměti tak, že zpracování procesu zůstává na stejné virtuální adrese, ale dochází k změně fyzické adresy (tato technika patrně nemá jiné využití než jako úmyslná snaha znesnadnit reverzní inženýrství).
Nižší programovací jazyky obvykle přebírají ze strojového kódu přímo příkaz skoku. Starší vyšší (imperativní) programovací jazyky mají obvykle konstrukci podobnou
IF
podmínka THEN
návěští
ze starších verzí jazyka BASIC, která umožňuje provádět libovolné skoky.
Novější programovací jazyky v souladu se zásadami strukturovaného programování nabízejí konstrukce jako rozvětvení, podmíněný příkaz, cykly a volání funkcí, procedur a metod.
Pokud vyšší programovací jazyk vůbec implementuje nejobecnější příkaz skoku, tento příkaz se obvykle nazývá goto. Blízko k příkazu skoku mají příkazy break a continue (např. v jazyku C) respektive last a next (např. v jazyku perl).
Při překladu do strojového kódu se řídící konstrukce překládají pomocí podmíněných a nepodmíněných skoků.
Za vynálezce podmíněného skoku je považována Ada Lovelace, první programátorka, spolupracovnice Charlese Babbage, vývojáře prvního mechanického počítače.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.