Esercitazione di Ing. Gian Luca Corso di Laurea in Ingegneria Elettronica Capitolo 5 Linguaggio Assembly Richiami: v[i] e &v[i] v[i] è il valore dell elemento i nel vettore v; &v[i] è il suo indirizzo. In generale, possiamo usare v come label per indicare la locazione di memoria che corrisponde all indirizzo del primo elemento di v, ovvero &v[0]. Per passare da &v[i] a &v[i+1] dobbiamo incrementare &v[i] di 4 byte (vedi organizzazione della memoria nel MIPS). Indirizzo Valore &v[0] v 1024 v[0] 1 &v[1] v+4 1028 v[1] -1 &v[2] v+8 1032 v[2] 3 2 Organizzazione della memoria Organizzazione della memoria La memoria è organizzata in locazione da 32 bit (4 byte). Per questo motivo indirizzi adiacenti in memoria distano 4 byte. In figura, i byte da 0 a 3 rappresentano una locazione di memoria! Es. il valore di un elemento di un vettore (v[i]) occupa una locazione di memoria, quindi è memorizzato su 4 byte. Aligned Not Aligned 0 1 2 3 QuickTime e un decompressore TIFF (LZW) sono necessari per visualizzare quest'immagine. 3 4
Esercizio 1 Mostrare la singola istruzione MIPS o la sequenza minima di istruzioni per i seguenti costrutti C: a = b + 100; x[10] = x[11] + c; Si assuma che a corrisponda al registro $11, b al registro $12, c a $13, e che il vettore x inizi alla locazione di memoria espressa, in base dieci, 1024. addi $11, $12, 100 # a = b + 100; # x[10] = x[11] + c; addi $16, $0, 11 # $16 11 muli $15, $16, 4 # $15 11*4 lw $14, 1024($15) # $14 x[11] add $14, $14, $13 # $14 x[11 ] + c subi $15, $15, 4 # $15 10*4 sw $14, 1024($15) # x[10] $14 (x[11]) $11 a $12 b $13 c &x[0]: 1024 5 6 Esercizio 2 Analisi del codice step-by-step Caricare nel registro $16 la seguente costante di 32 bit: 0000 0000 0011 1100 0000 1001 0000 0001 : (0000 0000 0011 1100) 2 = (60) 10 16 bit più significativi della costante (0000 1001 0000 0001) 2 = (2305) 10 16 bit meno significativi della costante $16 $16 1. move $16, $0 0000 0000 0000 0000 0000 0000 0000 0000 2. lui $16, 60 0000 0000 0011 1100 0000 0000 0000 0000 Utilizzando l istruzione lui è assai semplice: move $16, $0 lui $16, 60 addi $16, $16, 2305 $16 3. addi $16, $16, 2305 0000 0000 0011 1100 0000 1001 0000 0001 7 8
Esercizio 3 Tradurre in Assembly MIPS il seguente frammento di programma C: while(save[i]==k) i = i + j; Si assuma che $19 i, $10 4, $20 j, $21 k. 1 Loop: mul $9, $19, $10 # $9 i*4 lw $8, save($9) # $8 save[i] bne $8, $21, Exit # se $8!= $21, Exit # (altrimenti continua) add $19, $19, $20 # i = i+j; j Loop Exit: Implementare la stesso codice C usando solo un istruzione di salto (condizionato o no) $19 i $10 4 $20 j $21 k 9 10 2 Esercizio 4 Loop: mul $9, $19, $10 # $9 i*4 lw $8, save($9) # $8 save[i] add $19, $19, $20 # i = i+j; beq $8, $21, Loop # se $8==$21, cont. sub $19, $19, $20 # i=i-j Devo decrementare i all uscita del ciclo. Naturalmente, altre soluzioni (corrette) sono benvenute $19 i $10 4 $20 j $21 k Tradurre in Assembly il seguente codice C: for (i=0; i<=100; i++) a[i] = b[i] + c; Si assuma che: &a[0] locazione 1500; &b[0] locazione 2000; c $16 Si inizializzi la variabile i(*4) nel registro $15 11 12
Usiamo $17 per controllare la condizione di uscita del ciclo: se i == 404, esci. For: addi $17, $0, 404 move $15, $0 lw $14, 2000($15) #x=b[i]; add $14, $14, $16 #x=x+c; sw $14, 1500($15) #a[i]=x; addi $15, $15, 4 #i=i+4; bne $15, $17, For subi $15, $15, 4 $15 i*4 $16 c a: 1500 b: 2000 Esercizio 5 Scrivere un frammento di programma Assembly MIPS che effettui la somma degli elementi di un vettore di n interi. somma=0; for(i=0; i<n; i++) somma += x[i]; Assunzioni: somma $8; i $9 n $2; &x[0] $3; x[i] $10 Vincolo: si scriva la soluzione utilizzando SOLO i registri indicati 13 14 Esercizio 6 For: Exit: move $8, $0 move $9, $0 beq $9, $2, Exit lw $10, 0($3) add $8, $8, $10 addi $3, $3, 4 addi $9, $9, 1 j For Scrivere una funzione Assembly MIPS che, ricevendo in ingresso un intero, ne restituisca il valore assoluto. int abs(int valore) { if(valore<0) return -valore; else return valore; valore $4; il valore di ritorno viene inserito in $5 15 16
Abs: subi $29, $29, 4 slt $8, $4, $0 bne $8, $0, Then move $5, $4 j Exit Then: sub $5, $0, $4 Exit: lw $8, 0($29) addi $29, $29, 4 jr $31 # $8 (valore<0) Esercizio 7 Implementare in Assembly MIPS il seguente codice C: int proc(int g, int h, int i, int j) { int f; f = (g + h) (i + j); return f; g, h, i, j siano allocati nei registri $4-$7 f venga restituito in $4 Il salvataggio dei parametri avviene secondo la tecnica callee save 17 18 Si possono usare due registri $9 e $10 per collocare i dati temporanei (g + h) e (i + j). Salvataggio del contesto (parametri/registri): Proc: subi $29, $29, 8 sw $10, 4($29) sw $9, 0($29) Il corpo della procedura è dunque: add $9, $4, $5 add $10, $6, $7 sub $4, $9, $10 Ripristino dei parametri e ritorno al chiamante: lw $10, 4($29) lw $9, 0($29) addi $29, $29, 8 jr $31 19 20
alternativa Senza usare alcun registro temporaneo: Proc: add $4, $4, $5 #f=g+h sub $4, $4, $6 #f=f-i sub $4, $4, $7 #f=f-j jr $31 Esercizio 8 Implementare la seguente funzione C in Assembly: int min(int v[], int n) { int i, min_v; min_v = v[0]; for(i=1; i<n; i++) if(v[i]<min_v) min_v=v[i]; return min_v; Assumere che il salvataggio dei parametri avvenga con modalità callee save &v[0] $4, n $5 Il valore di ritorno viene immagazzinato nel registro $6 21 22 : salvataggio del contesto Assumiamo che le variabili locali siano allocate secondo la seguente configurazione: (i<n) $8; (v[i]<min_v) $9 i $10; v[i] $11 Il salvataggio dei parametri richiede le istruzioni: Min: addi $29, $29, -16 sw $9, 4($29) sw $10, 8($29) sw $11, 12($29) : corpo della procedura lw $6, 0($4) move $10, $0 For: addi $10, $10, 1 slt $8, $10, $5 beq $8, $0, Exit addi $4, $4, 4 lw $11, 0($4) slt $9, $11, $6 beq S9, $0, For move $6, $11 j For Exit: (ripristino dei parametri) 23 24
: procedura completa Esercizio 9 Min: addi $29, $29, -16 sw $9, 4($29) sw $10, 8($29) sw $11, 12($29) lw $6, 0($4) move $10, $0 For: addi $10, $10, 1 slt $8, $10, $5 beq $8, $0, Exit addi $4, $4, 4 lw $11, 0($4) slt $9, $11, $6 beq S9, $0, For move $6, $11 j For Exit: lw $11, 12($29) lw $10, 8($29) lw $9, 4($29) lw $8, 0($29) addi $29, $29, 16 jr $31 Scrivere una funzione Assembly MIPS che implementi il seguente codice C. Si assuma che: &x[0] locazione 1000, N $4, &y[0] locazione 2000, M $5. int positivi(int N) { int i,m; M=0; for (i=0; i<n; i++) if(x[i]>0) { y[m]=x[i]; M++; return M; 25 26 Utilizziamo i seguenti registri: $8 i; $9 (i*4); $10 x[i]; $11 (x[i]>0) $12 (M*4) Ciò richiede il preventivo salvataggio del parametri: positivi: subi $29, $29, 20 sw $9, 4($29) sw $10, 8($29) sw $11, 12($29) sw $12, 16($29) For: Exit: move $5, $0 move $8, $0 beq $8, $4, Exit muli $9, $8, 4 lw $10, 1000($9) slt $11, $0, $10 addi $8, $8, 1 beq $11, $0, For muli $12, $5, 4 sw $10, 2000($12) addi $5, $5, 1 j For (Ripristino dei parametri) 27 28
Esercizio 10 Scrivere una funzione che, ricevendo in ingresso un vettore v, un intero x e la dimensione di v, indicata con N, restituisca la posizione di x in v, se presente, altrimenti restituisca il valore -1. &v[0] $4, x $5, N $6 Valore di uscita $7 int posizione(int v[], int x, int N) { int i; for(i=0; i<n; i++) if(v[i]==x) return i; return -1; $8 i; $9 v[i]; $2-1; $10 (i<n). Salvataggio parametri: posizione: addi $29, $29, -16 sw $2, 0($29) sw $8, 4($29) sw $9, 8($29) sw $10, 12($29) 29 30 : corpo della funzione alternativa For: Exit: move $7, $2 move $8, $0 beq $8, $6, Exit lw $9, 0($4) addi $4, $4, 4 addi $8, $8, 1 bne $9, $5, For subi $7, $8, 1 (Ripristino del contesto) $8 v[i] posizione: subi $29, $29, 4 move $7, $0 #$7 i=0 For: lw $8, 0($4) #$8 v[i] beq $8, $5, Exit #v[i]==x, esci addi $7, $7, 1 #i++ addi $4, $4, 4 #calcola &v[i] bne $7, $6, For #i!=n, cicla addi $7, $0, -1 #i==n, set $7-1 Exit: lw $8, 0($29) addi $29, $29, 4 31 32
Altri esercizi 1. Scrivere un programma Assembly MIPS che, dato un array di cento interi memorizzato a partire dalla locazione 1000, ne effettui una copia a partire dalla locazione 2000. 2. Scrivere un programma Assembly MIPS che, dato un array di cento interi memorizzato a partire dalla locazione 1000, costruisca a partire dalla locazione 2000 l'array dei soli elementi non negativi. 3. Scrivere un programma Assembly MIPS che, dato un array di cento interi memorizzato a partire dalla locazione 1000, costruisca a partire dalla locazione 2000 l'array dei soli elementi negativi. Altri esercizi (cont d) 4. Scrivere un programma Assembly MIPS che, dato un array di cento interi memorizzato a partire dalla locazione 1000, costruisca a partire dalla locazione 2000 l'array dei soli elementi positivi. 5. Scrivere un programma Assembly MIPS che, dato un array di cento interi memorizzato a partire dalla locazione 1000, ne costruisca a partire dalla locazione 2000 un array ordinato. 6. Scrivere un programma Assembly MIPS che calcoli la media degli elementi di un vettore di N interi. 33 34