Macierze: dwa indeksy, jeden adres
Macierz to siatka liczb ułożonych w wiersze i kolumny. Wiersz to jedna pozioma linia siatki, czytana od lewej do prawej. Kolumna to jedna pionowa linia siatki, czytana od góry do dołu. Pamięć nie ma pojęcia wierszy ani kolumn. To jeden długi ciąg bajtów, ten sam rodzaj wektora omawiany w poprzedniej lekcji. Aby zapisać macierz, jej wiersze i kolumny muszą zostać umieszczone jeden po drugim w tym jednym ciągu. Zwykle wybiera się porządek row-major: zapisz każdą liczbę pierwszego wiersza, potem każdą liczbę drugiego wiersza, i kontynuuj, aż każdy wiersz zostanie umieszczony.
Dwa indeksy, jeden adres
Pozycja elementu w macierzy jest określona przez dwa indeksy: indeks wiersza, czyli do którego wiersza należy, oraz indeks kolumny, czyli do której kolumny należy. Liczenie obu zaczyna się od 0, tak samo jak indeksy działały w lekcji o wektorach. Pamięć przechowuje pojedynczy płaski ciąg liczb, więc oba indeksy trzeba najpierw połączyć w jeden spłaszczony indeks: pomnóż indeks wiersza przez liczbę kolumn macierzy, a następnie dodaj indeks kolumny. Stąd spłaszczony indeks staje się adresem bajtowym w taki sam sposób jak indeks wektora: address = base + index * 4.
mul t4, t1, t3 # t4 = indeks wiersza * liczba kolumnadd t4, t4, t2 # t4 = that + indeks kolumny (indeks spłaszczony)slli t4, t4, 2 # t4 = przesunięcie w bajtach = indeks * 4add t5, t0, t4 # t5 = adres elementu w tym wierszu i kolumnielw t5, 0(t5) # t5 = wartość pod tym adresem
mnoży indeks wiersza przez liczbę kolumn. W lekcji o wektorach mnożenie można było wykonać przesunięciem, ponieważ 4 jest potęgą dwójki, ale liczba kolumn macierzy zwykle nią nie jest, więc tutaj użyto zamiast . Dodaje się indeks kolumny, a wynik jest skalowany przez 4 za pomocą kolejnego (4 jest potęgą dwójki, więc przesunięcie nadal działa dla tej części). To daje przesunięcie bajtowe elementu w podanym wierszu i kolumnie.
Wiersz 0, kolumna 0 odpowiada indeksowi 0.
.data twojego programu i twoje własne czytanie narzucają na ten pojedynczy wiersz, używając arytmetyki , i pokazanej powyżej. Gdy siatka i spłaszczony wiersz zostaną zrozumiane jako jedna rzecz pokazana dwa razy, ten sam wzorzec obejmuje dowolną siatkę danych: wiersze pikseli obrazu, planszę gry lub arkusz kalkulacyjny. Każda z nich to jedna tablica, do której dociera się przez jedno dodatkowe mnożenie.Suma macierzy
.datam: .word 1, 2, 3, 4, 5, 6, 7, 8, 9 # macierz 3x3, przechowywana wiersz po wierszu.textla t0, m # adres bazowyli t1, 3 # liczba wierszyli t2, 3 # liczba kolumnli t3, 0 # bieżący indeks wiersza, zaczyna się od 0li s0, 0 # suma bieżącarow_loop:beq t3, t1, row_doneli t4, 0 # bieżący indeks kolumny, zaczyna się od 0col_loop:beq t4, t2, col_donemul t5, t3, t2 # indeks wiersza * liczba kolumnadd t5, t5, t4 # + indeks kolumny = spłaszczony indeksslli t5, t5, 2 # przesunięcie w bajtach = indeks * 4add t6, t0, t5 # adres elementu w tym wierszu i kolumnielw t6, 0(t6) # wartość pod tym adresemadd s0, s0, t6 # suma += elementaddi t4, t4, 1 # przechodzi do następnej kolumnyj col_loopcol_done:addi t3, t3, 1 # przechodzi do następnego wierszaj row_looprow_done:mv a0, s0 # wypisuje sumę: 1+2+...+9 = 45li a7, 1ecallli a7, 10ecall
Dwie zagnieżdżone pętle indeksują macierz. Zewnętrzna pętla wybiera wiersz, a wewnętrzna wybiera kolumnę w tym wierszu. mnoży indeks wiersza przez liczbę kolumn. Dodanie indeksu kolumny i skalowanie przez 4 daje adres tego elementu. Wartość zapisana pod tym adresem jest wczytywana i dodawana do bieżącej sumy. Gdy wewnętrzna pętla kończy wiersz, zewnętrzna pętla przechodzi do następnego wiersza, aż wszystkie 3 wiersze zostaną przetworzone.
