lol, div befehl geht nicht ....



  • hallo nochmals...

    also bei meinem 32bit code als image geht zum verrecken der div befehl nicht !
    er gibt immer den geist auf und macht nen reboot.
    ich hab schon alle varianten durchprobiert..

    mov eax, 56982
    mov ecx, 16
    div ecx

    egal an welcher stelle das steht.. er kann nicht dividieren..

    also ich hab das so verstanden dass in eax der wert reinkommt und der teiler in einem xbeliebigen register stehen kann und als operand angegeben wird.

    was mach ich falsch.. gibt es da irgendwelche randbedingungen noch ?
    jetz is klar warum meine itoa funktion nie geht 😃
    mul geht aber astrein.. ging schon immer

    mfg hammer



  • Hi.

    Der "Wert" kommt eben nicht nur in (e)ax rein, sondern auch in (e)dx und genau da liegt in deinem Code IMHO der Fehler: div loest naemlich nicht nur eine Exception 0 aus, wenn versucht wird, durch 0 zu teilen, sondern auch, wenn beim Teilen ein Overflow stattfindet.
    Wenn du also beim Teilen nur einen Wert in (e)ax verwendest, solltest du darauf achten, (e)dx zu loeschen.

    BTW: Bevor du grossartig versuchst irgendwelche C-Funktionen zu implementieren, waere es vielleicht auch mal ganz sinnvoll, einen kleinen Exception-Handler in Asm zu schreiben, der dir nuetzliche Infos auf den Bildschirm schreibt, anstatt es zu einem Tripple Fault kommen zu lassen. 🙄



  • jo tatsächlich..
    da hät ich wahrscheinlich lang gebraucht.. 🙄

    jetz funktioniert alles 🙂

    mfg



  • Der div befehl arbeitet wie folgt:

    Die Zahl die dividiert werden soll steht in EAX bzw EDX.

    wenn du nun schreibst
    div bx
    dann wird nur der Wert in EAX durch BX dividiert, da BX nur ein 16-Bit Register ist.

    Wenn du aber schreibst
    div ebx
    dann wird eine 64-Bitzahl, zusammengesetzt aus EAX und EDX durch EBX diviert.
    Das ergebniss einer Division steht dabei immer in EAX und der evtle. Rest in EDX



  • Hi.

    Was du da schreibst ist nicht ganz richtig: Bei einer Division mit einem 16Bit langen Divisor, wird der 32Bit lange Dividend (auch aus Gruenden der Abwaertskompatibilitaet zum 286) aus ax und dx gebildet (analog zur Division mit 32Bit Divisor).
    Nur bei einer Division mit 8Bit Divisor spielt sich alles im ax-Register ab.



  • Ok das mag sein.

    Ich kannte es ursprünglich auch nur mit ax und dx.
    Ich hatte es daher einfach auf EAX übertragen.



  • Der DIV - Befehl (66,F7,F1) funktioniert hier auch nicht.

    mov eax,1238
    mov ecx,10
    mov edx,0
    div ecx

    eax:0
    edx:8

    Warum ist in eax 0?

    Hingegen das macht die CPU noch:

    mov eax,1238
    mov ecx,1
    mov edx,0
    div ecx

    eax:1238
    edx:0



  • Meißel schrieb:

    mov eax,1238
    mov ecx,10
    mov edx,0
    div ecx

    eax:0
    edx:8

    Warum ist in eax 0?

    EAX ist nicht 0 - der Fehler liegt vermutlich in der Ausgabe.

    Grüße aus dem Jahr 2004.



  • Es wirkt komisch, für einen Teiler wie 2,4,8,16 usw. div zu benutzen.

    Außerdem ist die Angabe des Systems, des Compilers und der benutzten Shell(s) ganz sinnvoll bei Problemen wie diesen, weil es immer wieder mal Ärger gibt mit Divisionen, Stackzugriffen, Sonderzeichen, Kompatibilitäten zwischen Bitbreiten, Bibliotheken, Ausgabeformaten usw.



  • Danke für die Antworten.

    Achso, es sind Dezimalzahlen, habe ich vergessen zu erwähnen. Und das Programm.COM lief in einem Windows-Fenster (Eingabeaufforderung).

    Hoffe auch, daß es nur ein Ausgabeproblem ist.

    Übrigens klappen die FPU-Befehle auch nicht so richtig. Die werden zwar angenommen, aber nur selten richtig gerechnet. Da kriegt man dann sowas als Ergebnis für eine BCD-Zahl: 0000000000000>0????. Oder hat das irgendeine Bedeutung? FNINIT habe ich verwendet.



  • Hast du ein 32 Bit System oder ein 64bit System? Bei 64bit wären noch einige Dinge mehr zu beachten und .com Programme dürften (im Ergebnis) eher problematisch ausfallen, da der Virtual Mode (für 16/32 Bit Dosprgs (mit allem pipapo, auch SSE) unter 64 Bit wegfällt. Ich habs bisher noch nicht ausprobieren können, was soll einer mit Windows 64 Bit?

    Du könntest aber versuchen, ob dein Programm mit DosBox sinnvoller abläuft, oder alternativ ein normales .exe prg erstellen, und gucken, wie das im Debugger abläuft oder wie es im Dissassembly ausschaut.

    Es könnte auch noch sein, dass deine Windowsshell eine Macke hat, die gepatcht werden sollte. Ein Blick auf die Einstellungsmöglichkeiten bei der Fensterdarstellung/Emuleistung kann auch schon helfen.



  • Der eine Computer ist ein HP-Laptop mit Windows 98 (FPU-Problem), erkennt noch keine USB-Speicherstifte. Der andere ist viel moderner von 2011 (DIV Problem), kann ich aber erst am Mo nachschauen.

    Die .COM Datei wird mithilfe von QBASIC erstellt. Da wäre mir eine .EXE-Datei zu kompliziert.

    DOSBox hört sich gut an. Werde das mal zur Überprüfung des Programmcode ausprobieren.



  • Meißel schrieb:

    Die .COM Datei wird mithilfe von QBASIC erstellt. Da wäre mir eine .EXE-Datei zu kompliziert.

    Inwiefern?
    Auf dem Windows 98 System kannst du den korrekten Ablauf mit debug überprüfen (Windowstaste drücken, debug eingeben, sollte reichen, falls nicht, halt suchen)

    um dir die Register anzuzeigen, gibst du den Buchstaben r ein
    um Assemlercode zu schreiben, gibst du den Buchstaben a ein
    Um schrittweise zu testen, gibst du den Buchstaben t ein.
    Um die eine Übersicht der Kurzbefehle zu erhalten, gibst du ein ? ein.
    Für 32 Bit kannst du für einen anderen Debugger nehmen z.B. für Probleme wie diese
    den Debug Clone von Paul Voyta -> http://math.berkeley.edu/~vojta/
    Es ist allerdings stark zu vermuten, dass der .com Code 16-Bit Code ist, also debug die sinnvollere Wahl. Überprüfe das ganze mal genauer.



  • So, Fehler gefunden! Die Datei ansich ging nicht unter Debug einzuladen, die von-Hand-Eingabe wäre aufgrund der Länge sehr aufwendig gewesen.

    Da die ComBox keinen Fehler anzeigte, hab ich nochmal den Programmcode noch genauer untersucht.
    Und siehe da, eine Zahl war falsch und hat aus einem DEC ein INC gemacht, die Anzahl der Schleifendurchgänge verändert und den DIV unbemerkt
    mehrfach hintereinander ausführen lassen.

    Vielen Dank für die Hilfe!



  • Ich möchte nochmal auf die Ausgangsfrage zurück.

    Nobuo T schrieb:

    div loest naemlich nicht nur eine Exception 0 aus, wenn versucht wird, durch 0 zu teilen, sondern auch, wenn beim Teilen ein Overflow stattfindet.

    Wisst ihr, warum gerade beim Overflow der Division eine Exception ausgelöst und nicht einfach ein Flag gesetzt wird?



  • MrMagic schrieb:

    Ich möchte nochmal auf die Ausgangsfrage zurück.

    Nobuo T schrieb:

    div loest naemlich nicht nur eine Exception 0 aus, wenn versucht wird, durch 0 zu teilen, sondern auch, wenn beim Teilen ein Overflow stattfindet.

    Wisst ihr, warum gerade beim Overflow der Division eine Exception ausgelöst und nicht einfach ein Flag gesetzt wird?

    weil in beiden Faellen das Resultat nicht definiert ist.

    cdq ist die magische instruktion 🙂


Anmelden zum Antworten