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 ­čÖé


Log in to reply