Vektoren: Indizierung nach Position
Ein Vektor ist ein Array: eine Folge von Zahlen, die im Speicher nebeneinander abgelegt sind. In der vorherigen Lektion hast du einen summiert, indem du einen Zeiger für jedes Element um 4 Bytes vorwärts bewegt hast. Dieselbe Methode funktioniert auch hier. Es gibt eine weitere gängige Möglichkeit, auf ein Element zuzugreifen: über den Index. Ein Index ist die Position eines Elements vom Anfang an gezählt, wobei das erste Element den Index 0 hat, das zweite den Index 1, und so weiter.
Einen Vektor durch einen wandernden Zeiger summieren
.dataa: .word 5, 10, 15, 20 # vier Elemente.textla t0, a # t0 = Adresse von ali t1, 4 # t1 = Anzahl der verbleibenden Elementeli t2, 0 # t2 = laufende Summeloop:beq t1, zero, donelw t3, 0(t0) # lädt das aktuelle Elementadd t2, t2, t3 # addiert zur Summeaddi t0, t0, 4 # zum nächsten Wort weiter (4 Bytes)addi t1, t1, -1 # eines wenigerj loopdone:mv a0, t2 # gibt die Summe aus: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
Die Schleife läuft wie folgt ab. t0 enthält die Adresse von a, und t1 enthält die Anzahl der verbleibenden Elemente, beginnend bei 4. Bei jedem Durchlauf beendet die Schleife, wenn der Zähler null erreicht. lädt das Element an der Adresse in t0. addiert diesen Wert zur laufenden Summe. rückt den Zeiger zum nächsten Wort vor. verringert den Zähler. Nach vier Durchläufen (5 + 10 + 15 + 20) gibt done 50 aus. Dies ist dasselbe Muster wie in der Speicher-Lektion, nun auf einen Vektor angewendet.
Vom Index zur Adresse
Die Indexierung berechnet eine Adresse aus einem Basiszeiger und einer Position: address = base + index * 4. Die 4 ist die Größe eines Wortes in Bytes. Ein Compiler erzeugt dieselbe Berechnung für a[i] in einer Sprache wie C. Der Index selbst greift nie auf den Speicher zu. Nur die daraus berechnete Adresse tut dies.
slli t5, t3, 2 # t5 = Index * 4 (Wortgröße)add t6, t0, t5 # t6 = Adresse von element[index]lw t6, 0(t6) # t6 = element[index]
verschiebt den Index in t3 um 2 Bits nach links, was ihn mit 4 multipliziert (zwei Verdopplungen: 2 x 2), der Größe eines Wortes. Addiert man das Ergebnis zum Basiszeiger, erhält man die Adresse von element[index]. Diese Verschiebung ist dieselbe Zweierpotenz-Methode aus der Arithmetik-Lektion, und sie ist die Standardmethode, um einen Index mit der Größe eines Wortes zu skalieren.
a[0]: Index 0, Offset 0.
i als Position und die Adresse, die diese Position erzeugt, nachdem sie mit 4 skaliert und zur Basis addiert hat. Die Hex-Zahlen sind die tatsächlichen Adressen, die a belegt, wenn der Simulator dieses Programm ausführt. Das Ziel ist, die nächste Adresse vorherzusagen, bevor sie erscheint. Dadurch kannst du innerhalb einer inkrementierenden Schleife oder a[i] in einer C-ähnlichen Sprache lesen und dir die Speicheradresse vorstellen, auf die zugegriffen wird, anstatt die Notation als Blackbox zu behandeln.Einen Vektor per Index summieren
.dataa: .word 5, 10, 15, 20 # vier Elemente.textla t0, a # t0 = Basisadresse von ali t1, 4 # t1 = Anzahl der Elementeli t2, 0 # t2 = Index, beginnt bei 0li t3, 0 # t3 = laufende Summeloop:beq t2, t1, doneslli t4, t2, 2 # t4 = Index * 4 (Byte-Offset)add t5, t0, t4 # t5 = Adresse von a[index]lw t5, 0(t5) # t5 = a[index]add t3, t3, t5 # total += a[index]addi t2, t2, 1 # zum nächsten Index weiterj loopdone:mv a0, t3 # gibt die Summe aus: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
Die Schleife läuft wie folgt ab. t2 ist der Index, beginnend bei 0. Bei jedem Durchlauf beendet die Schleife, wenn der Index 4 erreicht, die in t1 gehaltene Elementanzahl. wandelt den Index in einen Byte-Offset um. addiert diesen Offset zur Basisadresse in t0, um die Adresse von a[index] zu erzeugen. lädt den dort gespeicherten Wert. Dieser Wert wird zur laufenden Summe in t3 addiert, und rückt zum nächsten Index vor. Nach vier Durchläufen (5 + 10 + 15 + 20) gibt done 50 aus.
Addition zweier Vektoren, Element für Element
.dataa: .word 3, 6, 9, 12 # erster Vektorb: .word 1, 2, 3, 4 # zweiter Vektorc: .space 16 # Platz für 4 Ergebniswörter.textla t0, a # Basisadresse von ala t1, b # Basisadresse von bla t2, c # Basisadresse von cli t3, 0 # Index, beginnt bei 0li t4, 4 # Anzahl der Elementeli s0, 0 # laufende Summeloop:beq t3, t4, doneslli t5, t3, 2 # Byte-Offset = Index * 4add t6, t0, t5 # Adresse von a[index]lw t6, 0(t6) # Wert von a[index]add a0, t1, t5 # Adresse von b[index]lw a0, 0(a0) # Wert von b[index]add t6, t6, a0 # a[index] + b[index]add a0, t2, t5 # Adresse von c[index]sw t6, 0(a0) # c[index] = a[index] + b[index]add s0, s0, t6 # Summe += c[index]addi t3, t3, 1 # zum nächsten Index weiterj loopdone:mv a0, s0 # gibt die Summe aus: 4+8+12+16 = 40li a7, 1ecallli a7, 10ecall
Die Schleife läuft wie folgt ab. wandelt den Index t3 in einen Byte-Offset um. Addiert man ihn zu jedem Basiszeiger (t0, t1, t2), erhält man die Adressen von a[i], b[i] und c[i]. Bei jedem Durchlauf werden beide Elemente geladen, addiert, in c gespeichert und zur laufenden Summe in s0 addiert. rückt zum nächsten Index vor, und die Schleife wiederholt sich, bis alle vier Elemente verarbeitet sind.
