Matrizen: zwei Indizes, eine Adresse
Eine Matrix ist ein Raster aus Zahlen, die in Zeilen und Spalten angeordnet sind. Eine Zeile ist eine horizontale Linie des Rasters, die von links nach rechts gelesen wird. Eine Spalte ist eine vertikale Linie des Rasters, die von oben nach unten gelesen wird. Der Speicher kennt keine Zeilen oder Spalten. Er ist eine lange Folge von Bytes, dieselbe Art von Vektor, die in der vorherigen Lektion behandelt wurde. Um eine Matrix zu speichern, müssen ihre Zeilen und Spalten nacheinander in dieser einzigen Folge abgelegt werden. Die übliche Wahl ist die Row-Major-Reihenfolge: jede Zahl der ersten Zeile speichern, dann jede Zahl der zweiten Zeile, und so weiter, bis jede Zeile abgelegt wurde.
Zwei Indizes, eine Adresse
Die Position eines Elements in einer Matrix wird durch zwei Indizes angegeben: den Zeilenindex, zu welcher Zeile es gehört, und den Spaltenindex, zu welcher Spalte es gehört. Die Zählung beginnt bei beiden bei 0, genauso wie die Indizes in der Vektorlektion funktionierten. Der Speicher enthält eine einzige flache Folge von Zahlen, daher müssen die beiden Indizes zuerst zu einem einzigen flachen Index kombiniert werden: den Zeilenindex mit der Anzahl der Spalten der Matrix multiplizieren, dann den Spaltenindex addieren. Von dort aus wird der flache Index auf dieselbe Weise wie der Index eines Vektors zu einer Byte-Adresse: address = base + index * 4.
mul t4, t1, t3 # t4 = Zeilenindex * Anzahl der Spaltenadd t4, t4, t2 # t4 = das + Spaltenindex (der flache Index)slli t4, t4, 2 # t4 = Byte-Offset = Index * 4add t5, t0, t4 # t5 = Adresse des Elements in dieser Zeile und Spaltelw t5, 0(t5) # t5 = Wert an dieser Adresse
multipliziert den Zeilenindex mit der Anzahl der Spalten. In der Vektorlektion konnte die Multiplikation mit einer Verschiebung durchgeführt werden, weil 4 eine Zweierpotenz ist, aber die Anzahl der Spalten einer Matrix ist normalerweise keine, daher wird hier anstelle von verwendet. Der Spaltenindex wird addiert, und das Ergebnis wird mit einem weiteren mit 4 skaliert (4 ist eine Zweierpotenz, also funktioniert eine Verschiebung für diesen Teil weiterhin). Das ergibt den Byte-Offset des Elements an der gegebenen Zeile und Spalte.
Zeile 0, Spalte 0 entspricht Index 0.
.data-Layout Ihres Programms und Ihr eigenes Lesen davon dieser einzigen Zeile auferlegen, unter Verwendung der oben gezeigten Arithmetik , und . Sobald das Raster und die flache Zeile als eine Sache verstanden werden, die zweimal gezeigt wird, deckt dasselbe Muster jedes Raster von Daten ab: die Pixelzeilen eines Bildes, ein Spielbrett oder eine Tabellenkalkulation. Jedes ist ein Array, das mit einer zusätzlichen Multiplikation erreicht wird.Matrix addieren
.datam: .word 1, 2, 3, 4, 5, 6, 7, 8, 9 # 3x3-Matrix, zeilenweise gespeichert.textla t0, m # Basisadresseli t1, 3 # Anzahl der Zeilenli t2, 3 # Anzahl der Spaltenli t3, 0 # aktueller Zeilenindex, beginnt bei 0li s0, 0 # laufende Summerow_loop:beq t3, t1, row_doneli t4, 0 # aktueller Spaltenindex, beginnt bei 0col_loop:beq t4, t2, col_donemul t5, t3, t2 # Zeilenindex * Anzahl der Spaltenadd t5, t5, t4 # + Spaltenindex = abgeflachter Indexslli t5, t5, 2 # Byte-Offset = Index * 4add t6, t0, t5 # Adresse des Elements in dieser Zeile und Spaltelw t6, 0(t6) # Wert an dieser Adresseadd s0, s0, t6 # Summe += Elementaddi t4, t4, 1 # zur nächsten Spalte weiterj col_loopcol_done:addi t3, t3, 1 # zur nächsten Zeile weiterj row_looprow_done:mv a0, s0 # gibt die Summe aus: 1+2+...+9 = 45li a7, 1ecallli a7, 10ecall
Zwei verschachtelte Schleifen indizieren die Matrix. Die äußere Schleife wählt eine Zeile aus und die innere Schleife wählt eine Spalte innerhalb dieser Zeile aus. multipliziert den Zeilenindex mit der Anzahl der Spalten. Das Addieren des Spaltenindex und das Skalieren mit 4 ergibt die Adresse dieses Elements. Der an dieser Adresse gespeicherte Wert wird geladen und zur laufenden Summe addiert. Wenn die innere Schleife eine Zeile beendet, geht die äußere Schleife zur nächsten Zeile über, bis alle 3 Zeilen verarbeitet wurden.
