floating-point-zahlen in ASM
In den letzten Tagen spielte ich mit C++, ASM und inline-ASM. Ich weiß, wie ich access basic-Variablen im Speicher und ähnliche Dinge. Jetzt versuche ich, die Arbeit mit floating-point-zahlen in ASM.
Ich habe zerlegt diesen code:
float A = 0.058;
und ich habe dieses Ergebnis:
fld dword ptr ds:[00415744h]
fstp dword ptr [ebp-8]
Aber ich verstehe nicht, dieser code. Ich war auf der Suche auf google, aber ich habe nicht gefunden, was brauchbar für mich. Kann jemand mir erklären reellen zahlen in ASM und kann jemand erklären mir dieser code? Bitte helfen Sie mir.
- Von "reellen zahlen", meinst du, Literale oder meinst du floating-point-zahlen?
- oh, tut mir Leid. floating-point-zahlen
- Sieht aus wie x86 (x87) Montage? Könnte nützlich sein, markieren Sie Sie als solche.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die erste Zeile lädt konstanter float-Wert 0.058 der FPU-stack. Die zweite Zeile kopiert die Spitze der FPU-stack der CPU-Stapel, adressiert ebp-8.
Können Sie Lesen über die FPU Anweisungen hier: http://maven.smith.edu/~thiebaut/ArtOfAssembly/CH14/CH14-4.html oder in jedem anderen Assembler-Referenz.
Bearbeiten.
dword ptr [ebp-8] kopiert die Spitze der FPU-stack, um die DWORD-Größe der lokalen Variablen auf den stack. Von der Montage über die Referenz, EBP (base pointer): die Montage-Funktion setzt den base-pointer entspricht der stack-pointer und dann stellen Ihre eigenen internen Variablen auf dem stack. Von diesem Zeitpunkt an, wird die Funktion bezieht sich auf die Parameter und Variablen relativ zum base pointer eher als stack-pointer.
Dies ist, was der compiler getan hast mit deinem code:
Den compiler erkannt "0.058" als ein floating-point literal. Es analysiert die Zeichenfolge zu berechnen und den Wert, den es zu vertreten und zu codieren, dass der Wert als double-precision-floating-point-Wert. Dann erkannte er, dass Sie die Zuordnung dieses double-precision-Wert auf eine single-precision-Objekt (float A, nicht mit Doppel-A), so dass Sie nicht brauchen die volle double-precision-Wert. Damit der compiler konvertiert es zu single-precision. Die Codierung, die geführt wurde wahrscheinlich 0x3d6d9168, was die Allgemeine IEEE-754-Codierung für .058 in single-precision.
Irgendwo in der Assembler-code den der compiler generiert, der compiler generiert eine Richtlinie (eine Anweisung an den assembler), die bewirkt, dass der Wert, 0x3d6d9168, um im Speicher abgelegt werden. (Dies ist ein komplizierter Prozess, der assembler schreibt den Wert für die Objekt-Datei, die es produziert, als Teil von verschiedenen Daten, werden Teil des Programms image. Diese Daten werden in den Speicher geladen, wenn das Programm bereit ist, für die Durchführung oder, wenn das Programm zum ersten mal versucht, auf diesen Teil des Speichers.)
Zusätzlich der compiler generiert die fld Anweisung, "fld dword ptr ds:[00415744h]". Es hat eine Weile, da ich verwendet, dass die form der Versammlung, also ich kann mich etwas ab, aber ich glaube, die Anleitung sagt "Verwenden Sie das Data Segment (DS) registrieren Sie sich als base-Adresse und 0x415744 als offset innerhalb des Segments. Diese Kombination ist ein Zeiger auf ein double-word. Last four bytes von dort aus auf die floating-point-stack. (Die floating-point-stack ist ein spezieller Satz von Registern im Prozessor.)
Den fstp Anweisung, "fstp dword ptr [ebp-8]", bedeutet: "Nimm den Inhalt der Extended Base Pointer (EBP) registrieren und subtrahieren 8. Dieser Wert ist ein Zeiger auf ein double-word. Speichern vier bytes aus dem floating-point-stack, um die double-word -, und pop das Element aus dem floating-point-stack."
Beachten Sie, dass 0x415744 hat nichts zu tun mit der floating-point-Wert. Es ist die Adresse im Speicher wo der Konstante Wert gespeichert wurde. Diese beiden Anweisungen sind das laden der Konstante Wert von einem nur-lese-Position in den Speicher und speichern Sie es auf [ebp-8], die den Ort im Speicher, wo der compiler beschlossen hat, halten Sie den Wert in die variable A. Die EBP wird Häufig verwendet, um beziehen sich auf Standorte in den stack, damit der compiler hat mit ziemlicher Sicherheit beiseite einige Speicher im stack-frame der Funktion die Werte Ihrer Variablen.
Ich vermute, Sie kompiliert den code-Optimierung ausgeschaltet. Wenn die Optimierung eingeschaltet ist, würde der compiler wahrscheinlich nicht die Mühe machen, tatsächlich speichern die floating-point-Wert im Speicher zugewiesen für A. Dies ist, weil Sie nicht etwas zu tun mit dem Wert, der sofort, nur der Speicherung in A. Aber wir wissen bereits, den Wert und haben es an anderer Stelle gespeichert, warum also die Mühe machen zu kopieren? Stattdessen werden zu einem späteren Stelle im code, wo Sie tatsächlich mit dem Wert von A, würde der compiler dann laden Sie es aus dem nur-lese-Speicher und verwenden Sie es, direkt in die Berechnungen. (Dies ist nicht immer der Fall ist, können Sie code schreiben, erfordert der compiler, um einige zu kopieren, da der code vielleicht nehmen Sie eine von mehreren möglichen Pfade je nach übergebenen Parameter oder andere Faktoren, und der compiler muss die kopieren, um sicherzustellen, dass die richtigen Daten für den Pfad, dem gefolgt wird. Jedoch, im Allgemeinen, Sie sollten nicht erwarten, finden Sie exakte übereinstimmungen zwischen C-code, den Sie schreiben, und Montage Anweisungen, die der compiler generiert.)