Wie kann ich das multiplizieren von zwei 64-bit-zahlen mit x86 Assembler?
Wie würde ich mich über...
-
Multiplikation von zwei 64-bit-zahlen
-
Multiplikation von zwei 16-stelligen hexadezimal-zahlen
...mit Assembler.
Ich bin mir nur erlaubt die Verwendung von Registern %eax, %ebx, %ecx, %edx, und der stack.
EDIT: Oh, ich bin mit der ATT-Syntax auf die x86
EDIT2: Nicht erlaubt, zu dekompilieren, in der Montage -...
- Möchten Sie möglicherweise angeben, welche Montage Sie verwenden. Allgemeine Techniken sind cross-anwendbar ist (in der Regel), aber die mnemonics sind fast immer zwischen verschiedenen Plattformen. 🙂
- Oh, ATT Syntax für die x86? Ich bin leider nicht hinzufügen, dass die info... Sieht für die Schaltfläche "Bearbeiten" auf Titel
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden, was sollte wohl werden, Ihren Kurs lehrbuch, Randall Hyde ' s "The Art of Assembly Language".
Sehen 4.2.4 - Extended-Precision-Multiplikation
(Siehe den link für die vollständige Liste der assembly und Illustrationen.)
Wenn dies 64x86,
Da bist du auf x86-Sie benötigen 4 mull Anweisungen. Teilen Sie die 64-bit-Mengen, die in zwei 32bit Worte und multiplizieren Sie die niedrigen Worte zu den niedrigsten und den 2 niedrigsten word mit dem Ergebnis, dann beide Paare von low-und high-word aus verschiedenen Nummern (Sie gehen auf das 2. und 3. niedrigste Wort des Ergebnisses) und schließlich sowohl hohe Worte in den 2 höchsten Worten über das Ergebnis. Hinzufügen Sie alle zusammen, nicht zu vergessen, befassen sich mit tragen. Sie nicht geben Sie das Speicher-layout der ein-und Ausgänge, so ist es unmöglich zu schreiben Beispielcode.
Dieser code setzt Voraus, Sie wollen x86 (nicht x64-code), dass Sie wahrscheinlich nur eine 64-bit-Produkt, und Sie kümmern sich nicht um überlauf oder vorzeichenbehaftete zahlen. (Eine signierte version ähnlich ist).
Diesem nicht Ehre, die genauen register Einschränkungen der OP, aber das Ergebnis passt durchaus in das Register angeboten, die durch die x86-Architektur. (Dieser code ist ungetestet, aber ich denke, es ist richtig).
[Anmerkung: ich übertragen (meine) diese Antwort aus einer anderen Frage, die habe geschlossen, weil KEINER von den anderen "Antworten", hier direkt die Frage beantwortet].
add
müssten Sieadc
.lo1 * lo2
=> 64 bit, ohne Zusatz tragen kann in der oberen Hälfte Ergebnislo1 * hi2
=> 32 bit undlo2 * hi1
=> 32 bits. So die letzten 2 könnte getan werden, mit 2-Operandenimul ecx, esi
/imul edi, ebx
stattxchg
undmul
, denn Sie will nur eine 64-bit-Ergebnis, und nicht 96 oder 128.Es hängt davon ab, welche Sprache Sie verwenden. Von was ich mich erinnere, lernen MIPS assembly, es ist eine Bewegung Von Hoch-Befehl und ein Umzug Von Lo-Befehl, oder mflo und mfhi. mfhi speichert die top-64bits während mflo speichert die unteren 64 bit der Gesamtzahl.
ah-Versammlung, schon eine Weile her, ich habe es verwendet. also ich gehe davon aus, dass das eigentliche problem hier ist, dass der mikrocontroller (was ich zu dem schreiben von code in Assembler sowieso) Sie arbeiten nicht in 64 bit-Register? wenn das der Fall ist, sind Sie gehen zu müssen, die brechen die zahlen mit dem Sie arbeiten, auseinander und führen Sie mehrere Multiplikationen mit den Stücken.
das klingt wie es ist eine Hausaufgabe aus dem Weg, du hast formuliert, so dass ich werde nicht buchstabieren Sie es aus, viel weiter 😛
Nur normale lange Multiplikation, wie wenn du die Multiplikation von zwei 2-stelligen zahlen, außer jede "Ziffer" ist wirklich eine 32-bit-Ganzzahl. Wenn Sie die Multiplikation von zwei zahlen in die Adressen X und Y, und speichern das Ergebnis in Z, dann, was Sie tun wollen (in pseudocode) ist:
Beachten Sie, dass wir verwerfen die oberen 64 bits des Ergebnisses (da ein 64-bit-Zahl mal eine 64-bit-Nummer ist mit einer 128-bit-Zahl). Beachten Sie auch, dass dies wird vorausgesetzt, little-endian. Auch, vorsichtig sein, über ein signiertes oder ein unsigniertes multiplizieren.
Finden Sie einen C-compiler, unterstützt 64-bit (GCC hat IIRC) kompilieren Sie ein Programm, das genau das tut, dann Holen Sie sich die Demontage. GCC spucken kann er sich auf seine eigene, und Sie können es out-of-object-Datei mit den richtigen tools.
OTOH ist eine 32bX32b = 64b-op auf x86
alles andere überläuft
(ungetestet)
Bearbeiten Unsigned nur
Ich Wette, du bist ein student, so sehen Sie, ob Sie diese Arbeit machen: Tun Sie es Wort für Wort, und verwenden Sie bit-Verschiebungen. Denke, die effizienteste Lösung. Hüten Sie sich vor der das Vorzeichen-bit.
Wenn Sie möchten, 128-Modus versuchen, diese...
__uint128_t
und Vermietung gcc zu tun. Auch dies ziemlich genau kopiert Ira Baxter ' s Antwort. Wenn es war gute inline-asm, könnte es eine sinnvolle Ergänzung sein, ist es aber nicht. Mit einer Menge von festen Registern, ohne memory-Operanden ist bei weitem nicht optimal. Sollten Sie nur lassen Sie gcc alles im Griff, außer die 64x64 -> 128mul
Anweisungen, mit zwei getrenntenasm
Aussagen mit 2 Eingänge und 2 Ausgänge. Und das sollte nicht seinvolatile
asm ("mulq %[src]" : "=a"(lo64_result), "=d"(hi64_result) : "a"(KEY.SPLIT.LWORDS[1]), [src] "rm" (KEY.SPLIT.LWORDS[0]));
Und dann eine zweite ähnliche asm-Anweisung für die zweite multiplizieren. gcc wird alles tun, denmov
Anweisungen. Sie einfach sagen, es, wo die Dinge sein müssen, und wo die Ergebnisse angezeigt werden. Quelle für die gcc-Bibliothek code hat nichts damit zu tun, und weder memory-Verschiebungen. Siehe die x86 - Tags, wiki-links zu schreiben wie man inline-asm, das ist nicht so schlimm. Das kompiliert: goo.gl/izSfMiWenn Sie möchten, dass die 128-bit-Multiplikation, dann sollte diese Arbeit ist dies in AT&T-format.