Bascom ganzzahlige Division mit Rest

Dieses Thema im Forum "Software" wurde erstellt von LotadaC, 3. Juni 2018.

  1. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.925
    Zustimmungen:
    44
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Hallo.

    Manchmal, insbesondere wenn man eine Zahl in Dezimalstellen zerhacken will, benötigt man sowohl den Quotienten als auch den Rest einer ganzzahligen Division.
    In der Praxis sieht man dann oft solche Code-Stücke:
    Man erkennt also: bei n-Stellen sind es n Modulo-Divisionen und n-1 Divisionen (die n-1 Subtraktionen sind hier unnötig).
    Jetzt erinnern wir uns an die Schriftliche Division aus der Grundschule:
    Code:
    2537 : 17 = 
    Code:
    2537 : 17 = 1
    Code:
    2537 : 17 = 1
    17
    --
    08
    Code:
    2537 : 17 = 1
    17
    --
    083
    Code:
    2537 : 17 = 14
    17
    --
    083
     68
     --
     15
    Code:
    2537 : 17 = 149
    17
    --
    083
     68
     --
     157
     153
     ---
       4
    BASCOM macht quasi dasselbe, nur eben binär. Das ganzzahlige Ergebnis hier wäre also die "149".
    Der Rest "4" ist auch vorhanden - wo läßt BASCOM den?

    Das kommt darauf an:
    • werden Bytes dividiert, läßt BASCOM den Rest in Register 24 liegen (den Quotienten in Register 16)
    • bei Words und Integern verbleibt der Rest in den Registern 17..16 (MSB..LSB) (der Quotient in R21..R20)
    • bei Long verbleibt der Rest in den Registern 19..16 (MSB..LSB) (der Quotient in R23..R20)
    Und wie kommt man da ran?
    Indem man das/die Register sofort nach der Division in die entsprechende Variable schreiben läßt.
    Bei Bytes also:


    CodeBox BascomAVR
    Quotient=Divident\Divisor
    STS {Rest}, R24

    Bei Words/Integern:


    CodeBox BascomAVR
    Quotient = Divident \ Divisor
    STS {rest}, r16
    STS {rest+1}, r17
    

    Bei Long zusätzlich noch R18 und R19 "Storen"

    Somit sollte sich der Code von oben, den @Thorsten_Sch uns freundlicherweise bereitgestellt hatte, wie folgt vereinfachen lassen:

    CodeBox BascomAVR
    Tausender=Zahl_temp\10
    STS {Einer}, R16
    STS {Einer+1}, R17
    Tausender=Tausender\10
    STS {Zehner}, R16
    STS {Zehner+1}, R17
    Tausender=Tausender\10
    STS {Hunderter}, R16
    STS {Hunderter+1}, R17
    

    Nur noch drei Divisionen.

    P.S. @dino03 : Kannst Du diesen Beitrag bitte in die FAQ-Übersicht aufnehmen?
     
    #1 LotadaC, 3. Juni 2018
    Zuletzt bearbeitet: 12. Juni 2018
  2. Thorsten_Sch

    Thorsten_Sch Mitglied

    Registriert seit:
    31. Oktober 2010
    Beiträge:
    147
    Zustimmungen:
    0
    Punkte für Erfolge:
    16
    Sprachen:
    BascomAVR
    super verstehe nur bahnhof
     
  3. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.925
    Zustimmungen:
    44
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Hm...
    Wo soll ich anfangen?
    Grundsätzliche Informationen zur Harvard-Architektur der AVR findest Du in Dinos "Dampmaschin-Thread".
    Die AVR sind 8Bit-Controller, nahezu alle Operationen basieren also auf Bytes.
    Nahezu alle Rechenoperationen werden von der ALU durchgeführt.
    Die benötigten Operanden müssen sich dazu in einem bzw zwei Registern des Registerfile ( quasi der Schreibtisch des ALU - bis auf wenige AVR immer 32 (Rechen-)Register) befinden - Das Ergebnis landet entsprechend auch in einem (ganz selten in mehreren) dieser Register.
    Daten(-Bytes) können außerdem im SRAM (quasi ein Aktenschrank im Flur), oder im Eeprom (Archiv im Keller) ausgelagert werden. Meinetwegen auch in externen Speichern (Hochregallager am anderen Ende der Stadt).

    Welche Rechenoperationen beherrschen die AVR?
    Addition
    Subtraktion
    Division/Multiplikation, aber nur mit zwei
    (MegaAVR (und X-Core-Tinies) können in gewissem Maße auch multiplizieren)

    Divisionen (und Multiplikationen) müssen also mit entsprechenden Schleifen (deswegen der Rechenweg mit der ganzzahligen Division oben) mithilfe der vorhandenen Operationen umgesetzt werden.

    BASCOM verwaltet die Variablen im SRAM, für jede Rechenoperation werden die benötigten Variablen also aus dem SRAM in (je) ein Register des Registerfile geladen, dann tut die ALU ihr Werk, anschließend wird das Ergebnis aus dem Registerfile wieder ins SRAM gespeichert.
    (Die ALU arbeitet wie gesagt Bytebasiert - wenn Du also zwei Words addierst, lädt BASCOM die vier Bytes (zwei pro Word, klar), die ALU führt zwei Additionen aus (einmal mit Übertrag=Carry), anschließend wird das Ergebnis in Form von zwei Bytes (ein Word) zurückgespeichert (also zwei Speicherinstruktionen).

    Vom SRAM ins Registerfile wird mit Load geladen -> LD oder LDS.
    Vom Registerfile ins SRAM gespeichert wird mit Store -> ST oder STS.

    Jetzt zu dem Code-Schnipsel, den ich Dir stibitzt hatte:
    Die drei Subtraktionen in den Zeilen 5, 9 und 13 sind unnötig, da die Variablen ganze Zahlen repräsentieren, die Division ganzzahlig ist.
    Die letzten beiden Zeilen liefern auch dasselbe Ergebnis - Effektiv wärst Du auch mit drei Divisionen und drei Modulo-Divisionen ausgekommen.
    Also insgesamt sechs Divisionen, bei denen je zwei Words (4 Bytes) vom SRAM ins Registerfile geladen werden, und ein Word (2 Bytes) zurückgespeichert wird.

    Was ich mit dem Rechenweg der ganzzahligen dezimalen Division aus der Grundschule da oben verdeutlichen wollte ist, daß auf dem Papier außer dem Ergebnis auch der Rest stehenbleibt, quasi als Abfallprodukt. Wenn Du also als zweite Aufgabe die Berechnung des Rests dieser Division gestellt bekommst, kannst Du entweder das ganze nochmal auf ein neues Blatt kritzeln (=Dein Programm), oder Du nimmst einfach die "4", die da schon unten am Rattenschwanz steht (=mein Programmschnipsel).

    BASCOM macht das bei der ganzzahligen Division ("/" bzw "\") genauso, nur eben binär. Es holt sich die Variablen aus dem Aktenschrank im Flur (SRAM) auf den Schreibtisch (Registerfile), kritzelt 'ne Weile auf dem ganzen Schreibtisch rum, und kopiert dann das ganzzahlige Ergebnis zurück in den Schrank.
    Entscheidend ist, daß der Tisch nie saubergemacht wird - die Register werden nur durch neue/folgende Instruktionen (bzw Loads) überschrieben.
    Wenn man also weiß, wo auf dem Schreibtisch BASCOM bei einer ganzzahligen Division den Rest hingekritzelt hatte, kann man ihn nach der Division einfach von dort in eine Variable im Aktenschrank abspeichern (genau, mit Store bzw STS), ohne irgendwas rechnen lassen zu müssen.

    Genau um dieses "Wo?" (und ggf auch das "Wie speichern?") bzw die Antwort darauf ging es mir in diesem Thema.

    Mein Code-Schnipsel liefert nämlich dieselben Ergebnisse wie Deiner mit etwa dem halben Rechenaufwand - weil der Rest ein Abfallprodukt der Division ist, den BASCOM auf dem Schreibtisch liegenläßt.
     
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden