Pfad: Home => AVR-Übersicht => Binäres Rechnen => Division
AT90S8515

Division einer 16-Bit-Zahl durch eine 8-Bit-Zahl


Dezimales Dividieren

Zunächst wieder eine dezimale Division, damit das besser verständlich wird. Nehmen wir an, wir wollen 5678 durch 12 teilen. Das geht dann etwa so:

             5678 : 12 = ?
--------------------------
- 4 * 1200 = 4800
             ----
              878
- 7 *  120 =  840
              ---
               38
- 3 *   12 =   36
               --
                2
Ergebnis: 5678 : 12 = 473 Rest 2
================================

Binäres Dividieren

Binär entfällt wieder das Multiplizieren des Divisors (4 * 1200, etc.), weil es nur Einsen und Nullen gibt. Dafür haben binäre Zahlen leider sehr viel mehr Stellen als dezimale. Die direkte Analogie wäre in diesem Fall etwas aufwändig, weshalb die rechentechnische Lösung etwas anders aussieht.

Die Division einer 16-Bit-Zahl durch eine 8-Bit-Zahl in AVR Assembler ist in HTML-Format hier und als Quellcode hier gezeigt.

Programmschritte beim Dividieren

Das Programm gliedert sich in folgende Teilschritte:
  1. Definieren und Vorbelegen der Register mit den Testzahlen,
  2. das Vorbelegen von Hilfsregistern (die beiden Ergebnisregister werden mit 0x0001 vorbelegt, um das Ende der Division nach 16 Schritten elegant zu markieren!),
  3. die 16-Bit-Zahl in rd1h:rd1l wird bitweise in ein Hilfsregister rd1u geschoben (mit 2 multipliziert), rollt dabei eine 1 links heraus, dann wird auf jeden Fall zur Subtraktion im vierten Schritt verzweigt,
  4. der Inhalt des Hilfsregisters wird mit der 8-Bit-Zahl in rd2 verglichen, ist das Hilfsregister größer wird die 8-Bit-Zahl subtrahiert und eine Eins in das Carry-Bit gepackt, ist es kleiner dann wird nicht subtrahiert und eine Null in das Carry-Bit gepackt,
  5. der Inhalt des Carry-Bit wird in die Ergebnisregister reh:rel von rechts einrotiert,
  6. rotiert aus dem Ergebnisregister eine Null links heraus, dann muss weiter dividiert werden und ab Schritt 3 wird wiederholt (insgesamt 16 mal), rollt eine 1 heraus, dann sind wir fertig.
Für das Rotieren gilt das oben dargestellte Procedere (siehe oben, zum Nachlesen).

Das Dividieren im Simulator

Die folgenden Bilder zeigen die Vorgänge im Simulator, dem Studio. Dazu wird der Quellcode assembliert und die Object-Datei in das Studio geladen.
  1. DIV8D1.gif: Der Object-Code ist gestartet, der Cursor steht auf dem ersten Befehl. Mit F11 machen wir Einzelschritte.
  2. DIV8D2.gif: In die Register R0, R1 und R3 werden die beiden Werte 0xAAAA und 0x55 geschrieben, die wir dividieren wollen.
  3. DIV8D3.gif: Die Startwerte für das Hilfsregister werden gesetzt, das Ergebnisregisterpaar wurde auf 0x0001 gesetzt.
  4. DIV8D4.gif: R1:R0 wurde nach links in Hilfsregister R2 geschoben, aus 0xAAAA ist 0x015554 entstanden.
  5. DIV8D5.gif: Weil 0x01 in R2 kleiner als 0x55 in R3 ist, wurde das Subtrahieren übersprungen, eine Null in das Carry gepackt und in R5:R4 geschoben. Aus der ursprünglichen 1 im Ergebnisregister R5:R4 ist durch das Linksrotieren 0x0002 geworden. Da eine Null in das Carry herausgeschoben wurde, geht der nächste Befehl (BRCC) mit einem Sprung zur Marke div8a und die Scleife wird wiederholt.
  6. DIV8D6.gif: Nach dem 16-maligen Durchlaufen der Schleife gelangen wir schließlich an die Endlosschleife am Ende der Division. Im Ergebnisregister R5:R4 steht nun das Ergebnis der Division von 0xAAAA durch 0x55, nämlich 0x0202. Die Register R2:R1:R0 sind leer, es ist also kein Rest geblieben. Bliebe ein Rest, könnten wir ihn mit zwei multiplizieren und mit der 8-Bit-Zahl vergleichen, um das Ergebnis vielleicht noch aufzurunden. Aber das ist hier nicht programmiert.
  7. DIV8D7.gif: Im Prozessor-View sehen wir nach Ablauf des gesamten Divisionsprozesses immerhin 60 Mikrosekunden Prozessorzeit verbraucht.


Zum Seitenanfang

©2002 by http://www.avr-asm-tutorial.net