steckl: Assembler: 32Bit Division mit Ergebnis > 16Bit?

Hi,

ich lerne gerade Assembler mit den Programmen TASM (Turbo-Assembler von Boorlean), einem 8086-Assembler und TD (Turbo Debugger).

Jetzt möchte ich Zahlen miteinander Dividieren. Solange es kleine Zahlen sind ist es ja noch recht leicht.

In einem Buch habe ich gefunden, dass ich mit
DIV BX
die Berechnung (DX:AX) / BX durchführe. DX:AX ist dabei ein Double-Word (32-Bit-Zahl) aufgeteilt auf das AX- und das DX-Register.
Das klappt auch noch bei kleinen Ergebnissen. Das Divisionsergebnis wird in AX geschrieben und der ganzzahlige Rest in DX.

Wenn jetzt aber ein Ergebnis > 16 Bit rauskommt gibt der Debugger die Fehlermeldung "Divide by Zero" aus. Ist es irgendwie möglich, dass ich ein Ergebnis > 16Bit berechnen kann?
Beispiel: 0FFFFFFh/2h erzeugt den Fehler.

Und noch eine Zusatzfrage:
Ist es möglich durch einen 32Bit-Wert zu dividieren?

Ich habe mal gehört, dass man irgendwie in einen anderen Modus schalten kann, damit Register 32Bit statt 16Bit groß sind. Darauf möchte ich aber (wenn möglich) erstmal verzichten.

