Programmeren in TI-83+ Assembly/Registers en procedures/De OP-registers

Uit Wikibooks
Naar navigatie springen Naar zoeken springen

Programmeren in TI-83+ Assembly


Optellen en aftrekken in Assembly is al een vrij moeilijke aangelegenheid. Vermenigvuldigen gaat nog veel ingewikkelder en delen gaat bijna niet. Verder kun je in Assembly alleen maar met gehele getallen werken. Hoe kan het besturingssysteem dan de rekensommen uitrekenen die door de gebruiker worden ingegeven? TI heeft daarvoor de OP-registers bedacht. Dat zijn plaatsen in het geheugen waarin kommagetallen kunnen staan. Met die OP-registers kun je gemakkelijker rekenen.

Wat zijn OP-registers?[bewerken]

Alhoewel de naam anders doet vermoeden, zijn de OP-registers feitelijk geen registers. Eigenlijk zijn het stukjes van het geheugen. Zoek maar eens in ti83plus.inc naar OP1, dan zie je dat deze zich bevindt op adres $8478 en volgende. OP2 bevindt zich op $8483, enz. Er zijn in totaal zes OP-registers. In deze registers kan een kommagetal worden opgeslagen in de wetenschappelijke notatie. Je kunt er bijvoorbeeld ook het getal 5,22·10^74 in kwijt.

Het voordeel van OP-registers is dat TI allerlei bcalls heeft meegegeven aan het besturingssysteem om ermee te rekenen. Er zijn bijvoorbeeld bcalls om op te tellen, af te trekken, enzovoorts.

De structuur van een OP-register[bewerken]

De structuur van een OP-register is vrij ingewikkeld. Zie de afbeelding hieronder.

Assembly OP-registers.png

Een OP-register bestaat dus uit in totaal 11 bytes:

  • Byte 1 is het teken van het getal (positief of negatief). Dit kan twee waarden aannemen: $00 betekent positief en $80 betekent negatief.
  • Byte 2 is de exponent van de tien-macht. Bijvoorbeeld bij 5,22·10^74 is de exponent 74. Maar wat nu als de exponent kleiner is dan 0? Je kunt immers geen negatief getal opslaan in een byte. Daarom wordt iedere exponent vermeerderd met $80 (= 128). Het resultaat is dus (voor 5,22·10^74) 128 + 74 = 202 = $CA. Voor negatieve exponenten wordt de uitkomst dus kleiner dan $80.
  • Byte 3-9 bevatten de echte cijfers van het getal. Vreemd genoeg wordt het getal decimaal opgeslagen: ieder cijfer komt in een halve byte (dus 4 bits) te staan. Voor ons getal 5,22·10^74 wordt dat dus $52, $20, $00, $00, ... De hexadecimale waarden A-F kunnen dus nooit worden gebruikt. Het getal wordt altijd in strikt wetenschappelijke notatie opgeslagen, dus precies één cijfer voor de komma. Het getal 10 sla je dus op als 1,0·10^1. Op deze manier weet de TI waar de komma valt.
  • Byte 10-11 bevatten vier extra cijfers, die nodig zijn om de precisie bij rekensommen te garanderen. Stel je voor dat je 100 deelt door 3 en het resultaat in OP1 zet. Stel dat er dan geen extra cijfers waren, en we het getal weer met 3 zouden vermenigvuldigen, dan zou het resultaat 99,99999... zijn in plaats van 100. Om dit soort afrondingsfouten te voorkomen, rekent de TI met 4 cijfers extra.

Een getal in een OP-register zetten[bewerken]

Om een getal in een OP-register te laden, moet je de benodigde 9 bytes (de extra cijfers hoef je niet mee te nemen) eerst ergens in het geheugen zetten, bijvoorbeeld onderaan het programma. Laad daarna in hl het geheugenadres van de eerste byte van de te kopiëren data. Roep daarna de bcall _Mov9ToOPx aan (met x is 1 of 2). Deze bcall laadt de negen bytes, te beginnen bij (hl), in OP1 of OP2. Het voorbeeld hieronder laadt de eerste decimalen van π in OP2.

    ld hl, GetalPi
    bcall(_Mov9ToOP2)

GetalPi:
    .db $00, $80, $31, $41, $59, $26, $53, $58, $97

Rekenen met OP-registers[bewerken]

Nu komen we bij het doel van het gebruik van OP-registers. Er is een gigantische hoeveelheid bcalls om met OP's te rekenen.

Deze tabel is nog in opbouw: alle beschrijvingen met (?) zijn nog niet gecontroleerd.

_Plus1 OP1 = OP1 + 1 _Cube OP1 = OP1³
_Minus1 OP1 = OP1 - 1 _DToR OP1 wordt omgezet van graden naar radialen (??)
_FPAdd OP1 = OP1 + OP2 _RToD OP1 wordt omgezet van radialen naar graden (??)
_FPSub OP1 = OP1 - OP2 _LnX OP1 = ln(OP1) (?)
_FPMult OP1 = OP1 × OP2 _LogX OP1 = log(OP1) (met grondtal 10) (?)
_FPDiv OP1 = OP1 ÷ OP2 _Sin OP1 = sin(OP1) (?) (OP1 in graden of radialen?)
_FPRecip OP1 = 1 ÷ OP1 _Cos OP1 = cos(OP1) (?) (OP1 in graden of radialen?)
_FPSquare OP1 = OP1² _Tan OP1 = tan(OP1) (?) (OP1 in graden of radialen?)
_SqRoot OP1 = √OP1

Er zijn nog veel meer bcalls om met OP's te rekenen; je vindt ze in ti83plus.inc.

Andere acties met OP-registers[bewerken]

Opdracht[bewerken]

Maak een programma dat π (=3,141592653589793) vermenigvuldigt met 2, en er daarna 2,37 vanaf haalt. Het resultaat moet daarna op het scherm worden geschreven.

Klap uit voor het antwoord
Het antwoord moet nog worden gemaakt.

Het antwoord staat achterin het boek.

ArrowLeftNavbox.svg ← De instructies call en ret De OP-registers Toets → ArrowRightNavbox.svg
Informatie afkomstig van http://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.