FPU-Helferlein

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

FPU-Helferlein

Beitrag von Helle »

Wer sich schonmal an der FPU-Programmierung versucht hat wird mit Sicherheit auch schon kurz vor einem mittelschweren Wutausbruch gestanden haben: Kommentarloser Abbruch, keine Fehlermeldung. Hier ein Hilfsprogramm; den "Vorspann" habe ich drin gelassen.

Code: Alles auswählen

;- FPU-Helferlein
;- "Helle" Klaus Helbing, 12.08.2007, PB4.02

;===================================================================================================
;- FPU-STATUS-REGISTER:
;      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+       
;  Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9  | 8  | 7  | 6  | 5  | 4  | 3  | 2  | 1  | 0  | 
;      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
;      | B  | C3 |     Top      | C2 | C1 | C0 | E  | S  | P  | U  | O  | Z  | D  | I  |
;      +----+----+--------------+----+----+----+----+----+----+----+----+----+----+----+ 
;- Bedeutung:
;- I:   Invalid Operation; es wurde eine ungültige Operation durchgeführt
;- D:   Denormalized Operand; eine denormalisierte Zahl wurde verwendet
;- Z:   Zero Divide; es wurde versucht, durch Null zu dividieren
;- O:   Overflow; mit der vorhergehenden Operation wurde der maximal darstellbare Wert überschritten
;- U:   Underflow; mit der vorhergehenden Operation wurde der minimal darstellbare Wert unterschritten
;- P:   Precision; die Genauigkeit der Berechnung ist unzureichend, z.B. eingestellte Genauigkeit ist
;                  Double Extended Precision, aber es werden Double- oder Single-Precision-Werte geladen 
;- S:   Stack Fault; es wurde versucht, einen Wert zu laden, obwohl alle Register belegt sind
;                    oder ein leeres Register soll gepoppt werden
;- E:   Error Summary Status 
;- C0:  Condition Code 0; Flag für z.B. Vergleiche 
;- C1:  Condition Code 1; Flag für z.B. angewandte Rundung
;- C2:  Condition Code 2; Flag für z.B. Vergleiche
;- Top: Top of Stack; Wert zwischen 0 und 7, gibt an, welches Register aktuell das oberste ist
;- C3:  Condition Code 3; Flag für z.B. Vergleiche
;- B:   Busy; signalisiert, das die FPU beschäftigt ist
;- Mittels
   ;!fnstsw ax     ;Status-Word der FPU in Register AX kopieren
   ;!sahf          ;Register AH in CPU-Flag-Register kopieren
