Vectores: indexación por posición
Un vector es un arreglo: una secuencia de números almacenados uno junto a otro en memoria. En la lección anterior sumaste uno moviendo un puntero hacia adelante 4 bytes por cada elemento. Ese mismo método funciona aquí. Hay otra forma común de llegar a un elemento: por índice. Un índice es la posición de un elemento contada desde el inicio, donde el primer elemento tiene índice 0, el segundo tiene índice 1, y así sucesivamente.
Suma un vector avanzando un puntero
.dataa: .word 5, 10, 15, 20 # cuatro elementos.textla t0, a # t0 = dirección de ali t1, 4 # t1 = número de elementos restantesli t2, 0 # t2 = suma acumuladaloop:beq t1, zero, donelw t3, 0(t0) # carga el elemento actualadd t2, t2, t3 # suma al totaladdi t0, t0, 4 # avanza a la siguiente palabra (4 bytes)addi t1, t1, -1 # uno menosj loopdone:mv a0, t2 # imprime el total: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
El bucle se ejecuta de la siguiente manera. t0 contiene la dirección de a, y t1 contiene el número de elementos restantes, comenzando en 4. En cada pasada, termina el bucle cuando el contador llega a cero. carga el elemento en la dirección de t0. suma ese valor al total acumulado. avanza el puntero a la siguiente palabra. disminuye el contador. Después de cuatro pasadas (5 + 10 + 15 + 20), done imprime 50. Este es el mismo patrón usado en la lección de memoria, ahora aplicado a un vector.
Del índice a la dirección
La indexación calcula una dirección a partir de un puntero base y una posición: address = base + index * 4. El 4 es el tamaño de una palabra en bytes. Un compilador genera este mismo cálculo para a[i] en un lenguaje como C. El índice en sí nunca accede a la memoria. Solo lo hace la dirección calculada a partir de él.
slli t5, t3, 2 # t5 = índice * 4 (tamaño de una palabra)add t6, t0, t5 # t6 = dirección de element[index]lw t6, 0(t6) # t6 = element[index]
desplaza el índice en t3 dos bits a la izquierda, lo que lo multiplica por 4 (dos duplicaciones: 2 x 2), el tamaño de una palabra. Sumar el resultado al puntero base da la dirección de element[index]. Este desplazamiento es el mismo método de potencias de dos de la lección de aritmética, y es la forma estándar de escalar un índice por el tamaño de una palabra.
a[0]: índice 0, desplazamiento 0.
i como posición, y la dirección que esa posición produce después de que la escala por 4 y la suma a la base. Los números hexadecimales son las direcciones reales que ocupa a cuando el simulador ejecuta este programa. El objetivo es predecir la siguiente dirección antes de que aparezca. Eso te permite leer dentro de un bucle incremental, o a[i] en un lenguaje tipo C, y visualizar la dirección de memoria que toca en lugar de tratar la notación como una caja negra.Sumar un vector por índice
.dataa: .word 5, 10, 15, 20 # cuatro elementos.textla t0, a # t0 = dirección base de ali t1, 4 # t1 = número de elementosli t2, 0 # t2 = índice, comienza en 0li t3, 0 # t3 = total acumuladoloop:beq t2, t1, doneslli t4, t2, 2 # t4 = índice * 4 (desplazamiento en bytes)add t5, t0, t4 # t5 = dirección de a[index]lw t5, 0(t5) # t5 = a[index]add t3, t3, t5 # total += a[index]addi t2, t2, 1 # avanza al siguiente índicej loopdone:mv a0, t3 # imprime el total: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
El bucle se ejecuta de la siguiente manera. t2 es el índice, comenzando en 0. En cada pasada, termina el bucle cuando el índice llega a 4, el número de elementos contenido en t1. convierte el índice en un desplazamiento en bytes. suma ese desplazamiento a la dirección base en t0 para producir la dirección de a[index]. carga el valor almacenado allí. Ese valor se suma al total acumulado en t3, y avanza al siguiente índice. Después de cuatro pasadas (5 + 10 + 15 + 20), done imprime 50.
Suma de dos vectores, elemento por elemento
.dataa: .word 3, 6, 9, 12 # primer vectorb: .word 1, 2, 3, 4 # segundo vectorc: .space 16 # espacio para 4 palabras de resultado.textla t0, a # dirección base de ala t1, b # dirección base de bla t2, c # dirección base de cli t3, 0 # índice, empieza en 0li t4, 4 # número de elementosli s0, 0 # total acumuladoloop:beq t3, t4, doneslli t5, t3, 2 # desplazamiento en bytes = índice * 4add t6, t0, t5 # dirección de a[index]lw t6, 0(t6) # valor de a[index]add a0, t1, t5 # dirección de b[index]lw a0, 0(a0) # valor de b[index]add t6, t6, a0 # a[index] + b[index]add a0, t2, t5 # dirección de c[index]sw t6, 0(a0) # c[index] = a[index] + b[index]add s0, s0, t6 # total += c[index]addi t3, t3, 1 # avanza al siguiente índicej loopdone:mv a0, s0 # imprime el total: 4+8+12+16 = 40li a7, 1ecallli a7, 10ecall
El bucle se ejecuta de la siguiente manera. convierte el índice t3 en un desplazamiento en bytes. Sumarlo a cada puntero base (t0, t1, t2) da las direcciones de a[i], b[i] y c[i]. En cada pasada, ambos elementos se cargan, se suman, se almacenan en c y se añaden al total acumulado en s0. avanza al siguiente índice, y el bucle se repite hasta que se procesan los cuatro elementos.
