ASM
- unix
- Beiträge: 361
- Registriert: 15.02.2005 19:25
- Wohnort: Zwischen Coburg und Bamberg :-)
- Kontaktdaten:
Noch ne Frage zum Thema:
Wie sieht das mit dem rechnen mit Floads aus?? wegen den Komma und so.
Mein Buch erklärte mir nur ganze Zahlen.
Lassen sich diese ohne Probleme addieren oder ist das komplexer?
danke für alle Antworten!!
[edit]
PB Meldet bei folgendem Code Fehler:
Warum??
Wie sieht das mit dem rechnen mit Floads aus?? wegen den Komma und so.
Mein Buch erklärte mir nur ganze Zahlen.
Lassen sich diese ohne Probleme addieren oder ist das komplexer?
danke für alle Antworten!!
[edit]
PB Meldet bei folgendem Code Fehler:
Code: Alles auswählen
Global Var_0.b = 10
Global Var_1.b = 9
Global Var_2.b = 0
! mov ax, [Var_0]
! mov bx, [Var_1]
! add ax, bx
! mov [Var_2], ax
Debug Var_2
Hier steht normalerweise die Putzfrau drin,
die hat aber Urlaub.
MfG : Unix
die hat aber Urlaub.
MfG : Unix
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
@unix: Beachte, wie die Variablen verwendet werden
!
Die Ergebnisse zeigen Dir auch gleich eine "Eigenart" von Float-Berechnungen!
Gruss
Helle

Code: Alles auswählen
;-------- Float-Addition "Helle" Klaus Helbing PB4.0 21.07.2006
;-------- 1.Beispiel: Alle Variablen mittels PB deklariert
Global F1.f = 12.45
Global F2.f = 67.89
Global X.f
!FNINIT
!FLD [v_F1] ;Unter PB deklarierte Variablen sind als "[v_Variable]" zu verwenden
!FLD [v_F2]
!FADD st0,st1
!FST [v_X]
MessageRequester("Float-Addition", StrF(X,20)) ;Ergebnis mit 20 Nachkomma-Stellen anzeigen
;-------- 2.Beispiel: Daten-Variablen mittels FAsm deklariert, die Ausgabe-Variable X wird vom PB-Teil genommen
!FNINIT
!FLD [F1] ;Unter FAsm deklarierte Variablen sind als "[Variable]" zu verwenden
!FLD [F2] ;Diese Variablen F1 und F2 sind nicht mit den oben mittels Global deklarierten Variablen identisch!
!FADD st0,st1
!FST [v_X] ;Wegen der PB-Ausgabe wird hier wieder die unter PB deklarierte Variable verwendet
MessageRequester("Float-Addition", StrF(X,20))
End
;-------- Hier werden am Ende des PB-Codes die nur unter FAsm verwendeten Variablen deklariert
;-------- Auf diese Variablen hat PB keinen Zugriff!
!section '.data' Data readable writeable
!F1 DD 1095185203 ;Umgerechneter Float-Wert von 12.45; ist ein Thema für sich
!F2 DD 1116194734 ;Umgerechneter Float-Wert von 67.89
;--------
Gruss
Helle
cooles Beispiel Helle.
Weißt du, wie man diese Werte:
umrechnet?
ich weiß, dass das irgendwas mit Mantisse und Exponent zu tun hat, hab auch dazu was in Wikipedia gefunden, aber schlau werd ich draus nicht
Weißt du, wie man diese Werte:
Code: Alles auswählen
!F1 DD 1095185203
!F2 DD 1116194734
ich weiß, dass das irgendwas mit Mantisse und Exponent zu tun hat, hab auch dazu was in Wikipedia gefunden, aber schlau werd ich draus nicht

- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
Wieso nicht
Und ein kleiner Hinweis zu Helles Code, der für Anfänger nicht fehlen
sollte: Der FPU-Stack ist nicht leer am Schluss dieses Beispiels, was zu
Fehlern führen kann.
Code: Alles auswählen
!section '.data' Data readable writeable
!F1 DD 12.45 ;Umgerechneter Float-Wert von 12.45; ist ein Thema für sich
!F2 DD 67.89 ;Umgerechneter Float-Wert von 67.89

