Vecteurs : indexation par position
Un vecteur est un tableau : une séquence de nombres stockés les uns à côté des autres en mémoire. Dans la leçon précédente, vous en avez fait la somme en déplaçant un pointeur de 4 octets pour chaque élément. Cette même méthode fonctionne ici. Il existe une autre façon courante d'atteindre un élément : par index. Un index est la position d'un élément comptée depuis le début, où le premier élément a l'index 0, le deuxième a l'index 1, et ainsi de suite.
Somme d'un vecteur en parcourant un pointeur
.dataa: .word 5, 10, 15, 20 # quatre éléments.textla t0, a # t0 = adresse de ali t1, 4 # t1 = nombre d'éléments restantsli t2, 0 # t2 = somme couranteloop:beq t1, zero, donelw t3, 0(t0) # charge l'élément courantadd t2, t2, t3 # ajoute au totaladdi t0, t0, 4 # avance au mot suivant (4 octets)addi t1, t1, -1 # un de moinsj loopdone:mv a0, t2 # affiche le total : 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
La boucle s'exécute comme suit. t0 contient l'adresse de a, et t1 contient le nombre d'éléments restants, en commençant à 4. À chaque passage, termine la boucle lorsque le compteur atteint zéro. charge l'élément à l'adresse contenue dans t0. ajoute cette valeur au total cumulé. avance le pointeur vers le mot suivant. décrémente le compteur. Après quatre passages (5 + 10 + 15 + 20), done affiche 50. C'est le même schéma que celui utilisé dans la leçon sur la mémoire, désormais appliqué à un vecteur.
De l'index à l'adresse
L'indexation calcule une adresse à partir d'un pointeur de base et d'une position : address = base + index * 4. Le 4 est la taille d'un mot en octets. Un compilateur génère ce même calcul pour a[i] dans un langage tel que le C. L'index lui-même n'accède jamais à la mémoire. Seule l'adresse calculée à partir de lui le fait.
slli t5, t3, 2 # t5 = index * 4 (taille d'un mot)add t6, t0, t5 # t6 = adresse de element[index]lw t6, 0(t6) # t6 = element[index]
décale l'index dans t3 de 2 bits vers la gauche, ce qui le multiplie par 4 (deux doublements : 2 x 2), la taille d'un mot. Ajouter le résultat au pointeur de base donne l'adresse de element[index]. Ce décalage est la même méthode des puissances de deux que dans la leçon sur l'arithmétique, et c'est la façon standard de mettre un index à l'échelle par la taille d'un mot.
a[0]: index 0, décalage 0.
i en tant que position, et l'adresse que cette position produit après que l'a mise à l'échelle par 4 et ajoutée à la base. Les nombres hexadécimaux sont les adresses réelles qu'occupe a lorsque le simulateur exécute ce programme. Le but est de prédire l'adresse suivante avant qu'elle n'apparaisse. Cela vous permet de lire dans une boucle incrémentale, ou a[i] dans un langage de type C, et d'imaginer l'adresse mémoire qu'il touche au lieu de traiter la notation comme une boîte noire.Sommer un vecteur par index
.dataa: .word 5, 10, 15, 20 # quatre éléments.textla t0, a # t0 = adresse de base de ali t1, 4 # t1 = nombre d'élémentsli t2, 0 # t2 = index, commence à 0li t3, 0 # t3 = total cumulatifloop:beq t2, t1, doneslli t4, t2, 2 # t4 = index * 4 (décalage en octets)add t5, t0, t4 # t5 = adresse de a[index]lw t5, 0(t5) # t5 = a[index]add t3, t3, t5 # total += a[index]addi t2, t2, 1 # passe à l'index suivantj loopdone:mv a0, t3 # affiche le total : 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
La boucle s'exécute comme suit. t2 est l'index, commençant à 0. À chaque passage, termine la boucle lorsque l'index atteint 4, le nombre d'éléments contenu dans t1. convertit l'index en décalage en octets. ajoute ce décalage à l'adresse de base dans t0 pour produire l'adresse de a[index]. charge la valeur stockée à cet endroit. Cette valeur est ajoutée au total cumulé dans t3, et passe à l'index suivant. Après quatre passages (5 + 10 + 15 + 20), done affiche 50.
Addition de deux vecteurs, élément par élément
.dataa: .word 3, 6, 9, 12 # premier vecteurb: .word 1, 2, 3, 4 # second vecteurc: .space 16 # place pour 4 mots de résultat.textla t0, a # adresse de base de ala t1, b # adresse de base de bla t2, c # adresse de base de cli t3, 0 # index, commence à 0li t4, 4 # nombre d'élémentsli s0, 0 # total courantloop:beq t3, t4, doneslli t5, t3, 2 # décalage en octets = index * 4add t6, t0, t5 # adresse de a[index]lw t6, 0(t6) # valeur de a[index]add a0, t1, t5 # adresse de b[index]lw a0, 0(a0) # valeur de b[index]add t6, t6, a0 # a[index] + b[index]add a0, t2, t5 # adresse de c[index]sw t6, 0(a0) # c[index] = a[index] + b[index]add s0, s0, t6 # total += c[index]addi t3, t3, 1 # passe à l'index suivantj loopdone:mv a0, s0 # affiche le total : 4+8+12+16 = 40li a7, 1ecallli a7, 10ecall
La boucle s'exécute comme suit. convertit l'index t3 en décalage en octets. L'ajouter à chaque pointeur de base (t0, t1, t2) donne les adresses de a[i], b[i] et c[i]. À chaque passage, les deux éléments sont chargés, additionnés, stockés dans c, et ajoutés au total cumulé dans s0. passe à l'index suivant, et la boucle se répète jusqu'à ce que les quatre éléments soient traités.
