Přeskočit na hlavní obsah

Způsoby vykonávání programů

Pojďme se pobavit o tom, jak se takový program vykonává. Projdeme si celý postup, od nízkoúrovńového programování po vyšší úroveň abstrakce. Jaké jsou metody běhu programů a jaké jsou jejich přednosti.

Rozdělení programovacích jazyků

Metoda spouštění velmi úzce souvisí s programovacím jazykem. V základu rozlišujeme programovací jazyky z pohledu jejich spuštění jako interpretované a kompilované.

Kompilované

Tyto druhy jazyků fungují tak, že se výsledný program spouští přímo na procesoru jako strojový kód.

Co je to strojový kód?

Strojový kód jsou data (jedničky a nuly), kterým rozumí procesor. Obsahuje seznam intrukcí, které má procesor dělat. Více se dozvíte v Assembly.

Programátor ale většinou neprogramuje přímo strojový kód — ten je obtížně čitelný a při složitějších projektech by nebyl přehledný. Využívají k tomu právě vyšší jazyky, které se zkompilují do strojového kódu, kterému rozumí procesor. Mezi hlavní zástupce patří především C a C++, ale jsou zde i další jako Rust nebo Go.

Co je to kompilace?

Jedná se o překlad daného jazyka do strojového kódu. Je to velmi složitý proces. Každý procesor má totiž odlišnou instrukční sadu. Kompilátor tedy musí podporovat velké množství procesorů a umět kód optimalizovat pro každý z nich. Mezi nejčastější kompilátory pro C a C++ patří GCC a Clang.

Linkování

U větších projektů se píše více zdrojových kódů. Tyto soubory jsou mezi sebou propojené způsobem, který stanovuje konkrétní programovací jazyk. Kompilace těchto souborů se provádí zvlášť. Následně linker spojí zkompilované kódy do jednoho, který se dá spustit. Více se dozvíte v kapitole o linkování.

Proces kompilace

Zde je ukázka, jak probíhá kompilace dvou zdrojových kódů do jednoho spustitelného strojového kódu.

  1. Programátor napíše zdrojový kód (C, C++, …) a ten předá kompilátoru, který z něj udělá assembly (.s).
  2. Assembler přeloží assembly do strojového kódu (.o).
  3. Tyto strojové kódy se následně předají linkeru, který je spojí do jedné spustitelné binárky.
Co když potřebuješ ještě níž?

V některých případech je třeba zapsat přímo sekvenci strojového kódu pro dostatečnou optimalizaci. Často to bývá, pokud překladač nemá podporu nějaké speciální funkce daného procesoru. V tom případě je nutné zavolat konkrétní instrukce procesoru napřímo. K tomu se používá jazyk Assembly. Většina kompilovaných jazyků má podporu pro tento jazyk přímo zabudovanou. Lze tedy celý kód napsat například v C++, ale jednu konkrétní funkci v Assembly pro dokonalou optimalizaci.

Kde lze spustit?

Výsledný strojový kód lze spustit pouze na zařízení, pro které byl kód zkompilován. Záleží tedy především na architektuře. Nelze tedy jednoduše přenášet spustitelné soubory mezi různými zařízeními.

Cross-kompilace

Jedná se o speciální druh kompilátoru. Někdy není možné kompilovat přímo na architektuře, na které chceme program spustit. Pomocí cross-kompilace tedy lze kompilovat i pro jinou architekturu, než na které kompilaci spouštíme.


Interpretované

Interpretované jazyky fungují dost odlišně. Programátor píše program v čitelné podobě stejně jako u kompilovaných jazyků. Ten ale není předán přímo procesoru, ale tzv. interpreteru. Díky tomu lze stejný program spouštět na několika architekturách. Mezi hlavní zástupce patří především Python, JavaScript, Lua nebo i Bash.

Co je to interpreter?

Jedná se o již spustitelný program, který dokáže vykonávat kód, který se mu předá. Zdrojový kód můžeme spouštět na jakékoli architektuře, pro kterou již byl tento interpreter zkompilován.

Importování

Větší projekty jsou rozdělené do více souborů. Interpretované jazyky to řeší tak, že se interpreteru předá pouze hlavní soubor. Ten si pomocí importovacích příkazů „natáhne“ potřebné pomocné soubory, které následně může používat.

Kde lze spustit?

Díky tomu, že zdrojový kód je zde nezávislý na architektuře, lze jej spustit na každém zařízení, které má dostupný daný interpret.

Nicméně i přes to zde jsou určité omezení.
Zdrojové kódy sdílené mezi platformami nemusí být vždy úplně kompatibilní. Pokud bude program využívat nějaké specifické systémové prostředky pro dané prostředí, stane se tím závislým na konkrétním prostředí a v jiném prostředí nemusí být 100% funkční. Kompatibilita například mezi Linuxem a Windowsem je tedy velmi závislá na konkrétním programu.


Hybridní

Existují i jazyky, které kombinují oba tyto přístupy. Provede se překlad do tzv. bytekódu, který se následně interpretuje. Tento překlad provádí většinou sám interpret těsně před spuštěním samotného kódu. Typickými zástupci této metody jsou Java nebo C#.