;- lassen sich C0, C2, C3 und Busy direkt auswerten. Es gelten dann folgende Zuordnungen:
;- C0 = Carry-Flag
;- C2 = Parity-Flag
;- C3 = Zero-Flag  
;- B  = Sign-Flag 
;===================================================================================================
;- FPU-CONTROL-REGISTER:
;      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+       
;  Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9  | 8  | 7  | 6  | 5  | 4  | 3  | 2  | 1  | 0  | 
;      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
;      |              | IC |   RC    |   PC    |    |    | P  | U  | O  | Z  | D  | I  |
;      +--------------+----+---------+---------+----+----+----+----+----+----+----+----+ 
;- Bedeutung:
;- I:  Invalid Operation; es wurde eine ungültige Operation durchgeführt
;- D:  Denormalized Operand; eine denormalisierte Zahl wurde verwendet
;- Z:  Zero Divide; es wurde versucht, durch Null zu dividieren
;- O:  Overflow; mit der vorhergehenden Operation wurde der maximal darstellbare Wert überschritten
;- U:  Underflow; mit der vorhergehenden Operation wurde der minimal darstellbare Wert unterschritten
;- P:  Precision; die Genauigkeit der Berechnung ist unzureichend; es wurden Double-oder Single-
;                 Precision-Werte geladen
;- PC: Precision Control; aktuell eingestellte Genauigkeit der Mantisse:
;                         00b = 0 = Single Precision 24 Bits
;                         01b = 1 = Reserviert
;                         10b = 2 = Double Precision 53 Bits
;                         11b = 3 = Double Extended Precision 64 Bits; Initialisierungs-Wert
;- RC: Rounding Control; aktuell eingestellter Rundungs-Modus:
;                         00b = 0 = Rundung zum nächsten Wert oder bei Gleichheit zum geraden Wert;
;                                   Initialisierungs-Wert
;                         01b = 1 = Rundung in Richtung minus Unendlich
;                         10b = 2 = Rundung in Richtung plus Unendlich 
;                         11b = 3 = Rundung in Richtung Null, d.h. der Nachkomma-Anteil wird
;                                   abgeschnitten 
;- IC: Infinity Control; aktuell eingestelltes Verfahren zur Unendlichkeits-Handhabung:    
;                          0b = 0 = projektives Verfahren, ist ein Zahlenkreis, minus und plus
;                                   Unendlich treffen sich in einem Punkt; Initialisierungs-Wert
;                          1b = 1 = affines Verfahren, ist eine Zahlen-Gerade mit den beiden Achs-
;                                   Endpunkten minus Unendlich und plus Unendlich 
;===================================================================================================
;OPCODES alphabetisch bzw. thematisch:
;D9 F0        F2XM1               Replace ST(0) with (2^ST(0))-1.
;D9 E1        FABS                Replace ST with its absolute value.
;D8 /0        FADD m32fp          Add m32fp To ST(0) and store result in ST(0).
;DC /0        FADD m64fp          Add m64fp To ST(0) and store result in ST(0).
;D8 C0+i      FADD ST(0), ST(i)   Add ST(0) To ST(i) and store result in ST(0).
;DC C0+i      FADD ST(i), ST(0)   Add ST(i) To ST(0) and store result in ST(i).
;DE C0+i      FADDP ST(i), ST(0)  Add ST(0) To ST(i), store result in ST(i), and pop the register stack.
;DE C1        FADDP               Add ST(0) To ST(1), store result in ST(1), and pop the register stack.
;DA /0        FIADD m32int        Add m32int To ST(0) and store result in ST(0).
;DE /0        FIADD m16int        Add m16int To ST(0) and store result in ST(0).
;DF /4        FBLD m80 dec        Convert BCD value to floating-point and push onto the FPU stack.
;DF /6        FBSTP m80bcd        Store ST(0) in m80bcd and pop ST(0).
;D9 E0        FCHS                Complements sign of ST(0).
;9B DB E2     FCLEX               Clear floating-point exception flags after checking for pending
;                                 unmasked floating-point exceptions.
;DB E2        FNCLEX              Clear floating-point exception flags without checking for
;                                 pending unmasked floating-point exceptions.
;DA C0+i      FCMOVB ST(0), ST(i) Move if below (CF=1).
;DA C8+i      FCMOVE ST(0), ST(i) Move if equal (ZF=1).
;DA D0+i      FCMOVBE ST(0), ST(i) Move if below or equal (CF=1 or ZF=1).
;DA D8+i      FCMOVU ST(0), ST(i) Move if unordered (PF=1).
;DB C0+i      FCMOVNB ST(0), ST(i) Move if not below (CF=0).
;DB C8+i      FCMOVNE ST(0), ST(i) Move if not equal (ZF=0).
;DB D0+i      FCMOVNBE ST(0), ST(i) Move if not below or equal (CF=0 and ZF=0).
;DB D8+i      FCMOVNU ST(0), ST(i) Move if not unordered (PF=0).
;D8 /2        FCOM m32fp          Compare ST(0) with m32fp.
;DC /2        FCOM m64fp          Compare ST(0) with m64fp.
;D8 D0+i      FCOM ST(i)          Compare ST(0) with ST(i).
;D8 D1        FCOM                Compare ST(0) With ST(1).
;D8 /3        FCOMP m32fp         Compare ST(0) with m32fp and pop register stack.
;DC /3        FCOMP m64fp         Compare ST(0) with m64fp and pop register stack.
;D8 D8+i      FCOMP ST(i)         Compare ST(0) with ST(i) and pop register stack.
;D8 D9        FCOMP               Compare ST(0) with ST(1) and pop register stack.
;DE D9        FCOMPP              Compare ST(0) with ST(1) and pop register stack twice.
;DB F0+i      FCOMI ST, ST(i)     Compare ST(0) with ST(i) and set status flags accordingly.
;DF F0+i      FCOMIP ST, ST(i)    Compare ST(0) with ST(i), set status flags accordingly, and
;                                 pop register stack.
;DB E8+i      FUCOMI ST, ST(i)    Compare ST(0) with ST(i), check for ordered values, and set
;                                 status flags accordingly.
;DF E8+i      FUCOMIP ST, ST(i)   Compare ST(0) with ST(i), check for ordered values, set status
;                                 flags accordingly, and pop register stack.
;D9 FF        FCOS                Replace ST(0) with its cosine.
;D9 F6        FDECSTP             Decrement TOP field in FPU status word.
;D8 /6        FDIV m32fp          Divide ST(0) by m32fp and store result in ST(0).
;DC /6        FDIV m64fp          Divide ST(0) by m64fp and store result in ST(0).
;D8 F0+i      FDIV ST(0), ST(i)   Divide ST(0) by ST(i) and store result in ST(0).
;DC F8+i      FDIV ST(i), ST(0)   Divide ST(i) by ST(0) and store result in ST(i).
;DE F8+i      FDIVP ST(i), ST(0)  Divide ST(i) by ST(0), store result in ST(i), and pop the
;                                 register stack.
;DE F9        FDIVP               Divide ST(1) by ST(0), store result in ST(1), and pop the
;                                 register stack.
;DA /6        FIDIV m32int        Divide ST(0) by m32int and store result in ST(0).
;DE /6        FIDIV m16int        Divide ST(0) by m64int and store result in ST(0).
;D8 /7        FDIVR m32fp         Divide m32fp by ST(0) and store result in ST(0).
;DC /7        FDIVR m64fp         Divide m64fp by ST(0) and store result in ST(0).
;D8 F8+i      FDIVR ST(0), ST(i)  Divide ST(i) by ST(0) and store result in ST(0).
;DC F0+i      FDIVR ST(i), ST(0)  Divide ST(0) by ST(i) and store result in ST(i).
;DE F0+i      FDIVRP ST(i), ST(0) Divide ST(0) by ST(i), store result in ST(i), and pop the
;                                 register stack.
;DE F1        FDIVRP              Divide ST(0) by ST(1), store result in ST(1), and pop the
;                                 register stack.
;DA /7        FIDIVR m32int       Divide m32int by ST(0) and store result in ST(0).
;DE /7        FIDIVR m16int       Divide m16int by ST(0) and store result in ST(0).
;DD C0+i      FFREE ST(i)         Sets tag for ST(i) to empty.
;DE /2        FICOM m16int        Compare ST(0) with m16int.
;DA /2        FICOM m32int        Compare ST(0) with m32int.
;DE /3        FICOMP m16int       Compare ST(0) with m16int and pop stack register.
;DA /3        FICOMP m32int       Compare ST(0) with m32int and pop stack register.
;DF /0        FILD m16int         Push m16int onto the FPU register stack.
;DB /0        FILD m32int         Push m32int onto the FPU register stack.
;DF /5        FILD m64int         Push m64int onto the FPU register stack.
;D9 F7        FINCSTP             Increment the TOP field in the FPU status register.
;9B DB E3     FINIT               Initialize FPU after checking for pending unmasked
;                                 floating-point exceptions.
;DB E3        FNINIT              Initialize FPU without checking for pending unmasked
;                                 floating-point exceptions.
;DF /2        FIST m16int         Store ST(0) in m16int.
;DB /2        FIST m32int         Store ST(0) in m32int.
;DF /3        FISTP m16int        Store ST(0) in m16int and pop register stack.
;DB /3        FISTP m32int        Store ST(0) in m32int and pop register stack.
;DF /7        FISTP m64int        Store ST(0) in m64int and pop register stack.
;DF /1        FISTTP m16int       Store ST(0) in m16int with truncation.
;DB /1        FISTTP m32int       Store ST(0) in m32int with truncation.
;DD /1        FISTTP m64int       Store ST(0) in m64int with truncation.
;D9 /0        FLD m32fp           Push m32fp onto the FPU register stack.
;DD /0        FLD m64fp           Push m64fp onto the FPU register stack.
;DB /5        FLD m80fp           Push m80fp onto the FPU register stack.
;D9 C0+i      FLD ST(i)           Push ST(i) onto the FPU register stack.
;D9 E8        FLD1                Push +1.0 onto the FPU register stack.
;D9 E9        FLDL2T              Push log210 onto the FPU register stack.
;D9 EA        FLDL2E              Push log2e onto the FPU register stack.
;D9 EB        FLDPI               Push p onto the FPU register stack.
;D9 EC        FLDLG2              Push log102 onto the FPU register stack.
;D9 ED        FLDLN2              Push loge2 onto the FPU register stack.
;D9 EE        FLDZ                Push +0.0 onto the FPU register stack.
;D9 /5        FLDCW m2byte        Load FPU control word from m2byte.
;D9 /4        FLDENV m14/28byte   Load FPU environment from m14byte or m28byte.
;D8 /1        FMUL m32fp          Multiply ST(0) by m32fp and store result in ST(0).
;DC /1        FMUL m64fp          Multiply ST(0) by m64fp and store result in ST(0).
;D8 C8+i      FMUL ST(0), ST(i)   Multiply ST(0) by ST(i) and store result in ST(0).
;DC C8+i      FMUL ST(i), ST(0)   Multiply ST(i) by ST(0) and store result in ST(i).
;DE C8+i      FMULP ST(i), ST(0)  Multiply ST(i) by ST(0), store result in ST(i), and pop
;                                 the register stack.
;DE C9        FMULP               Multiply ST(1) by ST(0), store result in ST(1), and pop
;                                 the register stack.
;DA /1        FIMUL m32int        Multiply ST(0) by m32int and store result in ST(0).
;DE /1        FIMUL m16int        Multiply ST(0) by m16int and store result in ST(0).
;D9 D0        FNOP                No operation is performed.
;D9 F3        FPATAN              Replace ST(1) with arctan(ST(1)/ST(0)) and pop the register
;                                 stack.
;D9 F8        FPREM               Replace ST(0) with the remainder obtained from dividing ST(0)
;                                 by ST(1).
;D9 F5        FPREM1              Replace ST(0) with the IEEE remainder obtained from dividing
;                                 ST(0) by ST(1).
;D9 F2        FPTAN               Replace ST(0) with its tangent and push 1 onto the FPU stack.
;D9 FC        FRNDINT             Round ST(0) to an integer.
;DD /4        FRSTOR m94/108byte  Load FPU state from m94byte or m108byte.
;9B DD /6     FSAVE m94/108byte   Store FPU state to m94byte or m108byte after checking for
;                                 pending unmasked floatingpoint exceptions. Then reinitialize
;                                 the FPU.
;DD /6        FNSAVE m94/108byte  Store FPU environment to m94byte or m108byte without checking
;                                 for pending unmasked floating-point exceptions. Then
;                                 re-initialize the FPU.
;D9 FD        FSCALE              Scale ST(0) by ST(1).
;D9 FE        FSIN                Replace ST(0) with its sine.
;D9 FB        FSINCOS             Compute the sine and cosine of ST(0); replace ST(0) with the
;                                 sine, and push the cosine onto the register stack.
;D9 FA        FSQRT               Computes square root of ST(0) and stores the result in ST(0).
;D9 /2        FST m32fp           Copy ST(0) to m32fp.
;DD /2        FST m64fp           Copy ST(0) to m64fp.
;DD D0+i      FST ST(i)           Copy ST(0) to ST(i).
;D9 /3        FSTP m32fp          Copy ST(0) to m32fp and pop register stack.
;DD /3        FSTP m64fp          Copy ST(0) to m64fp and pop register stack.
;DB /7        FSTP m80fp          Copy ST(0) to m80fp and pop register stack.
;DD D8+i      FSTP ST(i)          Copy ST(0) to ST(i) and pop register stack.
;9B D9 /7     FSTCW m2byte        Store FPU control word to m2byte after checking for pending
;                                 unmasked floating-point exceptions.
;D9 /7        FNSTCW m2byte       Store FPU control word to m2byte without checking for pending
;                                 unmasked floating-point exceptions.
;9B D9 /6     FSTENV m14/28byte   Store FPU environment to m14byte or m28byte after checking for
;                                 pending unmasked floating-point exceptions. Then mask all
;                                 floating-point exceptions.
;D9 /6        FNSTENV m14/28byte  Store FPU environment to m14byte or m28byte without checking
;                                 for pending unmasked floating-point exceptions. Then mask all
;                                 floating-point exceptions.
;9B DD /7     FSTSW m2byte        Store FPU status word at m2byte after checking for pending
;                                 unmasked floatingpoint exceptions.
;9B DF E0     FSTSW AX            Store FPU status word in AX register after checking for pending
;                                 unmasked floatingpoint exceptions.
;DD /7        FNSTSW m2byte       Store FPU status word at m2byte without checking for pending
;                                 unmasked floatingpoint exceptions.
;DF E0        FNSTSW AX           Store FPU status word in AX register without checking for
;                                 pending unmasked floatingpoint exceptions.
;D8 /4        FSUB m32fp          Subtract m32fp from ST(0) and store result in ST(0).
;DC /4        FSUB m64fp          Subtract m64fp from ST(0) and store result in ST(0).
;D8 E0+i      FSUB ST(0), ST(i)   Subtract ST(i) from ST(0) and store result in ST(0).
;DC E8+i      FSUB ST(i), ST(0)   Subtract ST(0) from ST(i) and store result in ST(i).
;DE E8+i      FSUBP ST(i), ST(0)  Subtract ST(0) from ST(i), store result in ST(i), and pop
;                                 register stack.
;DE E9        FSUBP               Subtract ST(0) from ST(1), store result in ST(1), and pop
;                                 register stack.
;DA /4        FISUB m32int        Subtract m32int from ST(0) and store result in ST(0).
;DE /4        FISUB m16int        Subtract m16int from ST(0) and store result in ST(0).
;D8 /5        FSUBR m32fp         Subtract ST(0) from m32fp and store result in ST(0).
;DC /5        FSUBR m64fp         Subtract ST(0) from m64fp and store result in ST(0).
;D8 E8+i      FSUBR ST(0), ST(i)  Subtract ST(0) from ST(i) and store result in ST(0).
;DC E0+i      FSUBR ST(i), ST(0)  Subtract ST(i) from ST(0) and store result in ST(i).
;DE E0+i      FSUBRP ST(i), ST(0) Subtract ST(i) from ST(0), store result in ST(i), and pop
;                                 register stack.
;DE E1        FSUBRP              Subtract ST(1) from ST(0), store result in ST(1), and pop
;                                 register stack.
;DA /5        FISUBR m32int       Subtract ST(0) from m32int and store result in ST(0).
;DE /5        FISUBR m16int       Subtract ST(0) from m16int and store result in ST(0).
;D9 E4        FTST                Compare ST(0) with 0.0.
;DD E0+i      FUCOM ST(i)         Compare ST(0) with ST(i).
;DD E1        FUCOM               Compare ST(0) with ST(1).
;DD E8+i      FUCOMP ST(i)        Compare ST(0) with ST(i) and pop register stack.
;DD E9        FUCOMP              Compare ST(0) with ST(1) and pop register stack.
;DA E9        FUCOMPP             Compare ST(0) with ST(1) and pop register stack twice.
;D9 E5        FXAM                Classify value or number in ST(0).
;D9 C8+i      FXCH ST(i)          Exchange the contents of ST(0) and ST(i).
;D9 C9        FXCH                Exchange the contents of ST(0) and ST(1).
;0F AE /1     FXRSTOR m512byte    Restore the x87 FPU, MMX, XMM and MXCSR register state from
;                                 m512byte.
;0F AE /0     FXSAVE m512byte     Save the x87 FPU, MMX, XMM and MXCSR register state to m512byte.
;D9 F4        FXTRACT             Separate value in ST(0) into exponent and significand, store
;                                 exponent in ST(0) and push the significand onto the register
;                                 stack.
;D9 F1        FYL2X               Replace ST(1) with (ST(1) * log2ST(0)) and pop the register
;                                 stack.
;D9 F9        FYL2XP1             Replace ST(1) with ST(1) * log2(ST(0) + 1.0) and pop the
;                                 register stack.

