Programmeren in TI-83+ Assembly/Assembly-basis/Variabelen
Registers zijn perfect om gegevens op te slaan die je direct weer nodig hebt. Maar gegevens die je voor langere tijd nodig hebt, moet je dus vooral niet in een register zetten (zie einde hoofdstuk 3). Daarom is er nog een andere mogelijkheid om gegevens op te slaan, namelijk variabelen: een plek in het geheugen waar je data in kunt zetten. In veel programmeertalen zijn er vaste structuren voor variabelen. In Assembly moet je een variabele echter zelf een geheugenadres toewijzen.
Een variabele toewijzen
bewerkenWat is nu eigenlijk een variabele? In feite is het alleen een plek in het RAM-geheugen (voortaan hebben we het in dit boek gewoon over "het geheugen"), met daarin gegevens. Deze plek kan worden aangesproken door een geheugenadres te geven, dit is een getal dat de "cel" in het geheugen aangeeft waar de gegevens in staan.
Echter, het geheugen wordt ook gebruikt door allerlei andere dingen op de TI, zoals het besturingssysteem en de gebruikersvariabelen. We willen dit natuurlijk niet overschrijven. Er zijn twee manieren om ervoor te zorgen dat je op een 'vrije' plaats schrijft. Als eerste kun je een plek kiezen waarvan je weet dat hij niet wordt gebruikt. Dit leer je in Het gebruik van EQU in hoofdstuk 3. De tweede manier is om je programma als het ware wat langer te maken, zodat je ruimte overhoudt waar je de gegevens in kunt zetten. Dit is helemaal niet moeilijk, je moet alleen de assembler een (of meerdere) extra byte(s) laten toevoegen. Dit kan met de directive (opdracht voor de assembler) .db
. De code hieronder plaatst een extra byte op de plek waar de directive in het programma staat, en plaatst er het cijfer 2 in.
.db 2
Om het geheugenadres zodadelijk gemakkelijk te kunnen opvragen, zetten we een label voor de variabele. Dit ziet er dan als volgt uit:
Variabele:
.db 2
De assembler onthoudt nu het geheugenadres voor ons, en we kunnen dat straks makkelijk opvragen.
Een variabele uitlezen
bewerkenAls we nu een variabele willen uitlezen, en de data die erin staat bijvoorbeeld in een register willen plaatsen, kunnen we dit doen:
ld a, (Variabele)
Dit mag overigens alleen bij a
, als je het resultaat in b
(of een ander register) wilt zetten moet je het via hl
doen:
ld hl, Variabele
ld b, (hl)
De processor heeft namelijk geen instructie voor ld b, (Variabele)
. Een andere manier is natuurlijk om het resultaat eerst in a
te zetten en het daarna te verplaatsen naar b
; dat zou je nu zelf moeten kunnen.
Een variabele beschrijven
bewerkenEen variabele schrijven gaat op dezelfde manier:
ld (Variabele), a
Ook hier geldt dat de processor geen instructie heeft voor ld (Variabele), b
, en trouwens ook niet voor ld (Variabele), 5
of iets dergelijks, dus dat moet weer via hl
:
ld Variabele, hl
ld (hl), b
Je kunt wel rechtstreeks hl
naar een variabele schrijven:
ld (Variabele), hl
Let dan wel op: hl
beslaat twee bytes en daarom wordt ook het adres Variabele + 1
beschreven. Verder wordt l
in Variabele
gezet, en h
in Variabele + 1
, een fenomeen dat big endian genoemd wordt. In het hoofdstuk Geheugenbeheer leer je meer hierover.
Tekst op het scherm schrijven
bewerkenEen voorbeeld van het gebruik van variabelen vind je als je tekst op het scherm wilt schrijven. Het TI-OS wil dan namelijk weten waar je tekst in het geheugen staat, en dat kun je dus met een label doen. Hier volgt een voorbeeldprogramma dat tekst op het scherm schrijft.
; Vul de standaardcode zelf aan (zie hoofdstuk 2).
bcall(_ClrLCDFull) ; Eerst maken we het scherm leeg.
ld hl, 0 ; Laad 0 in hl.
ld (CurCol), hl ; Laad nu hl=0 in de kolom van schrijven.
ld hl, Tekst ; Laad het label in hl.
bcall(_PutS) ; Zet de tekst, die staat vanaf hl (dus het label) op het scherm.
bcall(_NewLine) ; Zet de cursor op de volgende regel op kolom 0.
ret ; Terug naar het TI-OS.
Tekst: ; Label Tekst
.db "Hallo!", 0 ; Voeg aan het programma de tekenreeks "Hallo!" toe, gevolgd door een nul.
Ik zal nu stukje voor stukje uitleggen wat er gebeurt.
bcall(_ClrLCDFull) ; Eerst maken we het scherm leeg.
Voordat we op het scherm gaan schrijven, wordt het leeggemaakt om te voorkomen dat we over iets anders heen schrijven.
ld hl, 0 ; Laad 0 in hl.
ld (CurCol), hl ; Laad nu hl=0 in de kolom van schrijven.
Dit is de code om de (CurCol)
(dat is de kolom waarin we gaan schrijven) 0 te maken. Om precies te zijn is (CurCol)
ook een 'variabele', maar dan
ld hl, Tekst ; Laad het label in hl.
Nu wordt het geheugenadres van het label Tekst
geladen in het register hl
. Dit zou bijvoorbeeld $8000 kunnen zijn. Zie de volgende regel voor de reden waarom we dit doen.
bcall(_PutS) ; Zet de tekst, die staat vanaf hl (dus het label) op het scherm.
Dit is een nieuwe bcall. Hij zet de tekst, die begint bij hl
, op het scherm. Hierbij houdt hij rekening met (CurCol)
. Het resultaat is dus dat "Hallo!" op het scherm wordt gezet. De bcall stopt met schrijven als hij een 0 tegenkomt (geen teken "0" maar het cijfer).
bcall(_NewLine) ; Zet de cursor op de volgende regel op kolom 0.
De cursor wordt nu naar de volgende regel verplaatst, zodat de tekst op de volgende regel komt, als we nog iets zouden willen schrijven. Het is altijd een goed idee om dit te doen, en bovendien verschijnt "Done" nu op de juiste plaats.
ret ; Terug naar het TI-OS.
Dit moet nu duidelijk zijn. Zie anders hoofdstuk 2.
Tekst: ; Label Tekst
.db "Hallo!", 0 ; Voeg aan het programma de tekenreeks "Hallo!" toe, gevolgd door een nul.
Het label Tekst
is dus eigenlijk een geheugenadres. Hierop wordt dan met de opdracht .db
"Hallo!" gezet. Daarachter volgt een 0, omdat de _PutS
zoals gezegd stopt als hij een 0 tegenkomt. Haal de 0 maar eens weg en kijk (op de emulator!) wat er gebeurt.
Opdracht
bewerkenHet is belangrijk dat je dit onderwerp goed begrijpt. Daarom zijn er drie opgaven, gerangschikt van makkelijk naar moeilijk.
Opdracht 1
bewerken
Maak een programma met een variabele Getal
, die aan het begin van het programma 0 bedraagt. Aan het eind van het programma moet de variabele 2 bedragen.
Opdracht 2
bewerkenMaak een programma dat je naam, adres en woonplaats onder elkaar op het scherm zet.
Opdracht 3
bewerkenMaak een programma dat vier mededelingen bevat, bijvoorbeeld op de adressen (labels) Mededeling1
, Mededeling2
, enzovoorts. Het is de bedoeling dat er in een variabele een van deze vier labels staat (vast ingeprogrammeerd), en dat dan de betreffende mededeling wordt weergegeven. Door de variabele te wijzigen in een ander van de vier labels, wordt dan dus een andere mededeling weergegeven. Let op: om een variabele te maken voor een geheugenadres (dus 2 bytes), moet je .dw
gebruiken en niet .db
(de w staat voor Word, dat is 2 bytes).
De antwoorden staan achterin het boek.