RISCy business
Arnout van Kempen over rommelen in een digitale wereld.
Het grote voordeel van ARM ten opzichte van 80x86 is de RISC-architectuur. Door gebruik te maken van een beperkte instructieset zijn grote prestatievoordelen te behalen. Dat begint bij de fetch, decode, execute cyclus van de CPU. Iedere CPU doorloopt deze drie stappen. Een commando wordt uit het geheugen gehaald, gedecodeerd en uitgevoerd. De ARM voert deze stappen, net als de meeste moderne CPU’s, tegelijk uit. Dat wil zeggen: drie instructies na elkaar worden tegelijk verwerkt, steeds één stap verder. Maar de ARM doet iets slims om dat efficiënt te doen.
Ik gaf eerder al aan, assembly is niet de taal van de CPU, dat zijn nullen en enen, getallen dus. Het getal van een instructie heet de opcode, veelal gevolgd door de gegevens waarop de instructie betrekking heeft. Laten we wat opcodes van 8086 instructies vergelijken, alles hexadecimaal:
MOV AX, BX 89 D8
MOV AX, Ox1234 B8 34 12
MOV AX, [BX+SI+0x12] 8B 80 12 00
Nu drie ARM-instructies met hun opcode, weer een register naar register, een immediate waarde naar register en een geïndexeerd adres-inhoud naar register:
MOV X0, X1 AA 01 03 E0
MOV X0, 0x1234 D2 80 24 68
LDR X0, [X1, X2, LSL #2] F8 60 68 20
Op het eerste gezicht is de ARM inefficiënt. Immers, zelfs de eenvoudigste instructie, een move van het ene register naar het andere, heeft een opcode van 32 bits. De 8086 heeft hier slechts 16 bits voor nodig. Maar schijn bedriegt. De lengte van opcodes varieert bij de 8086 tussen de twee en zes bytes, terwijl de lengte bij de ARM altijd 4 bytes, dus 32 bits, is. En dat betekent dat de ARM niet al tijdens de fetch een eerste decode moet doen om te weten hoeveel bytes eigenlijk moeten worden gefetched. Dat maakt de ARM-fetch fase aanzienlijk simpeler en daarmee efficiënter en sneller.
Het heeft wel een prijs. Of eigenlijk twee. Om dat te doorzien, is het goed te bekijken hoe die 32 bits worden gebruikt. In de 32 bits zit informatie over de instructie zelf, de adresseringsmethode indien van toepassing, het gebruik van 32 of 64 bits registers (Wn of Xn dus), gegevens voor conditionele uitvoering, en eventuele immediate waarden of adressen. Als je je dat realiseert, begrijp je dat het aantal mogelijke instructies voor ARM veel kleiner is dan wat je met 32 bits zou kunnen coderen, want alle data moet óók in die 32 bits passen. Het aantal instructies is beperkt.
Maar ook het gebruik van data is beperkt. Immers, die data moet ook al in diezelfde 32 bits passen. Zo is de MOV-instructie niet in staat meer dan 16 bits tegelijk in een register te plaatsen. Dat schiet lekker op met een 64-bits register. Hoe dit op te lossen?
Op het niveau van de electronica heeft de ARM een "barrel shifter" die is geplaatst voor de ALU. En dat betekent dat een shift kan worden uitgevoerd voordat de feitelijke instructie wordt uitgevoerd. Nou en, zou je denken. Nou, dat is de oplossing. De ARM kent twee varianten op MOV, en die kan je combineren met een shift om zo alsnog 64 bits in een register te plaatsen. De instructies zijn MOVZ, waarmee een waarde vooraf wordt uitgevuld met nullen om in een register te passen, en MOVK waarmee alleen de aangeleverde bits in een register worden geplaatst, maar de rest onaangetast blijft. Als we nu de waarde 0x0123456789ABCDEF0 in X0 willen plaatsen, dan kan dat met de volgende instructies:
MOVZ X0, 0xDEF0, LSL #0 ; Laad de laagste 16 bits (0xDEF0) in X0
MOVK X0, 0x9ABC, LSL #16 ; Voeg de volgende 16 bits (0x9ABC) toe
MOVK X0, 0x5678, LSL #32 ; Voeg de volgende 16 bits (0x5678) toe
MOVK X0, 0x1234, LSL #48 ; Voeg de hoogste 16 bits (0x1234) toe
Met de eerste instructie plaats je het eerste blok van 16 bits rechts in X0 en maak je de rest leeg. Daarna plaats je ieder volgend blok van 16 bits er voor, door steeds verder naar links te shiften.
Ingewikkeld? Jawel. Maar het zorgt ervoor dat de ARM met 32 bits instructies kan werken, altijd.
Wie mee wil doen met #klooienmetcomputers kan dat doen via GitHub. Maak een account op github.com en zoek naar Abmvk/kmc. Het account Abmvk volgen kan ook. Lezers zijn vrij te gebruiken wat ze willen en om zelf zaken toe te voegen of aan te passen, vragen te stellen of commentaar te leveren.
Gerelateerd

Conditionele commando's
Arnout van Kempen over rommelen in een digitale wereld.

Basiscommando's
Arnout van Kempen over rommelen in een digitale wereld.

Automatiseren wat je kan
Arnout van Kempen over rommelen in een digitale wereld.

Vlagvertoon
Arnout van Kempen over rommelen in een digitale wereld.

Klein leed en moedig voorwaarts
Arnout van Kempen schrijft wekelijks over wat hij noemt "rommelen in een digitale wereld". Deze week alweer editie 100 van zijn 'nerd-rubriek' voor liefhebbers.