;---------------------------------------------------------------------------------------------------
;OPCODES High-Byte aufsteigend:
;0F AE /1     FXRSTOR m512byte    Restore the x87 FPU, MMX, XMM and MXCSR register state from
;                                 m512byte.
;0F AE /0     FXSAVE m512byte     Save the x87 FPU, MMX, XMM and MXCSR register state to m512byte.

;-------------
;9B D9 /6     FSTENV m14/28byte   Store FPU environment to m14byte or m28byte after checking for
;                                 pending unmasked floating-point exceptions. Then mask all
;                                 floating-point exceptions.
;9B D9 /7     FSTCW m2byte        Store FPU control word to m2byte after checking for pending
;                                 unmasked floating-point exceptions.
;9B DB E2     FCLEX               Clear floating-point exception flags after checking for pending
;                                 unmasked floating-point exceptions.
;9B DB E3     FINIT               Initialize FPU after checking for pending unmasked
;                                 floating-point exceptions.
;9B DD /6     FSAVE m94/108byte   Store FPU state to m94byte or m108byte after checking for
;                                 pending unmasked floatingpoint exceptions. Then reinitialize
;                                 the FPU.
;9B DD /7     FSTSW m2byte        Store FPU status word at m2byte after checking for pending
;                                 unmasked floatingpoint exceptions.
;9B DF E0     FSTSW AX            Store FPU status word in AX register after checking for pending
;                                 unmasked floatingpoint exceptions.

;-------------
;D8 /0        FADD m32fp          Add m32fp To ST(0) and store result in ST(0).
;D8 /1        FMUL m32fp          Multiply ST(0) by m32fp and store result in ST(0).
;D8 /2        FCOM m32fp          Compare ST(0) with m32fp.
;D8 /3        FCOMP m32fp         Compare ST(0) with m32fp and pop register stack.
;D8 /4        FSUB m32fp          Subtract m32fp from ST(0) and store result in ST(0).
;D8 /5        FSUBR m32fp         Subtract ST(0) from m32fp and store result in ST(0).
;D8 /6        FDIV m32fp          Divide ST(0) by m32fp and store result in ST(0).
;D8 /7        FDIVR m32fp         Divide m32fp by ST(0) and store result in ST(0).
;D8 C0+i      FADD ST(0), ST(i)   Add ST(0) To ST(i) and store result in ST(0).
;D8 C8+i      FMUL ST(0), ST(i)   Multiply ST(0) by ST(i) and store result in ST(0).
;D8 D0+i      FCOM ST(i)          Compare ST(0) with ST(i).
;D8 D1        FCOM                Compare ST(0) With ST(1).
;D8 D8+i      FCOMP ST(i)         Compare ST(0) with ST(i) and pop register stack.
;D8 D9        FCOMP               Compare ST(0) with ST(1) and pop register stack.
;D8 E0+i      FSUB ST(0), ST(i)   Subtract ST(i) from ST(0) and store result in ST(0).
;D8 E8+i      FSUBR ST(0), ST(i)  Subtract ST(0) from ST(i) and store result in ST(0).
;D8 F0+i      FDIV ST(0), ST(i)   Divide ST(0) by ST(i) and store result in ST(0).
;D8 F8+i      FDIVR ST(0), ST(i)  Divide ST(i) by ST(0) and store result in ST(0).

;-------------
;D9 /0        FLD m32fp           Push m32fp onto the FPU register stack.
;D9 /2        FST m32fp           Copy ST(0) to m32fp.
;D9 /3        FSTP m32fp          Copy ST(0) to m32fp and pop register stack.
;D9 /4        FLDENV m14/28byte   Load FPU environment from m14byte or m28byte.
;D9 /5        FLDCW m2byte        Load FPU control word from m2byte.
;D9 /6        FNSTENV m14/28byte  Store FPU environment to m14byte or m28byte without checking
;                                 for pending unmasked floating-point exceptions. Then mask all
;                                 floating-point exceptions.
;D9 /7        FNSTCW m2byte       Store FPU control word to m2byte without checking for pending
;                                 unmasked floating-point exceptions.
;D9 C0+i      FLD ST(i)           Push ST(i) onto the FPU register stack.
;D9 C8+i      FXCH ST(i)          Exchange the contents of ST(0) and ST(i).
;D9 C9        FXCH                Exchange the contents of ST(0) and ST(1).
;D9 D0        FNOP                No operation is performed.
;D9 E0        FCHS                Complements sign of ST(0).
;D9 E1        FABS                Replace ST with its absolute value.
;D9 E4        FTST                Compare ST(0) with 0.0.
;D9 E5        FXAM                Classify value or number in ST(0).
;D9 E8        FLD1                Push +1.0 onto the FPU register stack.
;D9 E9        FLDL2T              Push log210 onto the FPU register stack.
;D9 EA        FLDL2E              Push log2e onto the FPU register stack.
;D9 EB        FLDPI               Push p onto the FPU register stack.
;D9 EC        FLDLG2              Push log102 onto the FPU register stack.
;D9 ED        FLDLN2              Push loge2 onto the FPU register stack.
;D9 EE        FLDZ                Push +0.0 onto the FPU register stack.
;D9 F0        F2XM1               Replace ST(0) with (2^ST(0))-1.
;D9 F1        FYL2X               Replace ST(1) with (ST(1) * log2ST(0)) and pop the register
;                                 stack.
;D9 F2        FPTAN               Replace ST(0) with its tangent and push 1 onto the FPU stack.
;D9 F3        FPATAN              Replace ST(1) with arctan(ST(1)/ST(0)) and pop the register
;                                 stack.
;D9 F4        FXTRACT             Separate value in ST(0) into exponent and significand, store
;                                 exponent in ST(0) and push the significand onto the register
;                                 stack.
;D9 F5        FPREM1              Replace ST(0) with the IEEE remainder obtained from dividing
;                                 ST(0) by ST(1).
;D9 F6        FDECSTP             Decrement TOP field in FPU status word.
;D9 F7        FINCSTP             Increment the TOP field in the FPU status register.
;D9 F8        FPREM               Replace ST(0) with the remainder obtained from dividing ST(0)
;                                 by ST(1).
;D9 F9        FYL2XP1             Replace ST(1) with ST(1) * log2(ST(0) + 1.0) and pop the
;                                 register stack.
;D9 FA        FSQRT               Computes square root of ST(0) and stores the result in ST(0).
;D9 FB        FSINCOS             Compute the sine and cosine of ST(0); replace ST(0) with the
;                                 sine, and push the cosine onto the register stack.
;D9 FC        FRNDINT             Round ST(0) to an integer.
;D9 FD        FSCALE              Scale ST(0) by ST(1).
;D9 FE        FSIN                Replace ST(0) with its sine.
;D9 FF        FCOS                Replace ST(0) with its cosine.

;-------------
;DA /0        FIADD m32int        Add m32int To ST(0) and store result in ST(0).
;DA /1        FIMUL m32int        Multiply ST(0) by m32int and store result in ST(0).
;DA /2        FICOM m32int        Compare ST(0) with m32int.
;DA /3        FICOMP m32int       Compare ST(0) with m32int and pop stack register.
;DA /4        FISUB m32int        Subtract m32int from ST(0) and store result in ST(0).
;DA /5        FISUBR m32int       Subtract ST(0) from m32int and store result in ST(0).
;DA /6        FIDIV m32int        Divide ST(0) by m32int and store result in ST(0).
;DA /7        FIDIVR m32int       Divide m32int by ST(0) and store result in ST(0).
;DA C0+i      FCMOVB ST(0), ST(i) Move if below (CF=1).
;DA C8+i      FCMOVE ST(0), ST(i) Move if equal (ZF=1).
;DA D0+i      FCMOVBE ST(0), ST(i) Move if below or equal (CF=1 or ZF=1).
;DA D8+i      FCMOVU ST(0), ST(i) Move if unordered (PF=1).
;DA E9        FUCOMPP             Compare ST(0) with ST(1) and pop register stack twice.

;-------------
;DB /0        FILD m32int         Push m32int onto the FPU register stack.
;DB /1        FISTTP m32int       Store ST(0) in m32int with truncation.
;DB /2        FIST m32int         Store ST(0) in m32int.
;DB /3        FISTP m32int        Store ST(0) in m32int and pop register stack.
;DB /5        FLD m80fp           Push m80fp onto the FPU register stack.
;DB /7        FSTP m80fp          Copy ST(0) to m80fp and pop register stack.
;DB C0+i      FCMOVNB ST(0), ST(i) Move if not below (CF=0).
;DB C8+i      FCMOVNE ST(0), ST(i) Move if not equal (ZF=0).
;DB D0+i      FCMOVNBE ST(0), ST(i) Move if not below or equal (CF=0 and ZF=0).
;DB D8+i      FCMOVNU ST(0), ST(i) Move if not unordered (PF=0).
;DB E2        FNCLEX              Clear floating-point exception flags without checking for
;                                 pending unmasked floating-point exceptions.
;DB E3        FNINIT              Initialize FPU without checking for pending unmasked
;                                 floating-point exceptions.
;DB E8+i      FUCOMI ST, ST(i)    Compare ST(0) with ST(i), check for ordered values, and set
;                                 status flags accordingly.

;DB F0+i      FCOMI ST, ST(i)     Compare ST(0) with ST(i) and set status flags accordingly.

;-------------
;DC /0        FADD m64fp          Add m64fp To ST(0) and store result in ST(0).
;DC /1        FMUL m64fp          Multiply ST(0) by m64fp and store result in ST(0).
;DC /2        FCOM m64fp          Compare ST(0) with m64fp.
;DC /3        FCOMP m64fp         Compare ST(0) with m64fp and pop register stack.
;DC /4        FSUB m64fp          Subtract m64fp from ST(0) and store result in ST(0).
;DC /5        FSUBR m64fp         Subtract ST(0) from m64fp and store result in ST(0).
;DC /6        FDIV m64fp          Divide ST(0) by m64fp and store result in ST(0).
;DC /7        FDIVR m64fp         Divide m64fp by ST(0) and store result in ST(0).
;DC C0+i      FADD ST(i), ST(0)   Add ST(i) To ST(0) and store result in ST(i).
;DC C8+i      FMUL ST(i), ST(0)   Multiply ST(i) by ST(0) and store result in ST(i).
;DC E0+i      FSUBR ST(i), ST(0)  Subtract ST(i) from ST(0) and store result in ST(i).
;DC E8+i      FSUB ST(i), ST(0)   Subtract ST(0) from ST(i) and store result in ST(i).
;DC F0+i      FDIVR ST(i), ST(0)  Divide ST(0) by ST(i) and store result in ST(i).
;DC F8+i      FDIV ST(i), ST(0)   Divide ST(i) by ST(0) and store result in ST(i).

