Hoppa till innehållet

Maskinkod

Från Wikipedia
Ordet "Wikipedia" kodat i ASCII/UTF-8 (i det här fallet är kodningen identisk), visat som en följd av binära siffror.

Maskinkod (även kallat maskinspråk, binärkod eller native code) är det "språk" en processor direkt förstår och klarar att exekvera. Varje processortyp har sin särskilda maskinkod som är ett uttryck för dess instruktionsuppsättning. Ett datorprogram i något programspråk (den s.k. källkoden) kan antingen direkt tolkas och utföras via en interpretator eller översättas med en kompilator till maskinkod som i sin tur direkt kan köras, något som normalt ger bättre prestanda.

Maskinkod består av relativt enkla kommandon såsom "addera register B till register A", "jämför register A med innehållet i minnescell 123456", "hoppa till adress 234567 om det var lika" och dylikt. Varje sådan instruktion representeras av ett eller flera binära ord (binära tal med fix längd) vars längd (typiskt 8, 16, 32 eller 64 bitar) och precisa användning varierar med CPU-typ. En enkel operation, som att exempelvis omvandla en sträng av bokstäver till stora bokstäver, kan innebära många individuella maskinkodsinstruktioner. Varje instruktion består av ett eller flera ord som kodar för en viss operation, följd av eventuella argument i form av konstanter eller adresser, offset, etc. till platser där data lagras. Argument kan lagras i samma ord som operationskoden eller i separata ord beroende på ordlängd, arkitektur, och/eller instruktionstyp (då ordlängden vida överstiger vad som behövs för att representera alla operationer så används ofta resten av ordet för argument på något sätt, se instruktionsuppsättning).

Bitarna i en instruktion kan var och en direkt styra en funktion i processorn, till exempel så att en bit anger att ett visst register skall användas, en annan att det är frågan om addition, en tredje att en operand skall hämtas med en viss typs minnesadressering o.s.v. men normalt används rätt mycket avkodning för att begränsa antalet bitar och därmed spara minne; ursprungligen för att arbetsminnet var begränsat, men numera för att mer skall rymmas i cache-minnet och därmed ge bättre prestanda.

Maskinkod är ganska svårtolkad för människor; ett maskinkodsprogram består av sekvenser av binära ord utan någon uppenbar struktur. Utan att veta hur en specifik maskin indelar och tolkar dessa ord, kan man inte ens avgöra vilka av orden som är instruktioner eller data. Maskinen vet dock hur lång varje typ av instruktion (inklusive argument) är och när den har tolkat en instruktion så vet den därför var nästa instruktion ligger. För att underlätta manuell maskinspråksprogrammering använder man en "symbolisk maskinkod", assembler, där maskinkodens instruktioner representeras av korta "minnesord" (engelska: mnemonics) och symboliska (namngivna) minnesadresser och konstanter. Denna kod översätts sedan till maskinkod av en assemblator (omvänt av en disassembler). Om man arbetar med en enklare instruktions­uppsättning kan man göra assembleringen för hand, så kallad hand­assemblering.

Också om nästan alla datorprogram idag skrivs på något högnivåspråk (se programspråk), är förståelse för maskinkod väsentlig i speciella fall, till exempel då man skriver en kompilator eller en drivrutin för en hårdvaruenhet, då man optimerar kod som väsentligt påverkar ett datorprograms effektivitet eller då man söker efter vissa typer av fel.

Här är ett exempel på hur en instruktion kan se ut i assembler (för den virtuella processorn DCPU-16), det är ett SET-kommando som sätter innehållet vid minnesadressen '0x1040' (hexadecimal notation för 4160) till värdet 0x0001 (hex för 1). SET-instruktionen innebär alltså att man lagrar ett tal på ett speciellt ställe i minnet. Denna instruktion består av ett ord som kodar för en viss operation, i det här fallet SET, följd av argumenten i form av adress och värde.

SET    [0x1040], 0x0001

Som maskinkod blir detta (hexadecimalt och binärt, med mest signifikanta siffra först):

0x85E1 0x1040
1000 0101 1110 0001 0001 0000 0100 0000