Und ein kleiner Hinweis zu Helles Code, der für Anfänger nicht fehlen
sollte: Der FPU-Stack ist nicht leer am Schluss dieses Beispiels, was zu
Fehlern führen kann.
- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
Just try it:
Entferne den Kommentar und sehe das falsche Resultat.
Code: Alles auswählen
f.f = 7.0
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
;!FLD [v_f]
!FADD st0, st1
!FSTP dword[v_f]
Debug f
Da Remi´s Kommentare noch spärlicher sind als meine (und das will was heissen
!), hier der Versuch einer kurzen Erklärung: Die FPU verfügt über 8 (Stack-)Register und auch über einen eigenen Stackpointer (die Kunst der FPU-Programmierung besteht übrigens darin, über diese Register stets den Überblick zu behalten). Remi´s Beispiel zeigt was passiert, wenn man die 8 Register mit 9 Werten belegen will: Der (FPU-)Stackpointer wird runtergezählt und spätestens beim 9.Wert ist die ganze Sache undefiniert. Wenn ein Vorgänger-Programm den Pointer auch schon in einem runtergezähltem Zustand hinterlässt, kann es durchaus schon bei ganz normalen Rechnungen (nicht so ein Extrem wie das Beispiel) zum Crash kommen. Deshalb schwört Remi auf ein ordentliches, neutralisiertes Verlassen des FPU-Programm-Teiles. Ist ja erstmal auch richtig.
Aber: Wer garantiert mir, das jeder Programmierer sich so verhält? Deshalb verlasse ich mich nicht auf so etwas, sondern ich initialisiere beim Start des FPU-Teiles die FPU lieber selber neu (FNINIT). Also:
Und hier noch auf Wunsch eines einzelnen Herrn ein Beispiel zur Float-in-DWord-Umrechnung:
P.S.: Natürlich kann man auch wie Remi dem Assembler die Umrechnung überlassen, aber mit selbst ermittelten Werten kann man noch ein wenig schummeln...
Gruss
Helle

Aber: Wer garantiert mir, das jeder Programmierer sich so verhält? Deshalb verlasse ich mich nicht auf so etwas, sondern ich initialisiere beim Start des FPU-Teiles die FPU lieber selber neu (FNINIT). Also:
Code: Alles auswählen
f.f = 7.0
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
!FLD [v_f]
;.. Unfug so viel man will
!FNINIT
!FLD [v_f] ;st1
!FLD [v_f] ;st0
!FADD st0, st1
!FSTP dword[v_f]
Debug f
Code: Alles auswählen
;-------- Umrechnung Float in DWord nach IEEE-754 einfache Genauigkeit 32-Bit
;-------- "Helle" Klaus Helbing PB4.0 22.07.2006
;-------- Bit 31:Vorzeichen, Bit 23-30:Exponent, Bit 0-22:Mantisse
;-------- Exponent ist für 2-er Potenzen! Für 12.45 gilt E=3, da 2 hoch 3 gleich 8 die nächsttiefere 2er Potenz ist
;-------- 12.45 ist also 8x1.55625. Die Mantisse wird "normiert", so dass sie als 0.55625 erscheint.
;-------- Auch die Mantisse wird in 2-Potenzen aufgespalten; d.h. das erste Bit (Stelle 22) hat im gesetzten
;-------- Fall den Wert 0.5 (1/2); das Bit an Stelle 21 hat (gesetzt) den Wert 0.25 (1/4) usw.
Global F.f = 12.45 ;Testzahl
Global M.l ;Mantisse
Global E.l ;Exponent
Global A.l = 127 ;Additionswert für einfache Genauigkeit (32-Bit)
Global X.l ;Bildschirmausgabe
!fninit
!fld [v_F]
!fxtract ;Zerlegung einer Realzahl in Mantisse und Exponent
!fst [v_M] ;In Bit 0-22 steht die Mantisse
!fld st1
!fiadd [v_A]
!fist [v_E] ;Exponent+127, hier also 3+127=130
!XOR eax,eax
!MOV eax,[v_E]
!SHL eax,23 ;Exponent an "richtige" Stelle schieben
!MOV edx,[v_M]
!AND edx,807fffffh ;23 Bit der Mantisse und Vorzeichen verwenden
!ADD eax,edx
!MOV [v_X],eax
MessageRequester("F2DW", "Das Ergebnis lautet: " + Str(X))
Gruss
Helle