;-------------
;DD /0        FLD m64fp           Push m64fp onto the FPU register stack.
;DD /1        FISTTP m64int       Store ST(0) in m64int with truncation.
;DD /2        FST m64fp           Copy ST(0) to m64fp.
;DD /3        FSTP m64fp          Copy ST(0) to m64fp and pop register stack.
;DD /4        FRSTOR m94/108byte  Load FPU state from m94byte or m108byte.
;DD /6        FNSAVE m94/108byte  Store FPU environment to m94byte or m108byte without checking
;                                 for pending unmasked floating-point exceptions. Then
;                                 re-initialize the FPU.
;DD /7        FNSTSW m2byte       Store FPU status word at m2byte without checking for pending
;                                 unmasked floatingpoint exceptions.
;DD C0+i      FFREE ST(i)         Sets tag for ST(i) to empty.
;DD D0+i      FST ST(i)           Copy ST(0) to ST(i).
;DD D8+i      FSTP ST(i)          Copy ST(0) to ST(i) and pop register stack.
;DD E0+i      FUCOM ST(i)         Compare ST(0) with ST(i).
;DD E1        FUCOM               Compare ST(0) with ST(1).
;DD E8+i      FUCOMP ST(i)        Compare ST(0) with ST(i) and pop register stack.
;DD E9        FUCOMP              Compare ST(0) with ST(1) and pop register stack.

;-------------
;DE /0        FIADD m16int        Add m16int To ST(0) and store result in ST(0).
;DE /1        FIMUL m16int        Multiply ST(0) by m16int and store result in ST(0).
;DE /2        FICOM m16int        Compare ST(0) with m16int.
;DE /3        FICOMP m16int       Compare ST(0) with m16int and pop stack register.
;DE /4        FISUB m16int        Subtract m16int from ST(0) and store result in ST(0).
;DE /5        FISUBR m16int       Subtract ST(0) from m16int and store result in ST(0).
;DE /6        FIDIV m16int        Divide ST(0) by m64int and store result in ST(0).
;DE /7        FIDIVR m16int       Divide m16int by ST(0) and store result in ST(0).
;DE C0+i      FADDP ST(i), ST(0)  Add ST(0) To ST(i), store result in ST(i), and pop the register stack.
;DE C1        FADDP               Add ST(0) To ST(1), store result in ST(1), and pop the register stack.
;DE C8+i      FMULP ST(i), ST(0)  Multiply ST(i) by ST(0), store result in ST(i), and pop
;                                 the register stack.
;DE C9        FMULP               Multiply ST(1) by ST(0), store result in ST(1), and pop
;                                 the register stack.
;DE D9        FCOMPP              Compare ST(0) with ST(1) and pop register stack twice.
;DE E0+i      FSUBRP ST(i), ST(0) Subtract ST(i) from ST(0), store result in ST(i), and pop
;                                 register stack.
;DE E1        FSUBRP              Subtract ST(1) from ST(0), store result in ST(1), and pop
;                                 register stack.
;DE E8+i      FSUBP ST(i), ST(0)  Subtract ST(0) from ST(i), store result in ST(i), and pop
;                                 register stack.
;DE E9        FSUBP               Subtract ST(0) from ST(1), store result in ST(1), and pop
;                                 register stack.
;DE F0+i      FDIVRP ST(i), ST(0) Divide ST(0) by ST(i), store result in ST(i), and pop the
;                                 register stack.
;DE F1        FDIVRP              Divide ST(0) by ST(1), store result in ST(1), and pop the
;                                 register stack.
;DE F8+i      FDIVP ST(i), ST(0)  Divide ST(i) by ST(0), store result in ST(i), and pop the
;                                 register stack.
;DE F9        FDIVP               Divide ST(1) by ST(0), store result in ST(1), and pop the
;                                 register stack.

;-------------
;DF /0        FILD m16int         Push m16int onto the FPU register stack.
;DF /1        FISTTP m16int       Store ST(0) in m16int with truncation.
;DF /2        FIST m16int         Store ST(0) in m16int.
;DF /3        FISTP m16int        Store ST(0) in m16int and pop register stack.
;DF /4        FBLD m80 dec        Convert BCD value to floating-point and push onto the FPU stack.
;DF /5        FILD m64int         Push m64int onto the FPU register stack.
;DF /6        FBSTP m80bcd        Store ST(0) in m80bcd and pop ST(0).
;DF /7        FISTP m64int        Store ST(0) in m64int and pop register stack.
;DF E0        FNSTSW AX           Store FPU status word in AX register without checking for
;                                 pending unmasked floatingpoint exceptions.
;DF E8+i      FUCOMIP ST, ST(i)   Compare ST(0) with ST(i), check for ordered values, set status
;                                 flags accordingly, and pop register stack.
;DF F0+i      FCOMIP ST, ST(i)    Compare ST(0) with ST(i), set status flags accordingly, and
;                                 pop register stack.
;-------------

Procedure FPU()
Global FST0.d
Global FST1.d
Global FST2.d
Global FST3.d
Global FST4.d
Global FST5.d
Global FST6.d
Global FST7.d
Global SaveRam.l
Global FPUSW.w
Global FPUCW.w
Global OpcodeH.c
Global OpcodeL.c
Global C1.b 
Global PhysReg.b
Global Tag.b
Global Zeiger.b

