MUL(Assembler) in C
In Assembler kann ich auch mit dem MUL Befehl aus und erhalten Sie eine 64-bit-Ergebnis EAX:EDX,
wie kann ich das gleiche in C ? http://siyobik.info/index.php?module=x86&id=210
Mein Ansatz ein uint64_t und Schiebe das Ergebnis nicht arbeiten^^
Danke für Eure Hilfe (=
Mir
- Bitte posten Sie den C-code, den Sie verwendet, und die Ergebnisse, die Sie erwartet hatten, und wir können von dort aus zu gehen...
- Ich bin mir ziemlich sicher, dass dein problem ist, dass du versuchst zu werfen, um
uint64_t
nach Multiplikation anstatt vor. Besetzung eines der Argumente, bevor die Multiplikation.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Jeder anständige compiler tun Sie es einfach, wenn Sie gefragt.
Z.B. mit VC++ 2010, den folgenden code:
generiert die folgende assembler:
a
nach der Vermehrung? Es erscheint die Speicherung der höhere Anteil des Ergebnisses ina
. Ihre C-Quelle nicht irgend etwas tun, wie.a
und durchresult
, was vielleicht OK ista
ist nie benutzt danach.Post code. Dies funktioniert für mich:
MUL
Anleitung? Haben Sie überprüft?grep mul 4099867.s
gibt ` imulq %rdx, %rax. Apparently my compiler doesn't use
MUL` bei der Montage, dass der code ohne optimizimations. Mit voller Optimierungen, diegrep
gibt nichts zurückmul
wenn die Operanden und das Ergebnis waren nicht signiert.Sehen, wenn Sie den Gegenwert von __emul oder __emulu für den compiler(oder benutzen Sie dies einfach, wenn Sie haben eine MS-compiler). obwohl 64-bit-multiplizieren sollte automatisch funktionieren, es sei denn Ihr sitzt hinter bestimmten Einschränkungen oder andere lustige problem(wie _aulmul)
Du meinst multiplizieren zwei 32-bit-Mengen, erhalten Sie eine 64-bit-Ergebnis?
Dies ist nicht vorgesehen in C von selbst, entweder Sie haben tow 32 bit in wie
uint32_t
und dann ist das Ergebnis die gleiche Breite. Oder Sie werfen vor, umuint64_t
aber dann verlieren Sie den Vorteil, dass spezielle (und schnell) zu vermehren.Die einzige Möglichkeit die ich sehe ist die Verwendung von inline-assembler-Erweiterungen. gcc ist ziemlich gut in diesem können Sie produzieren ganz optimalen code. Aber das ist nicht portabel zwischen verschiedenen Versionen von Compilern. (Viele public-domain-Compiler verabschieden, gcc, obwohl, glaube ich)
#include
Diese produziert:
Beim kompilieren mit:
Verwendet
mul
Anweisung (genanntmull
hier für multiplizieren lange, wie man den gnu assembler für x86-mag es) in der Weise, dass Sie wollen.In diesem Fall wird einer der Parameter war, zog direkt aus dem Stapel, anstatt platziert in einem register (der
4(%esp)
was bedeutet, dass 4 bytes oberhalb des stack-Zeigers, und die 4 bytes werden übersprungen, sind die Rückkehr-Adresse), weil die zahlen an die Funktion übergeben wurden und hätte auf dem Stapel abgelegt (wie pro die x86-ABI (application binary interface) ).Wenn Sie inlined, die Funktion oder habe gerade die Mathe in der es in deinem code würde es höchstwahrscheinlich mit der
mul
Unterricht in vielen Fällen, wenn die Optimierung der Compiler ersetzen auch einige Multiplikationen mit einfacher code, wenn Sie sagen, dass es funktionieren würde (zum Beispiel könnte daraus eine Verschiebung oder gar eine Konstante, wenn die eine oder mehrere der Argumente bekannt waren).In den C-code mindestens eines der Argumente mussten gegossen werden, um eine 64-bit-Wert, so dass der compiler erzeugen würde eine 64 bit-Ergebnis. Selbst wenn der compiler war die Verwendung der code, der produziert einen 64-bit-Ergebnis, wenn die Multiplikation von 32-bit-Werten, kann es nicht als die Obere Hälfte der es wichtig zu sein, weil nach den Regeln der C-Operationen führen meist zu einem Wert vom gleichen Typ wie der Wert mit der größten Auswahl aus seinen Komponenten (außer manchmal kann man argumentieren, dass ist nicht wirklich genau was Sie tut).
Können Sie nicht tun, genau das auch in C, d.h. Sie können nicht multiplizieren von zwei N-bit-Werte, und der Erwerb eines 2N-bit-Wert als Ergebnis. Semantik von C Multiplikation unterscheidet sich von der Maschine eine Multiplikation. In C die Multiplikation operator bezieht sich immer auf die Werte des gleichen Typs
T
(so genannte üblichen arithmetischen Umwandlungen kümmern) und erzeugt das Ergebnis des gleichen TypsT
.Wenn du overflow bei Multiplikation, haben Sie einen größeren Typ der Operanden. Wenn es keine größere geben, sind Sie aus Glück (d.h., Sie haben keine andere Wahl, sondern auf library-Ebene die Umsetzung der großen Multiplikation).
Beispielsweise, wenn der größte integer-Typ Ihrer Plattform ist eine 64-bit-Typ, dann auf der assembly-Ebene auf Ihrem Computer haben Zugriff auf
mul
Betrieb produzieren die richtigen 128-bit-Ergebnis. Auf sprachlicher Ebene haben Sie keinen Zugriff auf eine solche Multiplikation.Nbit * Nbit -> 2Nbit
). Und wie ich schon sagte in meiner Antwort, leider gibt es keine solche Multiplikation in C. Es gibt keine Lösung. In der C-Multiplikation ist immerNbit * Nbit -> Nbit
.2Nbit * 2Nbit -> 2Nbit
Vermehrung (wenn möglich), das ist das, was Sie vorgeschlagen. Aber das ist nicht das, was angefordert wurde, der nach meiner interpretation der Frage. Es gibt ein Beispiel in meiner Antwort, dass zeigt den Unterschied: in C hat man keinen Zutritt zu der Maschine64-bit * 64-bit -> 128-bit
Multiplikation ist die größte integer-Typ ist 64-bit. Maschine es tun kann. C kann es nicht. Genauer gesagt, die C bietet keine Möglichkeit für Sie, die Aufgabe die Maschine zu tun. Das ist mein Punkt.