Soluzioni della prova di Assembler del 6 Settembre 2001
Testo degli esercizi
Esercizio 1A
Si programmi la subroutine che implementa la funzione F che calcola:
F(x,y) = (x*x) mod y
- la subroutine deve salvare e ripristinare i registri utilizzati come se si trattasse di una subroutine ricorsiva.
- si usino i registri $a0-$a4 e $v0-$v1 per il passaggio dei parametri e dei risultati
Esercizio 2A
- Siano date due aree di memoria:
- nrig e' una word di valore compreso tra 1 e 20
- matrice e' un'area di half-words sufficiente a contenere una matrice quadrata di nrig righe e colonne
- Si consideri matrice come una matrice organizzata per colonne. Per esempio, se nrig=7:
0 |
7 |
14 |
. |
42 |
1 |
8 |
15 |
. |
43 |
. |
. |
. |
. |
. |
6 |
13 |
20 |
. |
48 |
- Si scriva il programma che:
- contiene le direttive necessarie a definire nrig e matrice
- per ogni colonna J
- calcola il valore I=F(j,nrig)
- lo inserise nell'elemento a riga I.
- Esempio
- se la matrice ha dimensione nrig=7 e siamo alla colonna J=3 il programma deve:
- calcolare I=F(3,7) (che fa 2)
- inserire il valore trovato nell'elemento di colonna 3 e riga I
Esercizio 1B
Si programmi la subroutine che implementa la funzione F che calcola:
F(x,y) = (Somma da 1 a x escluso) mod y
- la subroutine deve salvare e ripristinare i registri utilizzati come se si trattasse di una subroutine ricorsiva.
- si usino i registri $a0-$a4 e $v0-$v1 per il passaggio dei parametri e dei risultati
- La somma va calcolata con un ciclo (non ricorsiva)
Esercizio 2B
- Siano date due aree di memoria:
- nrig e' una word di valore compreso tra 1 e 20
- matrice e' un'area di half-words sufficiente a contenere una matrice quadrata di nrig righe e colonne
- Si consideri matrice come una matrice organizzata per righe. Per esempio, se nrig=7:
0 |
1 |
2 |
. |
6 |
7 |
8 |
9 |
. |
13 |
. |
. |
. |
. |
. |
42 |
43 |
44 |
. |
48 |
- Si scriva il programma che:
- contiene le direttive necessarie a definire nrig e matrice
- per ogni riga I
- calcola il valore J=F(I,nrig)
- lo inserise nell'elemento a colonna J.
- Esempio
- se la matrice ha dimensione nrig=7 e siamo alla riga I=3 il programma deve:
- calcolare J=F(3,7) (che fa 3)
- inserire il valore trovato nell'elemento di riga 3 colonna J
Esercizio 1C
Si programmi la subroutine che implementa la funzione F che calcola:
F(x,y) = (x!) mod y
- la subroutine deve salvare e ripristinare i registri utilizzati come se si trattasse di una subroutine ricorsiva.
- si usino i registri $a0-$a4 e $v0-$v1 per il passaggio dei parametri e dei risultati
- Il fattoriale
x!=1*2*3*4*...*x
va calcolato con un ciclo (non ricorsivo)
Esercizio 2C
- Siano date due aree di memoria:
- nrig e' una word di valore compreso tra 1 e 20
- matrice e' un'area di half-words sufficiente a contenere una matrice quadrata di nrig righe e colonne
- Si consideri matrice come una matrice organizzata per colonne. Per esempio, se nrig=7:
0 |
7 |
14 |
. |
42 |
1 |
8 |
15 |
. |
43 |
. |
. |
. |
. |
. |
6 |
13 |
20 |
. |
48 |
- Si scriva il programma che:
- contiene le direttive necessarie a definire nrig e matrice
- per ogni colonna J
- calcola il valore I=F(j,nrig)
- lo inserise nell'elemento a riga I.
- Esempio
- se la matrice ha dimensione nrig=7 e siamo alla colonna J=3 il programma deve:
- calcolare I=F(3,7) (che fa 2)
- inserire il valore trovato nell'elemento di colonna 3 e riga I
Esercizio 1D
Si programmi la subroutine che implementa la funzione F che calcola:
F(x,y) = (Somma da x a y compresi) mod y
- la subroutine deve salvare e ripristinare i registri utilizzati come se si trattasse di una subroutine ricorsiva.
- si usino i registri $a0-$a4 e $v0-$v1 per il passaggio dei parametri e dei risultati
- La somma va calcolata con un ciclo (non ricorsiva)
Esercizio 2D
- Siano date due aree di memoria:
- nrig e' una word di valore compreso tra 1 e 20
- matrice e' un'area di half-words sufficiente a contenere una matrice quadrata di nrig righe e colonne
- Si consideri matrice come una matrice organizzata per righe. Per esempio, se nrig=7:
0 |
1 |
2 |
. |
6 |
7 |
8 |
9 |
. |
13 |
. |
. |
. |
. |
. |
42 |
43 |
44 |
. |
48 |
- Si scriva il programma che:
- contiene le direttive necessarie a definire nrig e matrice
- per ogni riga I
- calcola il valore J=F(I,nrig)
- lo inserise nell'elemento a colonna J.
- Esempio
- se la matrice ha dimensione nrig=7 e siamo alla riga I=3 il programma deve:
- calcolare J=F(3,7) (che fa 4)
- inserire il valore trovato nell'elemento di colonna J e riga 3
Soluzioni
Soluzione Esercizi A1 B1 C1 D1
Gli esercizi A1 B1 C1 e D1 non differiscono molto,
in comune hanno la parte esterna della funzione con il salvataggio su stack dei registri utilizzati
(nelle soluzioni qua sotto ho usato solo $a0):
f: # f(x,y) con x=$a0 e y=$a1
subu $sp, $sp, 4
sw $a0, 0($sp) # salvo $a0
... # parte diversa per ciascun esercizio (vedi sotto)
lw $a0, 0($sp) # ripristino $a0
addi $sp, $sp, 4
rem $v0, $v0, $a1 # resto della divisione per y
jr $ra # ritorno da subroutine
La parte diversa per ciascun esercizio,
da NON fare ricorsivamente (vedi testo) e', ad esempio:
Es. A | Es. B | Es. C | Es. D |
# x*x
mul $v0, $a0, $a0
|
# somma da 1 a x inclusi
li $v0, 0
ciclo: add $v0, $v0, $a0
sub $a0, $a0, 1
bgz $a0, ciclo
|
# x!
li $v0, 1
ciclo: mul $v0, $v0, $a0
sub $a0, $a0, 1
bgz $a0, ciclo
|
# somma da x a y escluso
li $v0, 0
ciclo: add $v0, $v0, $a0
addi $a0, $a0, 1
ble $a0, $a1, ciclo
|
Soluzione Esercizi A2 B2 C2 D2
I 4 esercizi sono identici a parte lo scambio della parola "righe" con "colonne"
(e corrispondentemente, I con J).
Una possibile soluzione e':
.data # inizio dichiarazioni blocco dati
nrig: .word 20 # numero di righe
matrice: .half 0:400 # matrice di 20x20=400 half words
.text # inizio blocco programma
.globl main # l'etichetta di partenza si chiama "main"
main:
li $t0, 2 # costante 2 (dimensione in bytes di una half-word)
li $a0, 1 # inizializzo l'indice di riga (colonna)
lw $a1, nrig # inizializzo il parametro y di f(x,y)
ciclo:
jal F # chiamo la funzione F
sub $t2, $a0, 1 # numero di righe precedenti
mul $t1, $t2, $a1 # numero di elementi delle righe precedenti
add $t1, $t1, $v0 #---+ numero di elementi della riga corrente
mul $t1, $t1, $t0 # moltiplico per 2 (si tratta di half-words)
sh $v0, matrice($t1) # memorizzo il valore (e' una half-word!)
addi $a0, $a0, 1 # incremento il numero di riga (colonna)
ble $a0, $a1, ciclo # se non sono finite le righe (colonne) continuo
li $v0, 10 # fine del programma
syscall
--
AndreaSterbini - 12 Sep 2001