Global Alarm$="Schwerwiegender Fehler ! Weitermachen ist Muster ohne Wert !"
Global Reg$
Global B1$
Global B$
Global C01$
Global C0$
Global C11$
Global C1$
Global C21$
Global C2$
Global C31$
Global C3$
Global CX$="Das Condition-Code-Flag "
Global Tag0$
Global Tag1$
Global Tag2$
Global Tag3$
Global Tag4$
Global Tag5$
Global Tag6$
Global Tag7$
Global I$
Global D$
Global Z$
Global O$
Global U$
Global P$
Global P1$
Global S$
Global S1$
Global Prec$
Global Round$
Global Inf$
Global TOS$
Global OP$
Global OF$="Overflow !"
Global UF$="Underflow !"
Global OP1$="Letzter FPU-Befehl : "    ;nicht möglich für FSTENV, FNSTENV, FLDENV, FINIT, FNINIT,
Global OPH$                            ; FSAVE, FNSAVE, FXSAVE, FRSTOR, FXRSTOR, FCLEX, FNCLEX, 
Global OPL$                            ; FLDCW, FSTCW, FNSTCW, FSTSW, FNSTSW
Global D8$= "FADD    FMUL    FCOM    FCOMP   FSUB    FSUBR   FDIV    FDIVR   "
Global D9$= "FLD     FXCH    FST     FSTP    "                                                          
Global D91$="FCHS    FABS                    FTST    FXAM                    FLD1    FLDL2T  FLDL2E  FLDPI   FLDLG2  FLDLN2  FLDZ    "
Global D92$="F2XM1   FYL2X   FPTAN   FPATAN  FXTRACT FPREM1  FDECSTP FINCSTP FPREM   FYL2XP1 FSQRT   FSINCOS FRNDINT FSCALE  FSIN    FCOS    "
Global DA$= "FIADD   FIMUL   FICOM   FICOMP  FISUB   FISUBR  FIDIV   FIDIVR  "
Global DA1$="FCMOVB  FCMOVE  FCMOVBE FCMOVU          FUCOMPP "
Global DB$= "FILD    FISTTP  FIST    FISTP           FLD             FSTP    " 
Global DB1$="FCMOVNB FCMOVNE FCMOVNBEFCMOVNU         FUCOMI  FCOMI   " 
Global DC$= "FADD    FMUL                    FSUBR   FSUB    FDIVR   FDIV    "
Global DD$= "FLD     FISTTP  FST     FSTP    "
Global DD1$="FFREE           FST     FSTP    FUCOM   FUCOMP  "
Global DE$= "FIADD   FIMUL   FICOM   FICOMP  FISUB   FISUBR  FIDIV   FIDIVR  " 
Global DE1$="FADDP   FMULP           FCOMPP  FSUBRP  FSUBP   FDIVRP  FDIVP   "
Global DF$= "FILD    FISTTP  FIST    FISTP   FBLD    FILD    FBSTP   FISTP   "
Global DF1$="                                        FUCOMIP FCOMIP  "
Global DX$
Global DX1$

!pushad                 ;Prozessor-Register sichern
!pushfd                 ;EFlag-Register sichern; FCOMI(P)!

!fnstcw [v_FPUCW]       ;Control-Word laden 
!fnstsw [v_FPUSW]       ;Status-Word laden

SaveRam = AllocateMemory(540)     ;512 Byte für FXSAVE und 28 Byte für FNSTENV
!mov esi,[v_SaveRam]

!fnstenv [esi+512]      ;nur wegen Opcode (AMD!)
!fxsave [esi]
!fwait

Tag0$="   Frei"
Tag1$="   Frei"
Tag2$="   Frei"
Tag3$="   Frei"
Tag4$="   Frei"
Tag5$="   Frei"
Tag6$="   Frei"
Tag7$="   Frei"
!mov al,[esi+4]         ;Tag
!mov [v_Tag],al
!test [v_Tag],1
!jz @f
Tag7$="   Belegt"
!@@:
!test [v_Tag],2
!jz @f
Tag6$="   Belegt"
!@@:
!test [v_Tag],4
!jz @f
Tag5$="   Belegt"
!@@:
!test [v_Tag],8
!jz @f
Tag4$="   Belegt"
!@@:
!test [v_Tag],10h
!jz @f
Tag3$="   Belegt"
!@@:
!test [v_Tag],20h
!jz @f
Tag2$="   Belegt"
!@@:
!test [v_Tag],40h
!jz @f
Tag1$="   Belegt"
!@@:
!test [v_Tag],80h
!jz @f
Tag0$="   Belegt"
!@@:

!mov ax,[esi+530]
!or ah,0d8h
!mov [v_OpcodeH],ah
!mov [v_OpcodeL],al
!fld tword[esi+32]
!fstp qword[v_FST0] 
!fld tword[esi+48]
!fstp qword[v_FST1]
!fld tword[esi+64]
!fstp qword[v_FST2] 
!fld tword[esi+80]
!fstp qword[v_FST3]
!fld tword[esi+96]
!fstp qword[v_FST4] 
!fld tword[esi+112]
!fstp qword[v_FST5]
!fld tword[esi+128]
!fstp qword[v_FST6] 
!fld tword[esi+144]
!fstp qword[v_FST7]

!cmp ah,0d8h
!je l_d8
!cmp ah,0d9h
!je l_d9
!cmp ah,0dah
!je l_da
!cmp ah,0dbh
!je l_db
!cmp ah,0dch
!je l_dc
!cmp ah,0ddh
!je l_dd
!cmp ah,0deh
!je l_de

;----------------------------
!push eax
DX$=DF$
DX1$=DF1$
!pop eax
!jmp l_dx
;----------------------------
D8:
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(D8$,Zeiger,8)+#LFCR$
!jmp l_ope
;----------------------------
D9:
!cmp al,0d0h
!jae @f
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(D9$,Zeiger,8)+#LFCR$
!jmp l_ope
!@@:
!ja @f
OP$="FNOP"+#LFCR$
!jmp l_ope
!@@:
!cmp al,0f0h
!jae @f
!and al,00001111b
!shl al,3
!mov [v_Zeiger],al
OP$=Mid(D91$,Zeiger,8)+#LFCR$
!jmp l_ope
!@@:
!and al,00001111b
!shl al,3
!mov [v_Zeiger],al
OP$=Mid(D92$,Zeiger,8)+#LFCR$
!jmp l_ope
;----------------------------
DA:
!push eax
DX$=DA$
DX1$=DA1$
!pop eax
!jmp l_dx
;----------------------------
DB:
!cmp al,0c0h
!jae @f
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(DB$,Zeiger,8)+#LFCR$
!jmp l_ope
!@@:
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(DB1$,Zeiger,8)+#LFCR$
!jmp l_ope
;----------------------------
DC:
!cmp al,0c0h
!jb l_d8
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(DC$,Zeiger,8)+#LFCR$
!jmp l_ope
;----------------------------
DD:
!push eax
DX$=DD$
DX1$=DD1$
!pop eax
!jmp l_dx
;----------------------------
DE:
!push eax
DX$=DE$
DX1$=DE1$
!pop eax
;----------------------------
DX:
!cmp al,0c0h
!jae @f
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(DX$,Zeiger,8)+#LFCR$
!jmp l_ope
!@@:
!and al,00111000b
!mov [v_Zeiger],al
OP$=Mid(DX1$,Zeiger,8)+#LFCR$
;----------------------------

OPE:
OPH$="Letzter FPU-Befehl High-Byte : "+RSet(Bin(OpcodeH),8,"0")+" = "+RSet(Hex(OpcodeH),2,"0")+"h"+#LFCR$
OPL$="Letzter FPU-Befehl Low-Byte :  "+RSet(Bin(OpcodeL),8,"0")+" = "+RSet(Hex(OpcodeL),2,"0")+"h"+#LFCR$+#LFCR$

