2016-12-24 6 views
-2

Wie in masm zwei Schwimmer Variablen multiplizieren, tritt Montage Benutzer eine Eingabe als 3,02 und mit 0,008 multiplizieren und dann drucken Sie esWie multiplizieren zwei float Variablen in masm

.data 
fin dd 5.0 

.code 
main proc 

fld fin 
fmul fin ;to multiply fin with fin 
fstp dword [eax] ;cannot mov result in eax 
call writefloat 

exit 
main EndP 
end main 
+0

Dieser Code lädt 'fin' und multipliziert ihn mit' fin'. Das ist das gleiche wie fin^2 (quadriert). Ihre 'fmul' sollte als ihren Operanden den Wert nehmen, den Sie mit' fin' * multiplizieren * wollen. Aber der Code stimmt nicht mit der Frage überein, da "fin" eine Konstante von 5.0 ist, während man davon ausgeht, dass man 3.02 x 0.008 multipliziert. –

Antwort

0

Wenn Sie die FPU verwenden möchten Beachten Sie, dass es einen gestapelten Satz von Registern verwendet, die nur aus dem Speicher geladen oder im Speicher gespeichert werden können.
Ich nehme an, dass Sie über das FPU-Programmiermodell selbst dokumentieren können, indem Sie entweder die Intel manual 1 oder, wenn Sie sich nostalgisch fühlen, von reading this 387 manual from Intel dated 05/26/1987.

Die Anweisung fstp dword [eax] speichern den Inhalt von st(0) bei bezeichnet die Adresse von eax. Diese Art von Adressierungsmodus ist ein indirekter Adressierungsmodus und wird durch die Verwendung von eckigen Klammern in der Intel-Assembly-Syntax konsequent markiert.
Vergleichen Sie dies mit Speichern st(0) in eax, die wie fstp eax (keine Klammern) aussehen sollte.
Leider wird Letzteres nicht unterstützt, wahrscheinlich weil die FPU 64-Bit- und 80-Bit-Formate unterstützt, die zu diesem Zeitpunkt nicht in ein Register passen.


Um Daten zu pushen. aus dem Speicher in den FPU-Stack fld verwenden, um die Register in den Speicher zu laden, verwenden Sie fstp (oder , wenn Sie den Stack nicht öffnen möchten).
Um eine Multiplikation durchzuführen fmul, kommt es in einigen Varianten, von denen einer mit einem Speicheroperanden arbeiten und das Ergebnis direkt in st(0) speichern kann.

Wenn Sie sich paranoid fühlen, können Sie am Anfang des Programms finit verwenden, dieser Befehl setzt die Steuerregister der FPU zurück, um die Register leer zu markieren.
Das Betriebssystem sollte Ihren Prozess bereits mit einem sauberen Zustand starten.

Hier ein einfaches Beispiel:

.DATA 

    A dd 5.0 
    B dq 0.008 

    C dd 0   ;Move into a BSS section if the assembler support it 

.CODE 

    finit    ;For paranoid only 

    fld DWORD [A]  ;ST(0) = A 
    fmul QWORD [B]  ;ST(0) = ST(0)*B = A*B 
    fstp DWORD [C]  ;C = ST(0) = A*B 

    mov eax, DWORD [C] ;EAX = C = A*B 
    call writefloat 

Wie heute können Sie die Vektorregister mit skalaren Befehle verwenden.
Die entsprechende Dokumentation finden Sie noch im zuvor verlinkten Intel-Handbuch.

.DATA 

    A dd 5.0   ;Use float 
    B dd 0.008  ;Use float again, avoid cvtss2sd 

    C dd 0   ;Move into a BSS section if the assembler support it 

.CODE 

movss xmm0, DWORD PTR [A] ;xmm0.f[0] = A 
mulss xmm0, DWORD PTR [B] ;xmm0.f[0] = A * B 
movd eax, xmm0    ;eax = xmm0.f[0] = A * B 
           ;Beware, 1 extra cycle for bypass delay 
call writefloat 
+0

danke für die Antwort war es sehr hilfreich –

Verwandte Themen