mfG,
steckl

  1. Hallo

    ich lerne gerade Assembler mit den Programmen TASM (Turbo-Assembler von Boorlean), einem 8086-Assembler und TD (Turbo Debugger).

    Asbach Uralt, 16-Bit-Real-Mode mit allen dämlichen Konsequenzen.

    Ich habe mal gehört, dass man irgendwie in einen anderen Modus schalten kann, damit Register 32Bit statt 16Bit groß sind. Darauf möchte ich aber (wenn möglich) erstmal verzichten.

    Warum?
    Warum willst Du nicht gleich 32-Bit-Assembler im Protected Mode lernen?
    Was bringt Dir der Real Mode? Möchtest Du nicht vielleicht lieber 8-Bit-Assembler lernen?

    Verständnislose Grüße

    Vinzenz, der sich vor ungefähr 15 Jahren mal mit 16-Bit-Assembler herumgeschlagen hat.

    1. Hi,

      Warum willst Du nicht gleich 32-Bit-Assembler im Protected Mode lernen?
      Was bringt Dir der Real Mode? Möchtest Du nicht vielleicht lieber 8-Bit-Assembler lernen?

      Wir lernen das in der FH und der Prof hat gemeint, für die Grundlagen reicht der 8086-Assembler erstmal. Später steigen wir dann wohl auf 32-Bit um.

      Vinzenz, der sich vor ungefähr 15 Jahren mal mit 16-Bit-Assembler herumgeschlagen hat.

      Ich habs hoffentlich nach dem nächsten Semester schon wieder hinter mir :)

      Mit deiner Erfahrung kannst du mir aber vielleicht noch sagen, ob es eine Lösung gibt, oder ob es mit 16-Bit-Assembler unmöglich ist.

      mfG,
      steckl

  2. Hallo,

    ich lerne gerade Assembler mit den Programmen TASM (Turbo-Assembler von Boorlean), einem 8086-Assembler und TD (Turbo Debugger).

    willkommen in der Welt spannender Handarbeiten!

    Jetzt möchte ich Zahlen miteinander Dividieren. [...]

    Wenn du erstmal beim traditionellen 8086-Registersatz bleiben willst (16bit) und trotzdem einen Dividend breiter als 32bit, einen Divisor breiter als 16bit, oder einen möglichen Quotienten breiter als 16bit verarbeiten willst, wirst du wohl den Algorithmus von Hand programmieren müssen. Und dann kannst du beliebig große Werte realisieren.
    Wie du übrigens völlig richtig erkannt hast, kann der Quotient bei einer ganzzahligen Division ebensogroß werden wie der Dividend. Die im x86-Befehlssatz implementierte div-Instruktion hat in diesem Punkt also eine Einschränkung.

    Die Division komplett in Software zu schreiben, ist übrigens gar nicht so schwer (nicht mal in ssembler), wenn man das Prinzip der "schriftlichen Division" wirklich verstanden hat.

    So long,
     Martin

    --
    Der Gast geht solange zum Tresen, bis er bricht.
    1. Hi,

      danke für die Antworten!

      willkommen in der Welt spannender Handarbeiten!

      Hallo ;)

      Jetzt möchte ich Zahlen miteinander Dividieren.

      Wenn du erstmal beim traditionellen 8086-Registersatz bleiben willst (16bit) und trotzdem einen Dividend breiter als 32bit, einen Divisor breiter als 16bit, oder einen möglichen Quotienten breiter als 16bit verarbeiten willst, wirst du wohl den Algorithmus von Hand programmieren müssen. Und dann kannst du beliebig große Werte realisieren.

      Die Division komplett in Software zu schreiben, ist übrigens gar nicht so schwer (nicht mal in Assembler), wenn man das Prinzip der "schriftlichen Division" wirklich verstanden hat.

      Da müsste ich mir erst noch was überlegen. Da ich bis jetzt noch nie so tief auf Bit-Ebene Programmiert habe, habe ich sowas auch noch nie gebraucht. Bis jetzt kann ich aber noch nichtmal Subroutinen Programmieren, also wirds wohl noch ein bisschen dauern. Wenn es so weit ist und ich dann nicht draufkomme melde ich mich ja vielleicht nochmal hier.

      Findest du auch, dass ich gleich mit 32-Bit-Assembler anfangen sollte?

      Wäre dann die 32-Bit-Division ohne Probleme lösbar?

      mfG,
      steckl

      1. Hi steckl,

        Die Division komplett in Software zu schreiben, ist übrigens gar nicht so schwer (nicht mal in Assembler), wenn man das Prinzip der "schriftlichen Division" wirklich verstanden hat.
        Da müsste ich mir erst noch was überlegen.

        okay, als ich schrieb "gar nicht so schwer", dachte ich auch schrittweise.
        Ich bin vom grundsätzlichen Algorithmus (Rechenschema) ausgegangen: Vom Dividend von links aus (MSB) eine Stelle nach der anderen nehmen, durch den Divisor teilen, Divisionsergebnis ergibt eine Stelle des Ergebnisses, Divisonsrest mit der nächsten Stelle ergänzen, nächster Schritt.
        Diesen grundsätzlichen Ablauf könnte man in sehr vielen Programmiersprachen realisieren (hab ich vor Jahren mal mit einer kleinen 8bit-CPU in Assembler gemacht), und es ist sehr hilfreich, wenn man sich diesen Ablauf erstmal als Flowchart skizziert oder in Pseudocode formuliert.
        Und dann stellt man plötzlich fest, dass es für das Prinzip völlig egal ist, ob man Bit für Bit, Ziffer für Ziffer oder Byte für Byte dividiert, und man kann sich die Aufgabe so portionieren, wie es die gewählte Programmiersprache oder CPU (im Falle von Assembler) am besten hergibt.

        Bis jetzt kann ich aber noch nichtmal Subroutinen Programmieren, also wirds wohl noch ein bisschen dauern.

        Klar. Aber einen guten Rat gebe ich dir schon jetzt: Versuche immer, nicht vorrangig eine bestimmte CPU-Instruktion isoliert zu betrachten und verstehen zu wollen, sondern versuche, das Konzept und die Zusammenhänge als Ganzes zu sehen. Das ist am Anfang nicht einfach, erleichtert aber nach einer gewissen Anlaufphase das weitere Lernen (auch selbständig) erheblich.

        Findest du auch, dass ich gleich mit 32-Bit-Assembler anfangen sollte?

        Was spricht dagegen? Schwieriger wird es dadurch nicht. Anspruchsvoller wird es teilweise dann, wenn du nicht nur die reine Programmierung betrachten willst, sondern auch übergeordnete Themen wie Speicherverwaltung, virtuelle Adressierung usw., ... Das sind Dinge, die dann (fast) zwangsläufig dazukommen, und da wird's zum Teil ... hmm, nicht ganz trivial. ;-)

        Wäre dann die 32-Bit-Division ohne Probleme lösbar?

        Well, das Problem würde sich verlagern. Anstatt DX:AX durch BX zu dividieren (also 32bit durch 16bit), könntest du EDX:EAX durch EBX dividieren, macht also 64bit durch 32bit. Wenn dich dabei auf einen Dividend mit nur 32bit Breite beschränkst wie bisher (EDX also 0 bleibt), hast du gewonnen. Aber hilft dir das wirklich? Es ist immer eine Frage des notwendigen Zahlenbereichs.

        Schönen Abend noch,
         Martin

        --
        Solange der Nagellack nicht trocken ist,
        ist eine Frau praktisch wehrlos.
          (Burt Reynolds, US-Schauspieler)