Matrizes: dois índices, um endereço
Uma matriz é uma grade de números organizados em linhas e colunas. Uma linha é uma linha horizontal da grade, lida da esquerda para a direita. Uma coluna é uma linha vertical da grade, lida de cima para baixo. A memória não tem conceito de linhas ou colunas. É uma longa sequência de bytes, o mesmo tipo de vetor abordado na lição anterior. Para armazenar uma matriz, suas linhas e colunas devem ser colocadas uma após a outra nessa única sequência. A escolha usual é a ordem row-major: armazenar cada número da primeira linha, depois cada número da segunda linha, e continuar até que todas as linhas tenham sido colocadas.
Dois índices, um endereço
A posição de um elemento em uma matriz é dada por dois índices: o índice de linha, a qual linha ele pertence, e o índice de coluna, a qual coluna ele pertence. A contagem para ambos começa em 0, da mesma forma que os índices funcionavam na lição sobre vetores. A memória contém uma única sequência plana de números, então os dois índices devem primeiro ser combinados em um único índice achatado: multiplique o índice de linha pelo número de colunas da matriz, depois adicione o índice de coluna. A partir daí, o índice achatado se torna um endereço de byte da mesma forma que o índice de um vetor: address = base + index * 4.
mul t4, t1, t3 # t4 = índice da linha * número de colunasadd t4, t4, t2 # t4 = isso + índice da coluna (o índice achatado)slli t4, t4, 2 # t4 = deslocamento em bytes = índice * 4add t5, t0, t4 # t5 = endereço do elemento nessa linha e colunalw t5, 0(t5) # t5 = valor nesse endereço
multiplica o índice de linha pelo número de colunas. Na lição sobre vetores, a multiplicação podia ser feita com um deslocamento porque 4 é uma potência de dois, mas o número de colunas de uma matriz geralmente não é, então é usado aqui em vez de . O índice de coluna é adicionado, e o resultado é escalado por 4 com outro (4 é uma potência de dois, então um deslocamento ainda funciona para essa parte). Isso produz o deslocamento em bytes do elemento na linha e coluna dadas.
Linha 0, coluna 0 corresponde ao índice 0.
.data do seu programa e sua própria leitura dele impõem a essa única linha, usando a aritmética , e mostrada acima. Uma vez que a grade e a linha achatada são entendidas como uma única coisa mostrada duas vezes, o mesmo padrão cobre qualquer grade de dados: as linhas de pixels de uma imagem, um tabuleiro de jogo ou uma planilha. Cada um é um array, alcançado com uma multiplicação extra.Soma de uma matriz
.datam: .word 1, 2, 3, 4, 5, 6, 7, 8, 9 # matriz 3x3, armazenada linha por linha.textla t0, m # endereço baseli t1, 3 # número de linhasli t2, 3 # número de colunasli t3, 0 # índice da linha atual, começa em 0li s0, 0 # total correnterow_loop:beq t3, t1, row_doneli t4, 0 # índice da coluna atual, começa em 0col_loop:beq t4, t2, col_donemul t5, t3, t2 # índice da linha * número de colunasadd t5, t5, t4 # + índice da coluna = índice achatadoslli t5, t5, 2 # deslocamento em bytes = índice * 4add t6, t0, t5 # endereço do elemento nessa linha e colunalw t6, 0(t6) # valor nesse endereçoadd s0, s0, t6 # total += elementoaddi t4, t4, 1 # avança para a próxima colunaj col_loopcol_done:addi t3, t3, 1 # avança para a próxima linhaj row_looprow_done:mv a0, s0 # imprime o total: 1+2+...+9 = 45li a7, 1ecallli a7, 10ecall
Dois loops aninhados indexam a matriz. O loop externo seleciona uma linha e o loop interno seleciona uma coluna dentro dessa linha. multiplica o índice de linha pelo número de colunas. Adicionar o índice de coluna e escalar por 4 dá o endereço desse elemento. O valor armazenado nesse endereço é carregado e adicionado ao total acumulado. Quando o loop interno termina uma linha, o loop externo passa para a próxima linha, até que todas as 3 linhas tenham sido processadas.
