De Program Counter
De PC is de program counter, of programma teller. Dit is een 16-bits register dat steeds het adres bevat van de instructie die als eerstvolgende moet worden uitgevoerd. Dit register bevat dus steeds het adres van een byte in het programmageheugen.
Zodra de CPU een instructie gaat uitvoeren, wordt het byte waar de PC op wijst uit het programmageheugen opgehaald, en de PC wordt met één verhoogd zodat hij nu op de volgende locatie in het programmageheugen wijst. Het uit het geheugen opgehaalde byte wordt geïnterpreteerd als een instructie. Na decoderen van de instructie wordt een begin gemaakt met het uitvoeren ervan. Dit kan betekenen dat ook een volgend byte uit het programmageheugen moet worden opgehaald (waarna de PC weer wordt verhoogd.) Er zijn instructies van één byte, maar sommige instructies kunnen wel 5 bytes lang zijn.
Nadat alle bytes van de huidige instructie zijn opgehaald, wijst de PC op het eerstvolgende byte in het programmageheugen, en wijst dus naar een nieuwe instructie die de processor kan gaan uitvoeren wanneer de zojuist opgehaalde instructie klaar is. Meestal is dit ook de instructie die als volgende uitgevoerd zal worden, maar er bestaan ook instructies die de inhoud van de PC aanpassen. Hierdoor hoeft een programma niet steeds in dezelfde volgorde doorlopen te worden, maar kan de loop van het programma veranderen (bijvoorbeeld op grond van de uitkomst van bepaalde berekeningen die de CPU gedaan heeft.)
Veranderingen in de loop van het programma
Zoals boven beschreven, is de 'normale' gang van zaken dat instructies worden uitgevoerd in de volgorde waarin ze in het programmageheugen staan. Een uitzondering treedt op, wanneer een instructie wordt uitgevoerd die de inhoud van de program counter veranderd. Hiervoor bestaan verschillende mogelijkheden:
Een 'jump' (sprong) instructie leidt ertoe dat een nieuwe waarde aan de program counter wordt toegekend. Deze nieuwe waarde staat expliciet in de instructie, of wordt uit één van de registers genomen. Het eenvoudigste voorbeeld is:
<adres> <instructie>
$B600 JMP $B73F De PC wordt geladen met $B73F
$B603 ....
....
....
$B73F STOP Na de JMP instructie wordt deze instructie uitgevoerd.
Na de instructie JMP worden nog twee bytes opgehaald. De processor weet dat bij deze JMP instructie nog twee bytes horen, en dat deze twee bytes in de PC moeten worden gezet.
De instructie 'JMP $B73F' zal ertoe leiden dat de program counter wordt geladen met het getal $B73F, waardoor de volgende instructie van adres $B73F wordt gelezen.
Een 'branch' (vertakking) instructie wordt gebruikt om de program counter een stukje te 'verschuiven'. Het aantal bytes dat de program counter verschoven moet worden is opgegeven in de instructie. De meeste van deze 'branch' instructies zijn conditioneel (onder voorwaarde.) De verschuiving is dan afhankelijk van het resultaat van een vorige berekening. Een voorbeeld is de instructie 'BEQ' (branch if equal):
<adres> <instructie>
$B600 BEQ 5
$B602 .... Als het resultaat van de vorige berekening niet 0 is, gaat het
programma op deze plaats verder.
....
....
$B607 STOP Als het resultaat van de vorige berekening wel 0 is, gaat het
programma meteen op deze plaats verder.
De instructie 'BEQ 5' (branch if equal) zal:
- als het resultaat van de laatste berekening 0 is: 5 bij de program counter optellen. Bedenk dat de PC na het lezen van de instructie 'BEQ 5' (die twee bytes lang is), al op de volgende instructie wijst (dus twee bytes verder dan de plaats waar de BEQ instructie staat.) Het getal 5 wordt bij déze waarde opgeteld.
- als het resultaat van de laatste berekening ongelijk aan 0 is: de inhoud van de program counter niet veranderen.
Een speciaal geval van de 'jump' instructie is de 'jsr' (jump to subroutine) instructie. Bij een subroutine wordt de program counter met een nieuw adres geladen, maar de oude inhoud van de program counter wordt eerst bewaard. Hierdoor is het mogelijk later terug te keren naar de plaats in het programma vanwaar de subroutine werd gestart. De oude inhoud van de program counter wordt bewaard op de 'stack' (zie hiervoor ook verderop onder 'stackpointer'.)
Terugkeer naar de plaats vanwaar de subroutine werd gestart kan door middel van de 'RTS' (return from subroutine) instructie. Deze instructie zorgt ervoor dat het op de stack bewaarde oude adres weer in de program counter wordt gezet. De eerstvolgende instructie die daarna wordt uitgevoerd is dan de instructie die onmiddellijk volgt op de 'jsr' instructie.
<adres> <instructie>
$B600 JSR $B63F De PC (die na lezen van deze instructie de waarde $B603 heeft)
wordt op de stack bewaard, en geladen met $B63F.
$B603 STOP
.... andere instructies van het programma
....
....
$B63F .... Dit is de eerste instructie van de subroutine
....
....
RTS Deze instructie leest de oorspronkelijke waarde van de program counter van
de stack, en plaatst deze terug in de PC. Hierdoor wordt het programma
vervolgd op adres $B603 (de 'STOP' instructie.)
|