2010-11-18 5 views
1

Ich verwende das PCSIM-Programm, von dem ich glaube, dass es MIPS verwendet. Ich bin nicht positiv, da ich Assemblersprache sehr neu bin. Ich muss zwei 32-Bit-Zahlen multiplizieren, indem ich nur addiere und verschiebe und das Produkt in zwei Registern abspeichere. Ich habe es dahin gebracht, wo es erfolgreich zwei Zahlen multipliziert, wenn das Ergebnis in 32 Bits gespeichert werden kann. Das Problem ist, dass, wenn die Zahl größer ist, ich nicht herausfinden kann, wie man die rechte Hälfte des Produkts mit der linken Hälfte kombiniert. Das linke Half-Register sollte Werte von 2^32 ganz oben halten. Wenn das nicht klar ist, kann ich versuchen, mehr zu erklären. Gibt es einen einfachen Weg, den ich übersehe, um dies zu erreichen? Danke für jede Hilfe.Wie kann ich zwei 32-Bit-Register in eine 64-Bit-Antwort kombinieren?

Antwort

0

Es gibt keine Möglichkeit, die beiden Hälften zu einem 32-Bit-Register zu "kombinieren". Wenn Sie die beiden Hälften zu einem 64-Bit-Wert im Speicher kombinieren möchten, müssen Sie beide Hälften nebeneinander speichern, abhängig von der Endgültigkeit Ihrer Maschine. Wenn Sie SPIM verwenden, scheint es, dass es die gleiche Enianness Ass Host-Computer verwendet.

X86? Kleiner Endian. Speichern Sie die untere Hälfte zuerst. PPC? Großer Endian. Speichern Sie zuerst die obere Hälfte.

1

Wenn ich richtig verstanden habe, steckst du an dem Punkt fest, an dem du eigentlich 64-Bit-Arithmetik machen musst, oder?

Wenn Sie eine typische tun Shift-und-Additions binäre lange Multiplikation, könnten Sie einige 64-Bit-Verschiebung und Addition Primitiven von 32-Bit-Operationen bauen, dann die gleiche Methode verwenden.

Hier sind einige Beispiele, wie C-Fragmente (sollte, zu MIPS zu übersetzen trivial sein, wenn das ist, was Sie verwenden eigentlich). Ich nehme an, dass Sie mit nicht signierten 32-Bit-Zahlen arbeiten und nicht signierte 64-Bit-Ergebnisse möchten.

logische Verschiebung nach links 1 Bit:

tmp = lo >> 31; /* top bit of lo to bottom bit of tmp, rest of tmp is 0 */ 
lo <<= 1; 
hi <<= 1; 
hi |= tmp; 

Logische Verschiebung nach rechts 1 Bit:

tmp = hi << 31; /* bottom bit of hi to top bit of tmp, rest of tmp is 0 */ 
hi >>= 1; 
lo >>= 1; 
lo |= tmp; 

(in der Tat können Sie ersetzen die 1 und 31 mit n und (32 - n) durch eine andere Zahl verschieben von Bits)

64-Bit-Zusatz:

result_lo = a_lo + b_lo; 
result_hi = a_hi + b_hi; 
if (result_lo < a_lo) 
    result_hi++; 

(siehe here für weitere Details, mit speziellem Verweis auf MIPS).

Ein alternativer Ansatz besteht darin, jeden Ihrer 32-Bit-Eingänge als ein Paar 16-Bit- "Ziffern" zu behandeln; Multiplizieren von zwei 16-Bit-Zahlen ergibt höchstens ein 32-Bit-Ergebnis. So ist die Grundidee ist wie folgt:

0x12345678 * 0x23456789 =  0x5678 * 0x6789 
          + ((0x1234 * 0x6789) << 16) 
          + ((0x5678 * 0x2345) << 16) 
          + ((0x1234 * 0x2345) << 32) 

(Sie werden noch einige 64-Bit-Erweiterungen benötigen).