Multiplizieren, Dividieren und Akkumulation
In diesem Abschnitt werden wir die Grundlagen der Multiplikation und Division im ARM64-Assembler behandeln, einschließlich der Arbeit mit negativen Zahlen und der Handhabung von Überläufen und großen Zahlen. Wir werden sowohl einfache Operationen als auch komplexere Szenarien betrachten, wie z.B. die Multiplikation zweier 64-Bit-Zahlen zu einer 128-Bit-Zahl und die Division einer 128-Bit-Zahl.
Einfache Multiplikation: mul-Befehl
Der mul-Befehl multipliziert zwei 64-Bit-Zahlen und speichert das Ergebnis in einem Register.
Syntax: mul <Zielregister>, <Quellregister1>, <Quellregister2> Beispiel: .global _start
_start:
mov x0, #5 // Setze x0 auf 5 mov x1, #6 // Setze x1 auf 6 mul x2, x0, x1 // x2 = x0 * x1 (5 * 6 = 30)
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Multiplikation und Umgang mit negativen Zahlen
In ARM64-Assembler sind Zahlen standardmäßig als vorzeichenbehaftet (signed). Der mul-Befehl funktioniert daher korrekt mit negativen Zahlen.
Beispiel mit negativen Zahlen: .global _start
_start:
mov x0, #-5 // Setze x0 auf -5 mov x1, #6 // Setze x1 auf 6 mul x2, x0, x1 // x2 = x0 * x1 (-5 * 6 = -30)
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Multiplikation zweier 64-Bit-Zahlen mit Überlauf: umulh
Um Überläufe in der Multiplikation zu behandeln und eine präzise 128-Bit-Zahl zu erhalten, verwenden wir eine Kombination von Befehlen: mul für die unteren 64-Bit und umulh (unsigned multiply high) für die oberen 64-Bit.
Beispiel: .global _start
_start:
mov x0, #0xFFFFFFFFFFFFFFFF // Setze x0 auf den maximalen 64-Bit-Wert mov x1, #2 // Setze x1 auf 2
// Multipliziere x0 und x1 mul x2, x0, x1 // x2 = untere 64 Bit des Ergebnisses umulh x3, x0, x1 // x3 = obere 64 Bit des Ergebnisses
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Division: udiv-Befehl
Der udiv-Befehl wird verwendet, um zwei 64-Bit-Zahlen zu dividieren.
Syntax: udiv <Zielregister>, <Quellregister1>, <Quellregister2> Beispiel: .global _start
_start:
mov x0, #30 // Setze x0 auf 30 mov x1, #6 // Setze x1 auf 6 udiv x2, x0, x1 // x2 = x0 / x1 (30 / 6 = 5)
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Umgang mit negativen Zahlen bei der Division
Bei der Division von vorzeichenbehafteten Zahlen verwenden wir sdiv (signed divide).
Beispiel: .global _start
_start:
mov x0, #-30 // Setze x0 auf -30 mov x1, #6 // Setze x1 auf 6 sdiv x2, x0, x1 // x2 = x0 / x1 (-30 / 6 = -5)
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Division einer 128-Bit-Zahl: udiv verwenden
Um eine 128-Bit-Zahl zu dividieren, die in zwei 64-Bit-Registern gespeichert ist, müssen wir die 64-Bit-Teile nacheinander verarbeiten. Dies ist komplexer und erfordert mehrere Schritte, um die Genauigkeit zu gewährleisten.
Beispiel für Division einer 128-Bit-Zahl durch eine 64-Bit-Zahl: Angenommen, wir haben eine 128-Bit-Zahl in den Registern x0 (untere 64-Bit) und x1 (obere 64-Bit) und wir wollen durch die 64-Bit-Zahl in x2 dividieren.
Konvertiere die obere 64-Bit-Zahl zu einer 128-Bit-Zahl. Füge die untere 64-Bit-Zahl dazu. Teile alles durch die 64-Bit-Zahl. .global _start
_start:
// Beispielwerte setzen mov x0, #0xFFFFFFFFFFFFFFFF // LSB von 128-Bit-Zahl mov x1, #0x0000000000000001 // MSB von 128-Bit-Zahl (kleiner Wert zur Vereinfachung) mov x2, #3 // Divisor
// Multipliziere MSB mit 2^64, um die richtige Position in der 128-Bit-Zahl zu erhalten
movk x1, #0, lsl 0 // x1 = x1 << 64 (technisch Teil des hohen Bits)
mul x3, x1, x2 // Division der oberen 64-Bits durch 3
// Hinweis: Pseudo, weil x64-Teiler nicht msb sondern nur shift)
// Addiere die unteren 64-Bit hinzu add x3, x3, x0 // Summiere die "er Ergebnisse"
// Teile die resultierende 64-Bit-Zahl in x3 durch x2 udiv x4, x3, x2 // Ergebnis in x4 (86)
// Programm beenden mov x8, #93 // exit system call svc 0 // system call
Zusammenfassung
In diesem Abschnitt haben wir die Grundlagen der Multiplikation und Division im ARM64-Assembler behandelt und uns speziell mit der Arbeit mit negativen Zahlen, Überläufen und großen Zahlen beschäftigt. Durch die Anwendung der gezeigten Techniken können Sie komplexe 128-Bit-Arithmetikoperationen durchführen und dabei die Genauigkeit und Konsistenz Ihrer Ergebnisse gewährleisten. Viel Erfolg beim Üben und Vertiefen dieser wichtigen Konzepte!