Hallo Besucher, der Thread wurde 1,7k mal aufgerufen und enthält 5 Antworten

letzter Beitrag von M. J. am

blöde Frage

  • D.h. wenn ich 0x10000000 durch 0x0002 teile, dann kann die 68k-CPU das Ergebnis in 16Bit darstellen? Wäre faszinierend (und sicher falsch).


    Nachtrag: für's Ergebnis sollte also auch 32Bit reserviert werden, falls ein Spaßvogel durch 1 teilt.


    Nachtrag zur Ausgangsfrage: nach kurzem googeln würde ich sagen: der längere Wert bestimmt (also 32 bit)

  • D.h. wenn ich 0x10000000 durch 0x0002 teile, dann kann die 68k-CPU das Ergebnis in 16Bit darstellen? Wäre faszinierend (und sicher falsch).


    Nachtrag: für's Ergebnis sollte also auch 32Bit reserviert werden, falls ein Spaßvogel durch 1 teilt.

    "Overflow may be detected and set before the instruction completes. If the instruction detects an overflow, it sets the overflow condition code and the operands are unaffected."


    Wenn das Ergebnis nicht in die 16 Bits des Ergebnisses passt, dann wird das V-Flag gesetzt.

  • Nachtrag zur Ausgangsfrage: nach kurzem googeln würde ich sagen: der längere Wert bestimmt (also 32 bit)

    So kenne ich das auch. Z.B. bei der Multiplikation bedeutet 16-Bit Multiplikation, dass man zwei 16 Bit Werte multipliziert. Dass das Ergebnis ggfs. nicht in 16 Bit passt, hat darauf keinen Einfluss. Das selbe hätte ich jetzt bei der Division angenommen, also wenn man einen 32 Bit-Wert durch einen anderen dividiert (auch wenn der dann kürzer ist), spricht man von einer 32 Bit Division.

  • blöde Frage:

    Merke: Es gibt keine blöden Fragen. Nur blöde Antworten (s. u.) ^^

    wenn ich eine 32 bit Zahl durch eine 16 bit Zahl dividiere, ist das eine 32 bit oder eine 16 bit Division?

    Das ist sogar eine sehr gute Frage und recht schwer zu beantworten.


    Zunächst ein Blick auf den 68000er:
    Ein Grund, warum der Befehl DIVU(.W) kein 32 Bit-Ergebnis zuläßt, ist auch, daß sich nach der Division im Highword des Registers der Modulo-Rest befindet. Dies dient dazu, mehrere Divisionen hintereinander ausführen zu können. Ist bei einer 32/16-Division das Ergebnis zu groß für 16 Bit, macht man folgendes: Man dividiert zunächst das Highword des Dividenden durch 16 Bit (die oberen 16 Bits werden auf 0 gesetzt), merkt sich das Ergebnis im Lowword als Highword des Quotienten. Dann lädt man in das Lowword des Divisionsregisters das Lowword des Dividenden. Der Modulowert des Highwords bleibt hierbei erhalten. Danach dividiert man diese 32 Bit erneut und erhält dadurch das Lowword des Quotienten. Damit hat man ein 32 Bit-Endergebnis.
    Was also bei einer vollständigen Division 32/16 passiert, ist, daß man tatsächlich zwei 16-Bit Divisionen hat, nicht eine. Natürlich kann man auch eine vollständige 32/32-Bit Division implementieren, jedoch ist diese weitaus langsamer und aufwendiger. Das kann man vielleicht am folgenden Beispiel illustrieren. Anstelle von 32/16 schaut man sich vereinfacht eine 16/8-Division auf dem 6502 an. Diese setzt sich ebenfalls aus zwei 8-Bit Divisionen zusammen.
    1. Schritt: (A zu Beginn 0. In A wird nach und nach der Dividend reingeschoben)

    Code
    1. cmp divisor
    2. bcc ?0
    3. sbc divisor
    4. ?0: rol dividend_quotient ; enthält das Schieberegister für den Dividenden und dient
    5. rol ; gleichzeitig als Schieberegister für den 8-Bit-Quotienten
    6. cmp divisor ; wiederhole 8 mal
    7. bcc ?1
    8. ...

    Dieser Algorithmus ist nur möglich, wenn der Inhalt von A garantiert kleiner als der Divisor ist.
    2. Schritt: Mit dem Modulo-Ergebnis in A wird jetzt eine zweite Division durchgeführt.

    Hierbei kann man den Unterschied zwischen dem 1. und dem 2. Schritt erkennen. Im ersten Schritt hat der Akkumulator zu Beginn den Wert 0. Da die Bits des Dividenden Stück für Stück von rechts reinrotiert werden, ist die Bedingung A >= Divisor irgendwann immer erfüllt, bevor ein gesetztes Highbit nach links unbehandelt rausrotiert würde.
    Im zweiten Schritt jedoch ist es möglich, daß der Modulowert bereits das Highbit gesetzt hat. Daher muß beim Rotieren zusätzlich getestet werden, ob dieses rausrotiert wurde, woraufhin immer eine Subtraktion erfolgen muß. (Der Wert lautet dann ja eigentlich $100 + x und ist damit immer größer als A.)
    Der Grund, warum man diese zwei Schritte vornimmt, ist, daß beim 1. Schritt dieser Test nicht stattfinden muß. Die Ausführung ist daher schneller. Außerdem müssen so weniger Werte rotiert werden als bei einer vollständigen 32/32-Bit-Division.
    Von daher würde ich die Frage so beantworten:
    Wenn man eine 32 Bit-Zahl durch eine 16 Bit-Zahl dividiert, handelt es sich (bei effizienter Umsetzung) um zwei 16-Bit Divisionen.