Was macht man an einem Feiertag mit durchwachsendem Wetter? Man überarbeitet alten verzapften Kram
Code: Alles auswählen
;-------- Beispiele für Anwendung 80-Bit-FPU
;-------- "Helle" Klaus Helbing, 20.05.2007, PB4.02
;-------- benötigt das Include-File Procfpu80.pbi
;- Var1, Var2 und Var3 PB als 10-Byte-Variable unterjubeln
Structure FPU80Bit
Teil1.l : Teil2.l : Teil3.l ;jeweils 12 Byte reservieren, von Teil3 werden nur 2 Bytes genutzt
EndStructure
Define.FPU80Bit Var1, Var2, Var3 ;dem Kind einen Namen geben
;- benötigten String für die Bildschirm-Ausgabe definieren
Global Convert$ = Space(255) ;frei wählbarer Name für die Ausgabe, Grösse je nach Bedarf (was man vor hat)
;- die 80-Bit-Prozeduren laden
XIncludeFile "Procfpu80.pbi" ;oder nur benötigte Prozeduren einfügen
;- Var1 und Var2 mit 10-Byte-Floating-Point-Werten belegen
Teststring1$ = "0.75"
ValT(@Teststring1$, Var1)
Teststring2$ = "11"
ValT(@Teststring2$, Var2)
;- Ab hier Beispiele mit den beiden Variablen Var1 und Var2
;-------- Beispiel ArcusCosinus(0.75)
ACosT(Var1, Var3) ;Var3 = ACos(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ACos(0.75)","Single-Float: "+StrF(ACos(0.75),20)+#LFCR$+"Double-Float: "+StrD(ACos(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.72273424781341561117837735264133")
;-------- Beispiel ArcusCotangens(0.75)
ACotT(Var1, Var3) ;Var3 = ACot(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ACot(0.75)","Single-Float: "+StrF((#PI/2)-ATan(0.75),20)+#LFCR$+"Double-Float: "+StrD((#PI/2)-ATan(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.92729521800161223242851246292243")
;-------- Beispiel Addition 0.75 + 11.0
AddT(Var1, Var2, Var3) ;Var3 = Var1 + Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Addition 0.75+11.0","Single-Float: "+StrF(0.75+11.0,20)+#LFCR$+"Double-Float: "+StrD(0.75+11.0,20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 11.75")
;-------- Beispiel ArcusSinus(0.75)
ASinT(Var1, Var3) ;Var3 = ASin(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ASin(0.75)","Single-Float: "+StrF(ASin(0.75),20)+#LFCR$+"Double-Float: "+StrD(ASin(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.84806207898148100805294433899842")
;-------- Beispiel ArcusTangens(0.75)
ATanT(Var1, Var3) ;Var3 = ATan(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ATan(0.75)","Single-Float: "+StrF(ATan(0.75),20)+#LFCR$+"Double-Float: "+StrD(ATan(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.64350110879328438680280922871732")
;-------- Beispiel Cosinus(0.75)
CosT(Var1, Var3) ;Var3 = Cos(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Cos(0.75)","Single-Float: "+StrF(Cos(0.75),20)+#LFCR$+"Double-Float: "+StrD(Cos(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.73168886887382088631183875300008")
;-------- Beispiel Cotangens(0.75)
CotT(Var1, Var3) ;Var3 = Cot(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Cot(0.75)","Single-Float: "+StrF(1/Tan(0.75),20)+#LFCR$+"Double-Float: "+StrD(1/Tan(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 1.0734261485493773587431645424435")
;-------- Beispiel Division 0.75 / 11.0
DivT(Var1, Var2, Var3) ;Var3 = Var1 / Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Division 0.75/11.0","Single-Float: "+StrF(0.75/11.0,20)+#LFCR$+"Double-Float: "+StrD(0.75/11.0,20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.068181818181818181818181818181818")
;-------- Beispiel Multiplikation 0.75 * 11.0
MulT(Var1, Var2, Var3) ;Var3 = Var1 * Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Multiplikation 0.75*11.0","Single-Float: "+StrF(0.75*11.0,20)+#LFCR$+"Double-Float: "+StrD(0.75*11.0,20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 8.25")
;-------- Beispiel Laden der Konstante Pi als Beispiel für alle Konstanten (s.Procfpu80.pbi)
PiT(Var3) ;Var3 = Pi
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe DAS Ergebnis als String (Convert$)
MessageRequester("Beispiel Laden der Konstante Pi","Single-Float: "+StrF(#PI,20)+#LFCR$+"Double-Float: "+StrD(#PI,20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 3.1415926535897932384626433832795")
;-------- Beispiel Potenzierung 0.75 ^ 11.0
Powt(Var1, Var2, Var3) ;Var3 = Var1 ^ Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Potenzierung 0.75^11.0","Single-Float: "+StrF(Pow(0.75,11.0),20)+#LFCR$+"Double-Float: "+StrD(Pow(0.75,11.0),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.0422351360321044921875")
;-------- Beispiel Sinus(0.75)
SinT(Var1, Var3) ;Var3 = Sin(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Sin(0.75)","Single-Float: "+StrF(Sin(0.75),20)+#LFCR$+"Double-Float: "+StrD(Sin(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.68163876002333416673324195277989")
;-------- Beispiel Quadratwurzel(0.75)
SqrT(Var1, Var3) ;Var3 = Sqr(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Sqr(0.75)","Single-Float: "+StrF(Sqr(0.75),20)+#LFCR$+"Double-Float: "+StrD(Sqr(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.86602540378443864676372317075294")
;-------- Beispiel Subtraktion 0.75 - 11.0
SubT(Var1, Var2, Var3) ;Var3 = Var1 - Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Subtraktion 0.75-11.0","Single-Float: "+StrF(0.75-11.0,20)+#LFCR$+"Double-Float: "+StrD(0.75-11.0,20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: -10.25")
;-------- Beispiel Tangens(0.75)
TanT(Var1, Var3) ;Var3 = Tan(Var1)
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Tan(0.75)","Single-Float: "+StrF(Tan(0.75),20)+#LFCR$+"Double-Float: "+StrD(Tan(0.75),20)+#LFCR$+"80-Bit-Float: "+Convert$+#LFCR$+"Windows-R.: 0.93159645994407246116520275657394")
;-------- Beispiel Compare
If CompT(Var1, Var2) = 0
MessageRequester("Compare","Var1 und Var2 sind gleich")
ElseIf Compt(Var1, Var2) = 1
MessageRequester("Compare","Var1 ist kleiner als Var2")
ElseIf Compt(Var1, Var2) = 2
MessageRequester("Compare","Var1 ist grösser als Var2")
EndIf
;-------- Beispiel Copy
CopyT(Var3, Var1) ;kopiert Var1 in Var3
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Copy", "Var3 hat jetzt den Wert " + Convert$)
;-------- Beispiel Change
ChangeT(Var1, Var2) ;vertauscht Var1 und Var2
StrT(@Convert$, Var1) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Change", "Var1 hat jetzt den Wert " + Convert$)
StrT(@Convert$, Var2)
MessageRequester("Beispiel für Change", "Var2 hat jetzt den Wert " + Convert$)
;-------- Beispiel Val
Teststring1$ = "0.19e4732"
ValT(@Teststring1$, Var1)
Teststring2$ = "0.11e4932"
ValT(@Teststring2$, Var2)
DivT(Var1, Var2, Var3) ;Var3 = Var1 / Var2
StrT(@Convert$, Var3) ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Val", "Der Quotient der beiden Teststring-Werte beträgt " + Convert$)
End
Code: Alles auswählen
;-------- Include-File Procfpu80.pbi
;-------- Bildschirm-Ausgabe und Funktionen 80-Bit-FPU
;-------- "Helle" Klaus Helbing, 20.05.2007, PB4.02
;-------- Es wurde darauf geachtet, das der TOS nach Verlassen der jeweiligen Prozedur
;-------- immer auf St(0) zeigt und St(0) leer ist
;-------- Str --------------- Variable1 = Str(Variable2) -----------------
Procedure StrT(Variable1, Variable2)
;- Dient nur zur Bildschirm-Ausgabe, hat mit Berechnungen nichts zu tun!
;- Der 10-Byte-Float-Wert von Variable2 wird in einen String konvertiert
;- Benötigt CPU mit SSE2!
;- Intern:
;- Fall 1: 0.00000000... bis 0.999999999999999999939999999999
;- Fall 2: 18446744073709551616 bis ...
;- Fall 3: 1.0 bis 18446744073709551615 (2^64-1)
;- Werte gelten auch für negative Zahlen
;- Werte-Bereich: 80-Bit : 2^-16382 ... 2^16384; Zifferngenau bis ca. 1.084x10^-19
;- Zum Vergleich: Single-Float: 2^-126 ... 2^128; " " " " 1.192x10^-7
;- Double-Float: 2^-1022 ... 2^1024; " " " " 2.220x10^-16
!xor eax,eax
!mov ebx,eax
!mov [StringZ],eax
!@@:
!mov dword[String1+ebx],eax
!add ebx,4
!cmp ebx,1024
!jb @b
!mov edi,[p.v_Variable2] ;Zeiger auf umzuwandelnden String
;-------- Vorzeichen und Exponent
!mov cx,[edi+8] ;Vorzeichen und Exponent
!and cx,cx ;Test, ob MSB (Bit15) gesetzt ist
!jns @f ;nein, Vorzeichen ist plus
!mov [StringA],2dh ;"-"
!mov [StringZ],1
!and cx,7fffh ;Vorzeichen-Bit löschen
!@@:
!sub cx,16383 ;Bias ("Versatz") subtrahieren, um "echten" Exponenten (auf Zweier-Basis) zu erhalten
;-------- Die 64-Bit-Mantisse einlesen
!mov eax,[edi+4] ;Mantisse High-Anteil
!mov ebx,[edi] ;Mantisse Low-Anteil
!mov dword[Mantisse],ebx
!mov dword[Mantisse+4],eax
;-------- Auswertung
;-------- Test,ob Exponent = -16383, d.h. von FPU als Null zurückgegeben
!cmp cx,-16383 ;Exponent
!jne @f
!or eax,eax ;Mantisse High-Anteil da der Sinn nicht die Exponential-Darstellung ist könnte auch hier abgebrochen werden
!jnz @f ;d.h. Wert auch Null
!or ebx,ebx
!jnz @f
!mov dword[StringA],20302e30h ;"0.0 "
!mov edi,[p.v_Variable1] ;Pointer auf String, in den geschrieben werden soll
!mov ebx,4 ;4 Bytes Ausgabe
!jmp l_merker_ende
;------------------------------------------------
!@@:
!mov [Trenner],63
!sub [Trenner],cx
!and cx,cx
!jns l_wnnx ;Exponent nicht negativ
;-------- Exponent < 0
!mov esi,[StringZ]
!mov word[StringA+esi],2e30h ;"0."
!add [StringZ],2
!mov [F],5
!mov [Merker],1
!jmp l_ziffern_bestimmen
;-------- Exponent >= 0
WNNX:
!cmp [Trenner],0
!jge @f
!neg [Trenner]
!mov [F],2 ;wenn Trenner kleiner Null wird mit 2 multipliziert!!!
!mov [Merker],2
!jmp l_ziffern_bestimmen
!@@:
!mov [F],5
!mov [Merker],3
;-------- "String" erzeugen
Ziffern_bestimmen:
!movq xmm0,[Mantisse] ;Ursprungswert laden
!lea esi,[Teiler] ;Beginn der Zehner-Potenzen
!lea edi,[String1] ;zum Abspeichern
!add edi,1004
!mov ecx,19 ;noch 19 Bytes, das 1.wird vor der Schleife gesetzt (kann nur 0 oder 1 sein)
!movmskpd eax,xmm0 ;Test auf MSB
!test eax,1 ;testet Bit 63!
!jz l_w11 ;nicht gesetzt, Mantisse kleiner als 9223372036854775808 (8000000000000000h)
;- Test ob Mantisse < 10000000000000000000
!movq xmm1,[esi]
!psubq xmm0,xmm1
!movmskpd eax,xmm0 ;Test auf MSB
!test eax,1 ;testet Bit 63!
!jnz @f ;kleiner als 10000000000000000000
!mov byte[edi],1 ;"1" setzen an höchste Stelle
!movq [Mantisse],xmm0 ;neuer Mantissen-Wert
!jmp l_w11
!@@:
!movq xmm0,[Mantisse] ;alten Mantissen-Wert wiederherstellen
;--------------------------------
W11:
!inc edi ;eine Stelle im "String" weiter
!add esi,8
W1:
!movq xmm1,[esi] ;(neue) Zehner-Potenz laden
!@@:
!psubq xmm0,xmm1 ;Mantisse minus Teiler
!movmskpd eax,xmm0
!test eax,1
!jnz @f
!movq [Mantisse],xmm0
!inc byte[edi]
!jmp @b
!@@:
!movq xmm0,[Mantisse]
!add esi,8
!inc edi
!dec ecx
!jnz l_w1
;- Komma ist hier auch Länge Ausgangs-String
!mov dword[Komma],20
!lea edi,[String1]
!add edi,1004
!mov ebx,20 ;Abbruch erfolgt sowieso früher
!@@:
!cmp byte[edi],0 ;auf führende Ziffer testen
!ja @f
!dec [Komma]
!inc edi
!dec ebx
!jnz @b
!@@:
!mov eax,[Komma]
!mov [Len],eax
!cmp [Trenner],0
!je l_trenner_0
!mov ecx,1
Schleife_fuer_4:
;------- wenn F=5 Ausgangswert umkopieren für 5=4+1
!cmp [F],5
!jne l_w2_1
!lea edi,[String1]
!add edi,1020
!lea esi,[String2]
!add esi,1020
!mov ebx,[Len]
!shr ebx,2
!inc ebx ;genug Reserve!
!@@:
!mov eax,[edi]
!mov [esi],eax
!sub edi,4
!sub esi,4
!dec ebx
!jnz @b
W2_1:
;-------
!mov edx,2 ;Zähler für x4
W1_1: ;für Schleife x4
!lea edi,[String1]
!add edi,1023 ;Ende des Strings
!mov ebx,[Len]
!xor ah,ah
W0_1: ;für Schleife x2
!mov al,[edi]
!add al,al
!add al,ah
!xor ah,ah
!cmp al,10
!jb l_nicht_10
!sub al,10
!inc ah
!cmp ebx,1
!jne @f
!inc [Len]
!inc ebx
!@@:
Nicht_10:
!mov [edi],al
!dec edi
!dec ebx
!jnz l_w0_1
!cmp [F],2
!je l_nur_2 ;nur "Multiplikation" mit 2
!dec edx
!jnz l_w1_1 ;zweiter Durchlauf für 2+2
;- hier 4+1 als "Multiplikation" mit 5
!xor ah,ah
!mov ebx,[Len]
!lea edi,[String1]
!add edi,1023
!lea esi,[String2]
!add esi,1023
W3_1:
!mov al,[edi]
!mov dl,[esi]
!add al,dl
!add al,ah
!xor ah,ah
!cmp al,10
!jb l_nicht_10_1
!sub al,10
!inc ah
!cmp ebx,1
!jne @f
!inc [Len]
!inc ebx
!@@:
Nicht_10_1:
!mov [edi],al
!dec edi
!dec esi
!dec ebx
!jnz l_w3_1
Nur_2:
!cmp byte[edi+1],1
!ja @f
!dec [Komma]
!@@:
!inc ecx
!cmp cx,[Trenner]
!jbe l_schleife_fuer_4
!cmp byte[edi+1],2 ;wenn 2 oder grösser noch eine Stelle mehr
!jb @f
!dec [Komma]
!@@:
;----------------------------------
Trenner_0:
!mov edi,[p.v_Variable1] ;Pointer auf String, in den geschrieben werden soll
!cmp [Merker],1 ;"0."
!jne l_ob_merker2
;-------- Merker = 1
!movzx ecx,[Trenner]
!mov ebx,[StringZ]
!sub ecx,[Len]
!jz l_null_1
!@@:
!mov byte[StringA+ebx],30h
!inc ebx
!dec ecx
!jnz @b
Null_1:
!lea esi,[String1]
!add esi,1024
!mov ecx,20
!sub esi,[Len]
!@@:
!mov al,[esi]
!add al,30h
!mov [StringA+ebx],al
!inc esi
!inc ebx
!dec ecx
!jnz @b
!jmp l_merker_ende
Ob_Merker2:
!cmp [Merker],2
!jne l_merker3
;-------- Merker = 2
Merker2:
!mov ebx,[StringZ] ;Zeiger in StringA
!lea esi,[String1]
!add esi,1024
!mov ecx,20
!sub esi,[Len]
!@@:
!mov al,[esi]
!add al,30h
!mov [StringA+ebx],al
!inc esi
!inc ebx
!dec ecx
!jnz @b
!mov ecx,[Len]
!sub ecx,ebx
!jz l_null_2
!@@:
!mov byte[StringA+ebx],30h
!inc ebx
!dec ecx
!jnz @b
Null_2:
!jmp l_merker_ende
;-------- Merker = 3
Merker3:
!mov ebx,[StringZ]
!lea esi,[String1]
!add esi,1024
!sub esi,[Len]
!mov ecx,[Komma]
!@@:
!mov al,[esi]
!add al,30h
!mov [StringA+ebx],al
!inc esi
!inc ebx
!dec ecx
!js @f
!jnz @b
!@@:
!mov ecx,20
!sub ecx,[Komma]
!jz l_merker_ende
!mov [StringA+ebx],2eh
!inc ebx
!@@:
!mov al,[esi]
!add al,30h
!mov [StringA+ebx],al
!inc esi
!inc ebx
!dec ecx
!jnz @b
Merker_Ende:
!lea esi,[StringA]
!mov ecx,ebx
!cld
!rep movsb
!mov byte[edi],0 ;für das String-Ende das Zero-Byte setzen
ProcedureReturn
End
!section '.data' Data readable writeable
!String1 RB 1024 ;eigentlicher Berechnungs-String; für Extrem-Werte ALLE String-Bezüge vergrössern!
!String2 RB 1024 ;Hilfs-String für die Multiplikation mit 5 = 4 + 1
!StringA RB 256 ;256 Byte für String-Ausgabe
!Mantisse DQ 0
!Teiler DQ 10000000000000000000
! DQ 1000000000000000000
! DQ 100000000000000000
! DQ 10000000000000000
! DQ 1000000000000000
! DQ 100000000000000
! DQ 10000000000000
! DQ 1000000000000
! DQ 100000000000
! DQ 10000000000
! DQ 1000000000
! DQ 100000000
! DQ 10000000
! DQ 1000000
! DQ 100000
! DQ 10000
! DQ 1000
! DQ 100
! DQ 10
! DQ 1
!F DD 0
!Komma DD 0
!Merker DD 0
!StringZ DD 0 ;Zeiger in String StringZähler
!Len DD 0
!Trenner DW 0
EndProcedure
;-------------------------------------------------------------------------
;-------- Val --------------- Variable2 = Val(Variable1) -----------------
Procedure ValT(Variable1, Variable2) ;Variable1 = Zeiger auf String, Variable2 = Ausgabe
;- Grundlage: Tim Roberts und pelaillo (FAsm-Forum), 30.Dezember 2002
;- Fehler beseitigt und an PB angepasst
;- Label-Namen wegen besserer Übersicht nicht weggekürzt (also keine "@")
!fninit
!xor eax,eax
!mov ebx,eax
!mov ecx,eax
!mov [ManVorzeichen],eax
!mov [ExpVorzeichen],eax
!mov [Dezimalpunkt],eax
!mov esi,[p.v_Variable1]
!mov al,[esi]
!cmp al,2dh ;"-"
!je l_minus_vorzeichen
!cmp al,2bh ;"+" Test auf pos. Vorzeichen erstmal drinlassen
!je l_plus_vorzeichen
!jmp l_vorzeichen_ende
Minus_Vorzeichen:
!inc [ManVorzeichen]
Plus_Vorzeichen:
!inc esi
!mov al,[esi]
Vorzeichen_Ende:
!fldz
Mantisse_Lesen:
!cmp al,45h ;"E"
!je l_exponent
!cmp al,65h ;"e"
!je l_exponent
!cmp al,2eh ;"."
!je l_dezimal_punkt
!xor al,30h ;"0"
!cmp al,9
!ja l_ziffern_ende
!mov [Temp],eax
!fmul [Zehner]
!fiadd word[Temp]
!inc ebx
!jmp l_kein_punkt
Dezimal_Punkt:
!cmp [Dezimalpunkt],0
!jne l_ziffern_ende
!mov [Dezimalpunkt],ebx
Kein_Punkt:
!inc esi
!mov al,[esi]
!jmp l_mantisse_lesen
Exponent:
!inc esi
!mov al,[esi]
!cmp al,2dh ;"-"
!je l_minus_exponent_vorzeichen
!cmp al,2bh ;"+"
!je l_plus_exponent_vorzeichen
!jmp l_exponent_lesen
Minus_Exponent_Vorzeichen:
!inc [ExpVorzeichen]
Plus_Exponent_Vorzeichen:
!inc esi
!mov al,[esi]
Exponent_Lesen:
!xor al,30h ;"0"
!cmp al,9
!ja l_ziffern_ende
!lea ecx,[ecx*4+ecx]
!lea ecx,[ecx*2+eax]
!inc esi
!mov al,[esi]
!jmp l_exponent_lesen
Ziffern_Ende:
!cmp [ExpVorzeichen],0
!je l_exponent_fertig
!neg ecx
Exponent_Fertig:
!mov eax,[Dezimalpunkt]
!or eax,eax
!jz l_kein_dezimalpunkt
!sub ebx,eax
!sub ecx,ebx
Kein_Dezimalpunkt:
!or ecx,ecx
!jz l_kein_exponent
!mov eax,ecx
!cmp eax,0
!jge l_exponent_vorzeichen_ok
!neg eax
Exponent_Vorzeichen_Ok:
!fld1
!mov dl,al
!and edx,0fh
!je l_groesserer_exponent
!lea edx,dword[edx+edx*4]
!fld tword [edx*2+Zehner_1-10]
!fmulp st1,st
Groesserer_Exponent:
!mov dl,al
!shr dl,4
!and edx,0fh
!je l_noch_groesserer_exponent
!lea edx,dword[edx+edx*4]
!fld tword [edx*2+Zehner_16-10]
!fmulp st1,st
Noch_Groesserer_Exponent:
!mov dl,ah
!and edx,1fh
!je l_exponent_vorzeichen
!lea edx,dword[edx+edx*4]
!fld tword[edx*2+Zehner_256-10]
!fmulp st1,st
Exponent_Vorzeichen:
!cmp ecx,0
!jge l_positiver_exponent
!fdivp st1,st
!jmp l_kein_exponent
Positiver_Exponent:
!fmulp st1,st
Kein_Exponent:
!cmp [ManVorzeichen],0
!je @f
!fchs
!@@:
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;leert damit auch den TOS
ProcedureReturn
End
!section '.data' Data readable writeable
!ManVorzeichen dd 0
!ExpVorzeichen dd 0
!Dezimalpunkt dd 0
!Temp dd 0
!Zehner dq 10.0
!Zehner_1 dt 1.0e1
! dt 1.0e2
! dt 1.0e3
! dt 1.0e4
! dt 1.0e5
! dt 1.0e6
! dt 1.0e7
! dt 1.0e8
! dt 1.0e9
! dt 1.0e10
! dt 1.0e11
! dt 1.0e12
! dt 1.0e13
! dt 1.0e14
! dt 1.0e15
!Zehner_16 dt 1.0e16
! dt 1.0e32
! dt 1.0e48
! dt 1.0e64
! dt 1.0e80
! dt 1.0e96
! dt 1.0e112
! dt 1.0e128
! dt 1.0e144
! dt 1.0e160
! dt 1.0e176
! dt 1.0e192
! dt 1.0e208
! dt 1.0e224
! dt 1.0e240
!Zehner_256 dt 1.0e256
! dt 1.0e512
! dt 1.0e768
! dt 1.0e1024
! dt 1.0e1280
! dt 1.0e1536
! dt 1.0e1792
! dt 1.0e2048
! dt 1.0e2304
! dt 1.0e2560
! dt 1.0e2816
! dt 1.0e3072
! dt 1.0e3328
! dt 1.0e3584
! dt 1.0e3840
! dt 1.0e4096
! dt 1.0e4352
! dt 1.0e4608
! dt 1.0e4864
EndProcedure
;-------------------------------------------------------------------------
;-------- ARITHMETISCHE FUNKTIONEN ---------------------------------------
;-------- Addition ---------- Variable3 = Variable1 + Variable2 ----------
Procedure AddT(Variable1, Variable2, Variable3)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!mov esi,[p.v_Variable2]
!fld tword[esi]
!faddp st1,st0
!mov esi,[p.v_Variable3]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Division ---------- Variable3 = Variable1 / Variable2 ----------
Procedure DivT(Variable1, Variable2, Variable3)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!mov esi,[p.v_Variable2]
!fld tword[esi]
!fdivp st1,st0
!mov esi,[p.v_Variable3]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Multiplikation ---- Variable3 = Variable1 * Variable2 ----------
Procedure MulT(Variable1, Variable2, Variable3)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!mov esi,[p.v_Variable2]
!fld tword[esi]
!fmulp st1,st0
!mov esi,[p.v_Variable3]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Quadratwurzel ----- Variable2 = Variable1 ^ 0.5 ----------------
Procedure SqrT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fsqrt
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Subtraktion ------- Variable3 = Variable1 - Variable2 ----------
Procedure SubT(Variable1, Variable2, Variable3)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!mov esi,[p.v_Variable2]
!fld tword[esi]
!fsubp st1,st0
!mov esi,[p.v_Variable3]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- WINKELFUNKTIONEN -----------------------------------------------
;-------- ArcusCosinus ------ Variable2 = ACos(Variable1(rad)) -----------
Procedure ACosT(Variable1, Variable2)
!fninit
!fld1
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fst st2
!fmul st0,st0
!fsubp
!fsqrt
!fxch
!fpatan
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
!fdecstp
!ffree st0
EndProcedure
;-------- ArcusCotangens ---- Variable2 = ACot(Variable1(rad)) -----------
Procedure ACotT(Variable1, Variable2) ;Pi/2 - arctan(x)
!fninit
!fldpi
!fld1
!fld1
!faddp
!fdivp
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fld1
!fpatan
!fsubp
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------- ArcusSinus -------- Variable2 = ASin(Variable1(rad)) -----------
Procedure ASinT(Variable1, Variable2)
!fninit
!fld1
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fst st2
!fmul st0,st0
!fsubp
!fsqrt
!fpatan
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
!fdecstp ;Stack-Bereinigung, TOS ist danach ST(0)
!ffree st0 ;ST(0) als leer deklarieren
EndProcedure
;-------- ArcusTangens ------ Variable2 = ATan(Variable1(rad)) -----------
Procedure ATanT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fld1
!fpatan
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------- Cosinus ----------- Variable2 = Cos(Variable1(rad)) ------------
Procedure CosT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fcos
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Cotangens --------- Variable2 = Cot(Variable1(rad)) ------------
Procedure CotT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fptan
!fdivrp st1,st0
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Sinus ------------- Variable2 = Sin(Variable1(rad)) ------------
Procedure SinT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fsin
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Tangens ----------- Variable2 = Tan(Variable1(rad)) ------------
Procedure TanT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fptan
!fdivp st1,st0
!mov esi,[p.v_Variable2]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- ERWEITERTE FUNKTIONEN ------------------------------------------
;-------- Pow --------------- Variable3 = Variable1 ^ Variable2 ----------
Procedure PowT(Variable1, Variable2, Variable3)
!fninit
!mov esi,[p.v_Variable2]
!fld tword[esi]
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fyl2x
!fld st0
!frndint
!fsub st1,st0
!fxch st1
!f2xm1
!fld1
!faddp st1,st0
!fscale
!fstp st1
!mov esi,[p.v_Variable3]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- KONSTANTEN -----------------------------------------------------
;-------- L0 ---------------- Variable1 = 0.0 ----------------------------
Procedure L0T(Variable1)
!fninit
!fldz ;00000000000000000000h = 0.0
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- L1 ---------------- Variable1 = 1.0 ----------------------------
Procedure L1T(Variable1)
!fninit
!fld1 ;3FFF8000000000000000h = 1.0
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Ld(10) ------------ Variable1 = Ld(10), 2 ^ Variable1 =10.0 ----
Procedure Ld10T(Variable1)
!fninit
!fldl2t ;4000D49A784BCD1B8AFEh = 3.3219280948873623478
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Ld(e) ------------- Variable1 = Ld(e), 2 ^ Variable1 = e -------
Procedure LdeT(Variable1)
!fninit
!fldl2e ;3FFFB8AA3B295C17F0BCh = 1.4426950408889634073
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Lg(2) ------------- Variable1 = Lg(2), 10 ^ Variable1 = 2.0 ----
Procedure Lg2T(Variable1)
!fninit
!fldlg2 ;3FFFB17217F7D1CF79ACh = 0.301029995663981195198
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Ln(2) ------------- Variable1 = Ln(2), e ^ Variable1 = 2.0 -----
Procedure Ln2T(Variable1)
!fninit
!fldln2 ;3FFD9A209A84FBCFF799h = 0.6931471805599453094
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- Pi ---------------- Variable1 = Pi -----------------------------
Procedure PiT(Variable1)
!fninit
!fldpi ;4000C90FDAA22168C335h = 3.1415926535897932385
!mov esi,[p.v_Variable1]
!fstp tword[esi] ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------
;-------- SONSTIGES ------------------------------------------------------
;-------- Change ------------ Vertauscht die Werte der beiden Variablen --
Procedure ChangeT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable1]
!fld tword[esi]
!mov edi,[p.v_Variable2]
!fld tword[edi]
!fstp tword[esi]
!fstp tword[edi]
EndProcedure
;-------------------------------------------------------------------------
;-------- Compare ----------- Vergleicht Variable1 mit Variable2 ---------
Procedure CompT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable2]
!fld tword[esi]
!mov esi,[p.v_Variable1]
!fld tword[esi]
!fcompp
!fstsw ax ;nicht fnstsw!
!sahf
!jne @f ;nicht gleich
!xor eax,eax
ProcedureReturn ;Rückgabewert=0 für Variable1 gleich Variable2
!@@:
!jnc @f ;nicht kleiner
!mov eax,1
ProcedureReturn ;Rückgabewert=1 für Variable1 kleiner als Variable2
!@@:
!mov eax,2
ProcedureReturn ;Rückgabewert=2 für Variable1 grösser als Variable2
EndProcedure
;-------------------------------------------------------------------------
;-------- Copy -------------- kopiert Variable2 in Variable1 -------------
Procedure CopyT(Variable1, Variable2)
!fninit
!mov esi,[p.v_Variable2]
!fld tword[esi]
!mov esi,[p.v_Variable1]
!fstp tword[esi]
EndProcedure
;-------------------------------------------------------------------------