Strojový kód je počítačový program napísaný v strojovom jazyku. Používa inštrukčnú sadu konkrétnej počítačovej architektúry a zvyčajne je zapísaný v binárnej sústave. Strojový kód predstavuje najnižšiu úroveň softvéru — je to priamo vykonateľná reprezentácia príkazov, ktoré dokáže CPU spracovať. Ostatné programovacie jazyky sa prekladajú alebo transformujú do strojového kódu, aby ich počítač mohol vykonávať.

Štruktúra inštrukcie

Inštrukcia v strojovom kóde hovorí procesoru, akú operáciu má vykonať. Každá inštrukcia sa zvyčajne skladá z niekoľkých častí:

  • opkód (kód operácie) — identifikuje, akú činnosť treba vykonať (napr. sčítať, presunúť, načítať z pamäte);
  • operandy — určujú zdroje a cieľ operácie (môžu byť registre, adresy pamäte alebo priamy údaj, tzv. immediátne hodnoty);
  • pomocné polia — v niektorých inštrukčných formátoch sú aj bity pre modifikátory, rozšírenie opkódu, veľkosť operandu alebo kódovanie režimu adresovania.

Operandy môžu byť reprezentované rôznymi spôsobmi (adresovanie): imediátne (hodnota je súčasťou inštrukcie), register, priama (adresa pamäte), nepriama (adresu ukladá register alebo iná pamäťová bunka), indexovaná alebo relatívna (offset voči programovému čítaču).

Formáty a rozdiely medzi architektúrami

Rôzne architektúry majú odlišné sady inštrukcií a kódovanie. Niektoré vlastnosti, ktoré sa líšia:

  • fixná vs. variabilná dĺžka inštrukcií (napr. RISC typicky fixná, x86 často variabilná);
  • počet a veľkosť registrov dostupných pre operandy;
  • podpora komplexných inštrukcií v hardvéri vs. jednoduché inštrukcie, ktoré sa kombinujú v softvéri;
  • poradie bajtov v pamäti (endianness) ovplyvňuje, ako sa viacbajtové hodnoty kódujú do strojového kódu.

Príklady populárnych inštrukčných sád: x86/x86-64, ARM, RISC-V, MIPS — každá má svoje opkódy, režimy adresovania a formát inštrukcií.

Reprezentácia

Hoci strojový kód je v jadre binárny (0/1), bežne sa zobrazuje v hexadecimálnom tvare pre prehľadnosť. Assembler (jazyk kód assembleru) poskytuje ľudski čitateľný zápis týchto inštrukcií a pomocné nástroje ich potom prekladajú do skutočných bajtov. Kompilátory vysokých programovacích jazykov zvyčajne generujú strojový kód alebo medziformát (napr. objektový súbor), ktorý sa následne linkuje do spustiteľného súboru.

Vykonávanie a nástroje

Procesor vykonáva inštrukcie opakovaným cyklom fetch–decode–execute (načítať–dekódovať–vykonať). Pred vykonaním musia byť inštrukcie a dáta načítané z pamäti do cache/registerov. Nástroje a pojmy súvisiace so strojovým kódom:

  • assembler — prevádza textový zápis (assembler) do strojového kódu;
  • disassembler — prekladá strojový kód späť na assembly kód (pomáha pri analýze a reverznom inžinierstve);
  • linker — spája objektové súbory do jedného spustiteľného súboru;
  • debugger — umožňuje krokovať strojový kód pri ladení (napr. breakpoints, registr-y, pamäťové zobrazenie);
  • tools ako hex editory, objdump, IDA, Ghidra — bežné pri analýze binárnych súborov a bezpečnostnom testovaní.

Použitie, výhody a obmedzenia

Strojový kód sa často nazýva natívny kód, pretože je priamo zrozumiteľný danému procesoru. Výhody:

  • maximálny výkon — vykonáva sa bez medzičlánkov (okrem prípadov JIT alebo emulácie);
  • úplný prístup k hardvéru a špeciálnym inštrukciám CPU;
  • možnosť jemného ladenia a optimalizácie pre konkrétnu architektúru.

Obmedzenia a riziká:

  • nízka prenosnosť — binárny kód je viazaný na konkrétnu architektúru, preto programy treba tvorcom programov často prekladať na rôzne platformy alebo používať cross-kompiláciu;
  • bezpečnostné riziká — chyby v natívnom kóde môžu viesť k pretečeniam zásobníka, kódu vykonanému z neoverených zdrojov (code injection) a podobne; moderné OS používajú mechanizmy ako DEP/NX, ASLR a podpisovanie kódu na zníženie rizika;
  • ťažšia čitateľnosť a údržba v porovnaní s vysokými programovacími jazykmi.

Preklad a interpretácia

Kód assembleru aj iné programovacie jazyky sa obvykle transformujú do strojového kódu — kompilátory prevádzajú zdrojový kód na strojový kód priamo, interprety môžu vykonávať príkazy priebežne alebo prekladať medziformát (napr. bytecode) do natívneho kódu za behu (JIT). V niektorých systémoch sa namiesto priamého strojového kódu používa virtuálny stroj (bytecode), ktorý zaisťuje prenositeľnosť medzi platformami, no s potenciálnou stratou výkonu bez JIT optimalizácií.

Nástroje pre prácu so strojovým kódom

Bežné nástroje používané pri práci so strojovým kódom zahŕňajú assemblery (napr. GNU as), linkery, debuggery (gdb), disassemblery a analyzátory (objdump, IDA Pro, Ghidra), hex editory a profily výkonu. Tieto nástroje uľahčujú ladeniu, optimalizáciu a bezpečnostnú analýzu binárnych programov.

Tvorcovia programov menia kód na iný jazyk alebo strojový kód podľa potreby. Strojový kód sa niekedy nazýva natívny kód a používa sa na označenie programov, ktoré fungujú len na niektorých počítačoch alebo architektúrach. Keď sa uvažuje o prenositeľnosti a bezpečnosti, vývojári volia medzi priamym generovaním strojového kódu, použitím medzivrstvy (bytecode) alebo inými prístupmi (emulácia, virtualizácia), v závislosti od požiadaviek projektu.