Mašininis kodas - tai kompiuterio programa, parašyta mašinine kalba. Joje naudojamas tam tikros kompiuterio architektūros instrukcijų rinkinys. Paprastai jis rašomas dvejetainiu kodu arba pateikiamas heksadekimaliniu formatu, kad būtų patogiau skaityti žmonėms. Mašininis kodas yra žemiausio lygio programinė įranga, kurią tiesiogiai vykdo procesorius. Kitos programavimo kalbos dažniausiai išverčiamos į mašininį kodą, kad kompiuteris galėtų jas vykdyti.

Instrukcijos struktūra

Instrukcija nurodo procesoriui, kokią operaciją atlikti. Kiekvieną instrukciją sudaro opkodas (operacijos kodas) ir vienas arba keli operandai. Operandai paprastai būna atminties adresai, registrai arba tiesioginiai (immediate) duomenys. Instrukcijų rinkinys - tai kompiuteriui prieinamų opkodų sąrašas ir taisyklės, kaip interpretuoti operandus.

Adresavimo būdai ir operandai

  • Immediate (tiesioginis) — operandas pateikiamas pačioje instrukcijoje (pvz., konstanta).
  • Register — operandas yra procesoriaus registras.
  • Memory — operandas yra atminties vieta nurodyta adresu.
  • Register indirect / offset — adresas apskaičiuojamas naudojant registrą ir poslinkį.

Adresavimo metodai lemia, kiek baitų užims instrukcija ir kaip greitai ji bus vykdoma. Skirtingos architektūros (pvz., x86, ARM, RISC-V) turi skirtingus adresavimo tipus ir galimybes.

Vykdymo ciklas

Procesorius vykdo instrukcijas pagal paprastą ciklą: fetch → decode → execute (paimti, iššifruoti, vykdyti). Mašininiame kode instrukcijos patalpinamos atmintyje, procesorius jas paima, nustato opkodą ir operandus, tada atlieka nurodytą operaciją (aritmetinę, loginę, duomenų perkėlimo ar srautų valdymo operaciją).

Kaip susidaro mašininis kodas

Programų kūrėjai dažnai rašo programinį kodą aukštesnio lygio kalbomis arba asemblerio kodu. Toks kodas yra kompiliuojamas arba verčiamas į mašininį kodą. Asembleris paverčia žmogiškai skaitomą mnemoniką į atitinkamus opkodus ir operandus, o kompiliatorius ir nuorodų (linker) įrankiai sukuria vykdomąjį failą, kurį operacinė sistema gali užkrauti ir paleisti. Kai kurios sistemos naudoja interpretuojamas kalbas, kurių kodas vykdomas per tarpinį sluoksnį (pvz., virtualiąją mašiną), bet galutinis žingsnis visada yra instrukcijų pateikimas CPU suprantamu formatu.

Pavyzdžiai ir pabrėžtinės sąvokos

Mašininis kodas kartais vadinamas gimtuoju kodu. Jis vartojamas, kai kalbama apie dalykus, kurie veikia tik kai kuriuose kompiuteriuose ar architektūrose (t. y. nėra nešiojami tarp skirtingų architektūrų be perkompiliavimo arba emuliacijos). Mašininis kodas saugomas vykdomuosiuose failuose, įkeliamas į atmintį ir vykdomas procesoriaus.

Paprastas iliustracinis pavyzdys (konceptualus): instrukcija gali būti suskirstyta į laukus — pirmas laukas yra 4 baitų ilgio opkodas, kitas laukas nurodo registrą, o trečias laukas suteikia poslinkį arba tiesioginę reikšmę. Tiksli struktūra priklauso nuo konkrečios architektūros.

Priemonės ir darbai su mašininiu kodu

  • Asembleris – verčia asemblerio kodą į mašininį kodą.
  • Kompiliatorius – verčia aukšto lygio programavimo kalbą į mašininį kodą arba tarpinį kodą, vėliau į mašininį.
  • Disassembler/Debugger – atvirkštinė priemonė, rodanti mašininį kodą kaip mnemonikas arba heksadekaminę išraišką, kas padeda derinti programas.

Savybės ir apribojimai

Mašininis kodas yra labai efektyvus ir greitas, nes vykdomas tiesiogiai procesoriaus. Tačiau jis priklauso nuo procesoriaus architektūros: skirtingos architektūros turi skirtingus instrukcijų rinkinius, todėl mašininis kodas, parašytas vienai architektūrai, negalės būti vykdomas kitoje be perkompiliavimo arba emuliacijos. Dėl mažesnio skaitomumo žmogui, programuotojai dažniausiai rašo aukštesnio lygio kodu ir naudoja įrankius, kurie verčia ar generuoja mašininį kodą.

Apibendrinant: mašininis kodas yra tiesioginis procesoriaus vykdomas kodas, sudarytas iš opkodų ir operandų pagal tam tikros architektūros instrukcijų rinkinį. Jį sukuria assembleriai ir kompiliatoriai, o specialistai gali analizuoti arba redaguoti mašininį kodą naudodami disassemblerius, hex redaktorius ar debugerius.