Matrices: dos índices, una dirección
Una matriz es una cuadrícula de números dispuestos en filas y columnas. Una fila es una línea horizontal de la cuadrícula, que se lee de izquierda a derecha. Una columna es una línea vertical de la cuadrícula, que se lee de arriba a abajo. La memoria no tiene concepto de filas ni columnas. Es una sola línea larga de bytes, el mismo tipo de vector tratado en la lección anterior. Para almacenar una matriz, sus filas y columnas deben colocarse una tras otra en esa única línea. La elección habitual es el orden row-major (por filas): almacenar cada número de la primera fila, luego cada número de la segunda fila, y continuar hasta que se haya colocado cada fila.
Dos índices, una dirección
La posición de un elemento en una matriz viene dada por dos índices: el índice de fila, que indica a qué fila pertenece, y el índice de columna, que indica a qué columna pertenece. El conteo de ambos comienza en 0, igual que funcionaban los índices en la lección de vectores. La memoria contiene una única secuencia plana de números, por lo que los dos índices deben combinarse primero en un único índice aplanado: multiplicar el índice de fila por el número de columnas de la matriz y luego sumar el índice de columna. A partir de ahí, el índice aplanado se convierte en una dirección de byte de la misma manera que lo hace el índice de un vector: address = base + index * 4.
mul t4, t1, t3 # t4 = índice de fila * número de columnasadd t4, t4, t2 # t4 = that + índice de columna (el índice aplanado)slli t4, t4, 2 # t4 = desplazamiento en bytes = índice * 4add t5, t0, t4 # t5 = dirección del elemento en esa fila y columnalw t5, 0(t5) # t5 = valor en esa dirección
multiplica el índice de fila por el número de columnas. En la lección de vectores la multiplicación podía hacerse con un desplazamiento porque 4 es una potencia de dos, pero el número de columnas de una matriz normalmente no lo es, así que aquí se usa en lugar de . Se suma el índice de columna y el resultado se escala por 4 con otro (4 es una potencia de dos, así que un desplazamiento sigue funcionando para esta parte). Eso produce el desplazamiento en bytes del elemento en la fila y columna dadas.
Fila 0, columna 0 se asigna al índice 0.
.data de tu programa y tu propia lectura de ella imponen sobre esa única línea, usando la aritmética , y mostrada arriba. Una vez que la cuadrícula y la fila aplanada se entienden como una sola cosa mostrada dos veces, el mismo patrón cubre cualquier cuadrícula de datos: las filas de píxeles de una imagen, un tablero de juego o una hoja de cálculo. Cada una es un array, al que se accede con una multiplicación adicional.Suma de una matriz
.datam: .word 1, 2, 3, 4, 5, 6, 7, 8, 9 # matriz 3x3, almacenada fila por fila.textla t0, m # dirección baseli t1, 3 # número de filasli t2, 3 # número de columnasli t3, 0 # índice de fila actual, empieza en 0li s0, 0 # total acumuladorow_loop:beq t3, t1, row_doneli t4, 0 # índice de columna actual, empieza en 0col_loop:beq t4, t2, col_donemul t5, t3, t2 # índice de fila * número de columnasadd t5, t5, t4 # + índice de columna = índice aplanadoslli t5, t5, 2 # desplazamiento en bytes = índice * 4add t6, t0, t5 # dirección del elemento en esa fila y columnalw t6, 0(t6) # valor en esa direcciónadd s0, s0, t6 # total += elementoaddi t4, t4, 1 # avanza a la siguiente columnaj col_loopcol_done:addi t3, t3, 1 # avanza a la siguiente filaj row_looprow_done:mv a0, s0 # imprime el total: 1+2+...+9 = 45li a7, 1ecallli a7, 10ecall
Dos bucles anidados indexan la matriz. El bucle externo selecciona una fila y el bucle interno selecciona una columna dentro de esa fila. multiplica el índice de fila por el número de columnas. Sumar el índice de columna y escalar por 4 da la dirección de ese elemento. El valor almacenado en esa dirección se carga y se suma al total acumulado. Cuando el bucle interno termina una fila, el bucle externo pasa a la siguiente fila, hasta que se hayan procesado las 3 filas.
