Het grootste deel van de inhoud van dit antwoord kwam oorspronkelijk van dit antwoord (geschreven voordat die andere vraag als een duplicaat werd gemarkeerd). Dus ik bespreek het gebruik van 8-bits waarden (hoewel deze vraag over 32-bits waarden ging), maar dat is oké omdat 8-bits waarden conceptueel eenvoudiger te begrijpen zijn, en dezelfde concepten gelden voor grotere waarden zoals 32-bits rekenen.
Als u twee getallen optelt die 8-bits zijn, is dat het grootste getal dat u kunt krijgen (0xFF + 0xFF = 1FE). In feite, als je twee getallen vermenigvuldigt die 8-bits zijn, is het grootste getal dat je kunt krijgen (0xFF * 0xFF = 0xFE01) nog steeds 16 bits, twee keer van 8-bits.
Nu kun je ervan uitgaan dat een x-bit processor alleen x-bits kan bijhouden. (Bijvoorbeeld, een 8-bit processor kan slechts 8 bits bijhouden.) Dat is niet accuraat. De 8-bit processor ontvangt gegevens in 8-bit brokken (deze “brokken” hebben meestal een formele term: een “woord”. Op een 8-bits processor worden 8-bits woorden gebruikt. Op een 64-bits processor kunnen 64-bits woorden worden gebruikt.)
Dus, als je de computer 3 bytes geeft:
Byte #1: de MUL instructie
Byte #2: de hoge orde bytes (bijv. 0xA5)
Byte #3: de lagere orde bytes (bijv. 0xCB)
De computer kan een resultaat genereren dat meer dan 8 bits is. De CPU kan resultaten als deze genereren:
0100 0000 0100 0010 xxxx xxxx xxxx xxxx 1101 0111
a.k.a.:
0x4082xxxxD7
Nu, laat me dat voor u interpreteren:
0x betekent gewoon dat de volgende cijfers hexadecimaal zijn.
Ik zal de “40” even in detail bespreken.
82 maakt deel uit van het “A” register, wat een serie van 8 bits is.
xx en xx maken deel uit van twee andere registers, genaamd het “B” register en het “C” register. De reden dat ik die bits niet heb gevuld met nullen of enen is dat een “ADD”-instructie (gestuurd naar de CPU) ertoe kan leiden dat die bits onveranderd blijven door de instructie (terwijl de meeste andere bits die ik in dit voorbeeld gebruik veranderd kunnen worden, behalve sommige van de vlagbits).
D7 zou in meer bits passen, genaamd het “D”-register.
Een register is slechts een stukje geheugen. Registers zijn ingebouwd in de CPU’s, zodat de CPU toegang heeft tot registers zonder dat er interactie met het geheugen op een RAM-stick nodig is.
Dus het wiskundige resultaat van 0xA5 maal 0xCB is 0x82D7.
Nu, waarom zijn de bits gesplitst in de A en D registers in plaats van de A en B registers, of de C en D registers? Nou, nogmaals, dit is een voorbeeldscenario dat ik gebruik, bedoeld om in concept vrij gelijkaardig te zijn aan een echte assemblagetaal (Intel x86 16-bit, zoals gebruikt door de Intel 8080 en 8088 en veel nieuwere CPU’s). Er kunnen een aantal gemeenschappelijke regels zijn, zoals het “C”-register dat typisch wordt gebruikt als een index voor het tellen van operaties (typisch voor lussen), en het “B”-register dat wordt gebruikt voor het bijhouden van offsets die helpen bij het specificeren van geheugenlocaties. Dus, “A” en “D” kunnen meer gebruikelijk zijn voor sommige van de gemeenschappelijke rekenkundige functies.
Elke CPU-instructie zou enige documentatie moeten hebben, gebruikt door mensen die programmeren in Assembly. Die documentatie zou moeten specificeren welke registers door elke instructie worden gebruikt. (De keuze van de te gebruiken registers wordt dus vaak gespecificeerd door de ontwerpers van de CPU, niet door de programmeurs van de Assembly-taal. Hoewel, er kan enige flexibiliteit zijn.)
Nu, terug naar de “40” in het bovenstaande voorbeeld: dat is een serie bits, vaak het “vlaggenregister” genoemd. Elk bit in het vlaggenregister heeft een naam. Er is bijvoorbeeld een “overflow” bit dat de CPU kan instellen als het resultaat groter is dan de ruimte die een byte van de resultaten kan opslaan. (Het “overflow”-bit wordt vaak aangeduid met de verkorte naam “OF”. Dat is een hoofdletter o, geen nul). Software kan de waarde van deze vlag controleren en het “probleem” opmerken. Het werken met dit bit wordt vaak onzichtbaar behandeld door talen van een hoger niveau, dus beginnende programmeurs leren vaak niet hoe ze met de CPU-vlaggen moeten omgaan. Echter, assemblage programmeurs hebben vaak toegang tot sommige van deze vlaggen op een manier die erg lijkt op andere variabelen.
Bijvoorbeeld, je kunt meerdere ADD instructies hebben. Eén ADD instructie kan 16 bits van de resultaten in het A register en het D register opslaan, terwijl een andere instructie gewoon de 8 lage bits in het A register kan opslaan, het D register kan negeren en de overloopbit kan specificeren. Later (na het opslaan van de resultaten van het A-register in het hoofdgeheugen) zou u een andere ADD-instructie kunnen gebruiken die alleen de 8 hoge bits in een register opslaat (mogelijk het A-register.) Of u een overloopvlag moet gebruiken, kan afhangen van welke vermenigvuldigingsinstructie u gebruikt.
(Er is ook vaak een “underflow” flag, voor het geval je te veel aftrekt om in het gewenste resultaat te passen.)
Om je te laten zien hoe ingewikkeld het is:
De Intel 4004 was een 4-bit CPU
De Intel 8008 was een 8-bit CPU. Het had 8-bits registers met de namen A, B, C en D.
De Intel 8086 was een 16-bits CPU. Het had 16-bits registers met de naam AX, BX, CX en DX.
De Intel 80386 was een 32-bit CPU. Het had 32-bits registers met de namen EAX, EBX, ECX en EDX.
De Intel x64 CPU’s hebben 64-bits registers met de namen RAX, RBX, RCX en RDX. De x64-chips kunnen 16-bits code uitvoeren (in sommige bedrijfsmodi) en kunnen 16-bits instructies interpreteren. Daarbij zijn de bits waaruit het AX-register bestaat de helft van de bits waaruit het EAX-register bestaat, wat de helft is van de bits waaruit het RAX-register bestaat. Dus wanneer u de waarde van AX verandert, verandert u ook de EAX en RAX, omdat de bits die door AX worden gebruikt deel uitmaken van de bits die door RAX worden gebruikt. (Als u EAX verandert met een waarde die een veelvoud is van 65.536, dan zijn de lage 16 bits onveranderd zodat AX niet zou veranderen. Als je EAX verandert met een waarde die geen veelvoud is van 65,536, dan zou dat ook invloed hebben op AX.)
Er zijn meer vlaggen en registers dan alleen de vlaggen en registers die ik heb genoemd. Ik heb eenvoudigweg enkele veelgebruikte vlaggen gekozen om een eenvoudig conceptueel voorbeeld te geven.
Nu, als je op een 8-bit CPU zit, kan het zijn dat je, wanneer je naar het geheugen schrijft, wat beperkingen vindt om te kunnen verwijzen naar een adres van 8-bits, niet naar een adres van 4 bits of 16-bits. De details zullen variëren op basis van de CPU, maar als u dergelijke beperkingen heeft, dan kan de CPU te maken hebben met 8-bits woorden, daarom wordt de CPU meestal aangeduid als een “8-bits CPU”.