Reg$="ST0 = "+StrD(FST0)+Tag0$+#LFCR$
Reg$+"ST1 = "+StrD(FST1)+Tag1$+#LFCR$
Reg$+"ST2 = "+StrD(FST2)+Tag2$+#LFCR$
Reg$+"ST3 = "+StrD(FST3)+Tag3$+#LFCR$
Reg$+"ST4 = "+StrD(FST4)+Tag4$+#LFCR$
Reg$+"ST5 = "+StrD(FST5)+Tag5$+#LFCR$
Reg$+"ST6 = "+StrD(FST6)+Tag6$+#LFCR$
Reg$+"ST7 = "+StrD(FST7)+Tag7$

!mov [v_C1],0
!test [v_FPUSW],200h
!jz @f 
!mov [v_C1],1           ;z.B. für Stack-Fault
!@@:
I$=""
!test [v_FPUSW],1
!jz @f
I$="Invalid Operation !"+#LFCR$+Alarm$+#LFCR$
!@@:
D$=""
!test [v_FPUSW],2
!jz @f
D$="Denormalized Operand !"+#LFCR$+Alarm$+#LFCR$
!@@:
Z$=""
!test [v_FPUSW],4
!jz @f
Z$="Division by Zero !"+#LFCR$+Alarm$+#LFCR$
!@@:
O$=""
!test [v_FPUSW],8
!jz @f
O$=OF$+#LFCR$
!@@:
U$=""
!test [v_FPUSW],10h
!jz @f
U$=UF$+#LFCR$
!@@:
P$=""
P1$=""
!test [v_FPUSW],20h
!jz @f
P1$="kleineren Wert !"+#LFCR$
P$="Low Precision ! Rundung erfolgte zum "
!cmp [v_C1],0
!jz @f
P1$="grösseren Wert !"+#LFCR$
!@@:
P$+P1$

S$=""
S1$=""
!test [v_FPUSW],40h
!jz @f
S1$=UF$+#LFCR$+Alarm$+#LFCR$
S$="Stack Fault : "
!cmp [v_C1],0
!je @f
S1$=OF$+#LFCR$+Alarm$+#LFCR$
!@@:
S$+S1$

B1$="nicht"
!mov ax,[v_FPUSW]
!sahf
!jns @f 
B1$=""
!@@:
B$="Das Busy-Flag ist "+B1$+" gesetzt !"+#LFCR$

C11$="nicht"
!cmp byte[v_C1],0
!je @f 
C11$=""
!@@:
C1$=CX$+"C1 ist "+C11$+" gesetzt !"+#LFCR$

C01$="nicht"
C21$="nicht"
C31$="nicht"
!mov ax,[v_FPUSW]   
!sahf   
!jnc @f
!pushfd
C01$=""
!popfd
!@@:
!jnp @f
!pushfd
C21$=""
!popfd
!@@:
!jnz @f
!pushfd
C31$=""
!popfd
!@@:
C0$=CX$+"C0 ist "+C01$+" gesetzt !"+#LFCR$
C2$=CX$+"C2 ist "+C21$+" gesetzt !"+#LFCR$
C3$=CX$+"C3 ist "+C31$+" gesetzt !"+#LFCR$+#LFCR$

!mov ax,[v_FPUSW]
!and ah,38h
!shr ah,3               ;in Bit 0-2 schieben
!mov [v_PhysReg],ah
TOS$="Das physische Register " + Str(PhysReg) + " ist Top of Stack !"+#LFCR$

Prec$=#LFCR$+"Die eingestellte Genauigkeit ist "
!mov ax,[v_FPUCW]
!and ah,3
!jz l_single
!cmp ah,2
!je l_double
Prec$+"Double Extended Precision 64 Bits"
!jmp l_precend
Single:
Prec$+"Single Precision 24 Bits"
!jmp l_precend
Double:
Prec$+"Double Precision 53 Bits"
PrecEnd:
Prec$+#LFCR$

Round$="Rundung erfolgt "
!mov ax,[v_FPUCW]
!and ah,0ch
!cmp ah,4
!je l_round1
!cmp ah,8
!je l_round2
!cmp ah,0ch
!je l_round3
Round$+"zum nächsten oder geraden Wert"
!jmp l_roundend
Round1:
Round$+"in Richtung minus Unendlich"
!jmp l_roundend
Round2:
Round$+"in Richtung plus Unendlich"
!jmp l_roundend
Round3:
Round$+"keine, Nachkommastellen werden abgeschnitten"
RoundEnd:
Round$+#LFCR$

Inf$="Infinity ist "
!mov ax,[v_FPUCW]
!test ah,10h
!jnz @f
Inf$+"projektiv"
!jmp l_infend
!@@:
Inf$+"affinitiv"
InfEnd:
Inf$+#LFCR$+#LFCR$

MessageRequester("FPU-Innenleben",I$+D$+Z$+O$+U$+P$+S$+Prec$+Round$+Inf$+OP1$+OP$+OPH$+OPL$+B$+C0$+C1$+C2$+C3$+TOS$+#LFCR$+Reg$)

!mov esi,[v_SaveRam]
!fxrstor [esi] 

FreeMemory(SaveRam)

!popfd
!popad
EndProcedure

;- Beispiel: Berechnung Kugelvolumen: V=4/3*Pi*Radius^3 
Global R.d=123.456
Global Z.d=4
Global N.d=3
Global V.d

;!fninit
FPU()
!fldpi                  ;ST0   Pi
FPU()
!fmul qword[v_Z]        ;ST0   Pi*4
FPU()
!fdiv qword[v_N]        ;ST0   Pi*4/3
FPU()
!fld qword[v_R]         ;ST0   ST1=Pi*4/3
FPU()
!fmul st0,st0           ;ST0=R*R
FPU()
!fmul qword[v_R]        ;ST0=R*R*R
FPU()
!fmulp                  ;ST0=ST0*ST1
FPU()
!fstp qword[v_V]        ;ST0 in V kopieren
FPU()

MessageRequester("Kugelvolumen-Berechnung mit FPU()",StrD(V))

;Aus Jux mal sehen, wie PB die FPU verlässt:
V=4/3*#PI*R*R*R
FPU()

V=4/3*#PI*Pow(R,3)
FPU()

End 
Gruß
Helle

Edit: Korrektur+Erweiterung 11.08.2007
Edit: Kosmetik+Erweiterung 12.08.2007