Programmeren in TI-83+ Assembly/Controle/Loops
Met behulp van de voorwaarden is het mogelijk om loops te maken. Een loop (in het Nederlands lus) is een serie instructies die bepaalde opdrachten meerdere keren uitvoert. Hoeveel keer precies hangt af van het soort loop.
De While-loop
bewerkenDe While-loop bouwen we door eerst te kijken hoe je deze in woorden zou uitdrukken. Stel je een While-loop voor: While a=0
- Als a niet gelijk is aan 0, spring naar het einde van de loop.
- Voer bepaalde instructies uit.
- Ga nu terug naar het begin.
- Deze instructies worden uitgevoerd als a een keer niet gelijk is aan 0 geweest.
Dit kan als volgt worden omgezet in Assembly-code:
; stap 1 BeginLoop: cp 0 ; controleer of a gelijk is aan 0 jp nz, EindLoop ; als dat niet zo is, spring naar EindLoop ; stap 2 ; instructies ; stap 3 jp BeginLoop ; stap 4 EindLoop: ; instructies
Bij While-loops moet je oppassen voor oneindige loops. Zie het volgende voorbeeld:
ld a, 0 BeginLoop: cp 0 ; controleer of a gelijk is aan 0 jp nz, EindLoop ; als dat niet zo is, spring naar EindLoop inc b jp BeginLoop EindLoop: ; instructies
Dit zorgt voor een probleem: a blijft natuurlijk 0, omdat er in de instructies binnen de While-loop niets mee gebeurt. Het resultaat is bekend: het enige wat hiertegen nog kan worden gedaan, is de batterijen uit de rekenmachine halen.
De For-loop
bewerkenDe For-loop is een loop waarbij het aantal keren herhalen van te voren bekend is. Het is eigenlijk een speciaal soort While-loop, namelijk een While-loop waarbij bij iedere cyclus een teller ééntje verhoogd wordt. De voorwaarde is hierbij een controle of de teller een bepaald getal is. Bijvoorbeeld: je wilt een instructie vijf keer uitvoeren.
ld a, 0 BeginLoop: cp 5 ; controleer of a gelijk is aan 5 jp nz, EindLoop ; als dat niet zo is, spring naar EindLoop inc a jp BeginLoop EindLoop: ; instructies
Dit is goede code, maar hij kan wellicht beter. Het is immers niet handig om a te gebruiken voor de teller, aangezien dit ook het rekenregister is. Het is dus beter om b te gebruiken. Maar dan is het niet mogelijk een cp te gebruiken, aangezien dit alleen bij a kan. dec kan wél bij b gebruikt worden. Deze set de zero-vlag als het resultaat 0 is. Om het gebruik van dec mogelijk te maken, is het dus nodig om de teller steeds te verlagen, in plaats van hem te verhogen. Je begint bijvoorbeeld bij 5, en telt dan af tot 0. Als de teller 0 is, dan spring je uit de loop. Dit gaat dus als volgt.
ld b, 5 BeginLoop: ; instructies dec b ; b met 1 verlagen; als b niet 0 is, gaat de zero-vlag uit jp nz, BeginLoop ; als de zero-vlag uit is, ofwel als b niet 0 is, spring naar BeginLoop EindLoop: ; instructies
Of, korter:
ld b, 5 BeginLoop: ; instructies djnz BeginLoop ; is hetzelfde als dec b, jp nz BeginLoop EindLoop: ; instructies
Opdracht
bewerkenPas de opdracht van paragraaf 1 van dit deel aan, en gebruik nu een for-loop.
Een mogelijk antwoord zie je hier. Vul de standaardcode zelf aan. Deze oplossing is nog niet getest!
ld b, 4 BeginLoop: call TekstSchrijven ; TekstSchrijven aanroepen djnz BeginLoop ; Één aftrekken van b en als het resultaat niet 0 is, naar BeginLoop springen EindLoop: ret ; Terug naar de TI-OS. TekstSchrijven: ; Let op, níét PenCol instellen, want dan zouden de "Hallo!"'s iedere keer op dezelfde plek komen! 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 de hoofdmodule. Tekst: ; Label Tekst .db "Hallo!", 0 ; Voeg aan het programma de tekenreeks "Hallo!" toe, gevolgd door een nul.Opmerking: in dit geval is het niet veel korter, maar vooral bij 5 of meer herhalingen is dit erg nuttig.