Opkods (no angļu val. opcode — operation code) ir instrukcijas daļa mašīnkodā, kas norāda, kāda pamatoperācija jādatora procesoram veic. Parasti viena mašīnvalodas instrukcija sastāv vismaz no opkoda un vienas vai vairākām operandu daļām: opkods ir kā darbības vārds teikumā, bet operandi — kā priekšmets vai papildinājumi, kas norāda, uz ko darbība jāpiemēro (piemēram, reģistra nosaukums, atmiņas adrese vai tūlītēja (immediate) vērtība). Operandi var ietvert reģistru numurus, adreses vai oktetus, kas norāda datu atrašanās vietu.
Kā opkods darbojas
Instrukcija procesorā tiek kodēta kā binārs vārds, kurā viens vai vairāki biti atvēlēti opkoda laukam, bet pārējie — operandiem, adresēšanas režīma informācijai, papildu bajtiem u. c. Opkoda vērtība nosaka, kura aparatūras loģika tiks aktivēta (piem., saskaitīšana, pārvietošana, salīdzināšana, nosacīta zara veikšana). Atkarībā no arhitektūras opkods var aizņemt vienu bitu lauku (ļoti reti) līdz vairākām bajtiem; dažās arhitektūrās (piem., x86) instrukcijas garums var būt mainīgs, bet RISC arhitektūrās instrukcijas parasti ir fiksēta garuma (bieži 32 biti).
Reprezentācija un lasāmība
Pēc būtības opkodi ir binārās vērtības, jo procesors strādā ar bitiem. Lai ērtāk lasītu un rakstītu, tās bieži attēlo ar heksadecimālām vērtībām (piem., binārais 10100101 = heksadecimāli A5) vai izmanto asemblera mnemonikas (lasāmus atslēgas vārdus). Asemblejā ierasts rakstīt opkoda mnemoniku (piem., ADD, MOV, LOAD, STORE), bet zemā līmenī tās tiek pārveidotas par atbilstošo bināro/heksadecimālo kodu, ko izpilda procesors.
Adresēšanas režīmi un papildu lauki
Instrukcijā blakus opkodam var būt lauki, kas nosaka adresēšanas režīmu (piem., tūlītēja vērtība, reģistra saturs, atmiņas adrese, reģistru indirektā adresācija), kā arī papildu modifikatori (piem., ātruma optimizācijas bitu slēdzēji, nosacījumu kodi). Dažās arhitektūrās opkoda bits var tikt kombinēts ar papildu lauciņiem, kas kopā definē plašāku instrukciju kopu.
RISC pret CISC
Instrukciju kopas veidošanas pieejas ietekmē arī opkodu daudzveidību:
- RISC (reduced instruction set computer) — mazāks un vienkāršāks opkodu komplekts, fiksēta instrukcijas garuma arhitektūra, kur instrukcijas veic vienkāršas operācijas, bieži vien ar ātru izpildi un vienkāršu dekodēšanu.
- CISC (complex instruction set computer) — plašāks opkodu klāsts ar daudzveidīgām, bieži kompleksām instrukcijām un dažādiem adresēšanas režīmiem; instrukcijas var būt mainīga garuma un saturēt daudz loģikas vienā komandrindā.
Praksē abu pieeju atšķirības ir saistītas ar kompromisiem starp aparatūras vienkāršību, izpildes ātrumu, atmiņas izmantošanu un programmēšanas ērtumu.
Asembleervaloda, mnemonikas un augstākā līmeņa valodas
Programmētāji reti tieši rediģē bināros opkodus. Asemblejā rakstot, izmanto mnemonikas un sintaksi, ko pārvērš par mašīnkodu ar asemblēšanas (assembler) programmu. Tādejādi programmētājam nav jāatceras konkrētā opkoda binārā vērtība, tikai mnemonika un reģistru/operandju kārtība. Ja izmanto augsta līmeņa programmēšanas valodu, kompilators vai tulks veiks virkni pārveidojumu (no augstākā līmeņa uz zemākiem līmeņiem) līdz galīgajam mašīnkodam, padarot programmu portablāku starp dažādām arhitektūrām.
Piemēri un izmantošanas gadījumi
Opkodi tiek lietoti ļoti dažādām darbībām: aritmētiskām operācijām (ADD, SUB), loģiskām operācijām (AND, OR), datu pārvietošanai (MOV, LOAD, STORE), zaru instrukcijām (nosacītas/nenosacītas skokiem), sistēmas zvaniem un citiem speciāliem uzdevumiem. Piemēram, x86 arhitektūrā opkods 0x89 bieži apzīmē instrukciju MOV r/m32, r32; citās arhitektūrās tā pati heksadecimālā vērtība var nozīmēt pilnīgi citu instrukciju.
Opkodi reversajai inženierijai un emulācijai
Disassembleri un emulācijas rīki izmanto opkodus, lai parādītu izpildāmo kodu saprotamā formā — pārvēršot bināro saturu par asemblervalodas mnemonikām. To izmanto gan programmu atkļūdošanai, gan drošības pārbaudēm vai programmatūras emulācijai dažādām arhitektūrām.
Kopsavilkums
Opkods ir pamatkomponents instrukcijas formātā, kas norāda, kura aparatūras operācija jāveic. Tā forma, garums un nozīme ir atkarīga no datora instrukciju kopas arhitektūras. Lai strādātu ērti, programmētāji izmanto asemblervalodu un mnemonikas, bet zemākā līmenī visas instrukcijas tiek saglabātas kā binārie/heksadecimālie opkodi, ko izpilda procesors.