Autor Thema: Frage zur FPU  (Gelesen 6081 mal)

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« am: 20. November 2005, 18:10 »
Ich habe folgenden Code, der den Rest einer Float Division berechnen soll:
fld dword [esp] ;operand 1 vom stack in st0 holen
fld dword [esp + 4] ;operand 2 vom stack in st1 holen
.calc
fprem ;einen teil der berechnung vornehmen
fstsw ax ;statusword nach ax
test ax, 10000000000b ;gucken ob die berechnung fertig ist (bit 10 nicht gesetzt)
jnz .calc ;wenn nicht, dann weiterrechnen
add esp, 4 ;einen operand vom stack popen
fstp dword [esp] ;ergebniss in den stack schreiben

Er funktioniert auch wunderbar, nur wenn ich ihn öfters aufrufe, dann liefert er falsche Ergebnisse, ich nehme an, das liegt daran, das der FPU-Stack überläuft.

EDIT: Scheint daran zu liegen, das der FPU-Stack überläuft, wenn ich noch ein fstp einbaue, funktioniert das ganze, gibts noch eine Möglichkeit, ein FPU-Register zu popen, ohne den Inhalt irgentwo hin zu speichern?

Osbios

  • Beiträge: 247
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 22. November 2005, 19:28 »
Es sieht so aus als ob Du gerade beim erlernen des Koprozessors bist.

Also das mit dem Überlauf hast Du richtig erkannt. Und zum löschen eines Registers vom Stack kann man ganz einfach FFREE STX benutzen. (Anstelle vom X natürlich die Registernummer)

Aber nach deinen Komentaren im Quellcode und der unnötigen Schleife zu urteilen hast du das noch nicht ganz verstanden.

fild dword[teiler]     ;st0 = teiler; stack=1
fild dword[zahl]       ;st1 = st0; st0 = zahl; stack=2
   
fprem ;st0 = st0 mod st1
   
fistp dword[ergebniss] ;ergebniss = st0; st0 = st1 ;stack=1
ffree st0 ;stack=0
   
wait ;Warten bis der Koprozessor fertig ist


Das währe mein Vorschlag. Ich habe das jetzt mit festen Variablen gemacht, aber über ESP geht es natürlich auch.

[edit]Und FINIT nicht vergessen![/edit]
db 0x55AA

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. November 2005, 20:23 »
Erstmal Danke für deine Hilfe. Aber soweit ich weiß, kann es sein, das fprem nur einen Teil des Modulo berechnet, und Zwischenergebnisse in st0 zurücklässt, daher hatte ich die Schleife eingebaut, um das komplette Ergebniss zu berechnen.

Osbios

  • Beiträge: 247
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 23. November 2005, 07:08 »
Zitat von: SSJ7Gohan
Erstmal Danke für deine Hilfe. Aber soweit ich weiß, kann es sein, das fprem nur einen Teil des Modulo berechnet, und Zwischenergebnisse in st0 zurücklässt, daher hatte ich die Schleife eingebaut, um das komplette Ergebniss zu berechnen.


Aber die FPU macht doch keine halben Sachen. :)
db 0x55AA

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 23. November 2005, 12:04 »
Nach dem Intel Manual anscheinend schon:
Zitat
The FPREM instruction gets its name “partial remainder” because of the way it computes the
remainder. This instruction arrives at a remainder through iterative subtraction. It can, however,
reduce the exponent of ST(0) by no more than 63 in one execution of the instruction. If the
instruction succeeds in producing a remainder that is less than the modulus, the operation is
complete and the C2 flag in the FPU status word is cleared. Otherwise, C2 is set, and the result
in ST(0) is called the partial remainder. The exponent of the partial remainder will be less than
the exponent of the original dividend by at least 32. Software can re-execute the instruction
(using the partial remainder in ST(0) as the dividend) until C2 is cleared. (Note that while
executing such a remainder-computation loop, a higher-priority interrupting routine that needs
the FPU can force a context switch in-between the instructions in the loop.)

Osbios

  • Beiträge: 247
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 23. November 2005, 20:37 »
OK, die FPU macht doch halbe Sachen. -.-

Also wird sozusagen immer wieder ein sub vorgenommen und weil das so lange dauert kann es auch unterbrochen bzw. wieder fortgesetzt werden?
db 0x55AA

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 23. November 2005, 21:16 »
Ja, anscheinend schon.

 

Einloggen