| |
Il progetto dsy.it è l'unofficial support site dei corsi di laurea del Dipartimento di Scienze dell'Informazione e del Dipartimento di Informatica e Comunicazione della Statale di Milano. E' un servizio degli studenti per gli studenti, curato in modo no-profit da un gruppo di essi. I nostri servizi comprendono aree di discussione per ogni Corso di Laurea, un'area download per lo scambio file, una raccolta di link e un motore di ricerca, il supporto agli studenti lavoratori, il forum hosting per Professori e studenti, i blog, e molto altro...
In questa sezione è indicizzato in textonly il contenuto del nostro forum |
Preparazione al Laboratorio F49 Clicca QUI per vedere il messaggio nel forum |
uLori |
Ciao ragazzi, mi devo preparare per sostenere a gennaio la parte di laboratorio dell esame per informatica f49.
Qualcuno saprebbe indicarmi dove trovare il materiale giusto per la preparazione? e magari un esempio delle procedure ricorsive che sono richieste nelle nuova modalità di esame?
Grazie 1000 |
pintu |
idem..qualcuno sta seguendo le lezioni per caso?? |
pintu |
@vivian.souza: hai gia sostenuto la parte di laboratorio?? |
uLori |
nessuno sà darci un esempio di esame di laboratorio? :( |
aPiso |
Io ho fatto laboratorio per F1X quindi non so aiutarvi, se sul sito non c'è nulla secondo me la cosa migliore è provare a mandare una mail al dottor Codara. |
uLori |
io ho guardato il sito e ci sono gli esempi del laboratorio..ma è un sacco di codice io spero non sia da fare così tanto.. |
CowBoy |
Io questo esame l'ho dato tanto tempo fa... era molto semplice perché le richieste non erano poi fuori dal mondo:
- variabili assembly
- chiamate a funzione (i vari jump)
- gestione di chiamata a funzione ricorsiva (gestione dello stack)
- somme, sottrazioni, moltiplicazioni, divisioni (matematica di base)
- mascheramento di variabili (operatori binari AND, OR, XOR, SHIFT)
... e qualcos'altro
Svolgendo gli esercizi di laboratorio nel ambiente SPIM (simulatore MIPS) vi andrà via tutta questa ansia da prestazione.
MA DOVETE SCRIVERE VOI LA SOLUZIONE!!! NON CERCATE DI SCOPIAZZARE ALTRIMENTI SARA' TUTTO TEMPO PERSO! IMPEGNATEVI E ANDRÀ TUTTO LISCIO. :D
In bocca al lupo! |
vivian.souza |
@pintu sì l'ho sostenuto a luglio. L'esame consiste nella stesura di una procedura ricorsiva in linguaggio assembly MIPS - senza main, soltanto la procedura. Per esempio, la risoluzione dell'esame di giugno:
alfa = gamma(n) - beta(alfa(n-1))
alfa:
addi $sp, $sp, -12 #alloco spazio per salvare l'indirizzo di ritorno e altre variabile
sw $ra, 8($sp) #salvo l'indirizzo di ritorno
sw $a0, 4($sp) #salvo il valore originale di n
beq $a0, $zero, fine #se a0(n) = 0, salto a fine (caso base)
jal gamma #altrimenti chiamo la procedura gamma
sw $v0, 0($sp) #salvo il risultato di gamma
lw $a0, 4($sp) #carico in a0 il valore originale di n
addi $a0, $a0, -1 #decrementa a0 di 1 (n - 1)
jal alfa #chiamo la procedura alfa
move $a0, $v0 #a0 <- v0 (risultato della procedura alfa)
jal beta #chiamo la procedura beta
lw $t0, 0 ($sp) #carico in t0 il risultato della procedura gamma
sub $v0, $t0, $v0 #v0 = risultato di gamma - risultato di beta
lw $ra, 8($sp) #carico in ra l'indirizzo di ritorno salvato sullo stack
addi $sp, $sp, 12 #realloco lo stack nella sua posizione originale
jr $ra #ritorno al chiamante
fine:
addi $sp, $sp, 12 #realloco lo stack
li $v0, 0 #caso base, ritorno 0
jr $ra |
uLori |
la richiesta era solo alfa = gamma(n) - beta(alfa(n-1)) ?
non avendo ancora studiato mi risulta difficile capire cosa si richide.. |
vivian.souza |
scusami... vediamo Alfa è la funzione che tu deve risolvere creando una procedura. Alfa richiama se stessa e una seconda procedura chiamata beta che sappiamo a priore che esiste ma non ci importa che cosa veramente faccia, la dobbiamo soltanto chiamare e prendere il suo risultato per risolvere alfa.
Per un esempio di enunciato simile a questo suggerisco prendere le tracce dei progetti che sono ancora disponibili nel sito, sono tutti simili. Più tarderà proverò a trovare l'enunciato completo di questo problema perché adesso sono in uni... |
uLori |
nessuno sà altro riguardo questo esame?! |
uLori |
stò provando a capire qualcosa, ma gli esercizi di esempio non mi sono chiari come faccio ad arrivare al risultato. ad esempio questo:
Si consideri la coppia di sequenze denite da
(1) F(n) = n - M(F(n - 1)) ;
(2) M(n) = n - F(M(n - 1)) ;
con valori iniziali
(3) F(0) = 1 ;
(4) M(0) = 0 :
Scrivere un programma per il calcolo dei valori di F(n) e M(n). Il programma
dovra contenere due procedure: una per il calcolo di F(n) e una per il calcolo di
M(n). Il programma principale si occupera della lettura di un numero n >= 0 da
tastiera, del calcolo di F(n) e M(n) e della visualizzazione del risultato. |
CowBoy |
Allora:
code:
#include <stdio.h>
int F( int a );
int M( int b );
int main( void )
{
int n = 0;
printf("Inserire un numero intero n >= 0: ");
scanf("%d", &n);
printf("\nIl risultato della funzione F è: %d\n", F(n));
printf("Il risultato della funzione M è: %d\n", M(n));
return 0;
}
int F( int a )
{
int n = a;
if (n == 0)
return 1;
else
return n - M(F(n-1));
}
int M ( int b )
{
int n = b;
if (n == 0)
return 0;
else
return n - F(M(n-1));
}
Chiaro, no?! |
uLori |
il codice è chiaro..ma il calcolo matematico che avviene non lo capisco..
ad esempio se metto n=3
F(3) = 3 - M(F(3-1))
M(3) = 3 - F(M(3-1))
come si arriva ad un risultato? |
CowBoy |
Avvengono diverse chiamate tra le funzioni F e M, ricorsivamente. Se vuoi puoi effettuare delle modifiche al codice (in C) per stampare le chiamate e vedere cosa accade durante l'esecuzione.
code:
1: F(3) = 3 - M(F(2)) (mettilo nello stack e chiama 2)
2: F(2) = 2 - M(F(1)) (mettilo nello stack e chiama 3)
3: F(1) = 1 - M(1) (mettilo nello stack e chiama 4)
4: M(1) = 0 (ritorna il risultato a 3, e rimettilo in esecuzione)
5: F(1) = 1 (ritorna il risultato a 2, e rimettilo in esecuzione)
6: F(2) = 2 - M(1) (mettilo nello stack e chiama 7)
7: M(1) = 0 (ritorna il risultato a 6, e rimettilo in esecuzione)
8: F(2) = 2 (ritorna il risultato a 1, e rimettilo in esecuzione)
9: F(3) = 3 - M(2) (mettilo nello stack e chiama 10)
10: M(2) = 2 - F(M(1)) (mettilo nello stack e chiama 11)
11: M(1) = 1 - F(0) (ritorna il risultato a 10, e rimettilo in esecuzione)
12: M(2) = 2 - 1 (ritorna il risultato a 9, e rimettilo in esecuzione)
13: F(3) = 3 - 1 = 2!!!
Ta-da, provare M(3) per credere! |
pintu |
Sui computer del laboratorio per l'esame cosa viene usato? PCSpim? |
uLori |
ragazzi qualche altro esempio di tema d'esame? così da esercitarsi con altri esercizi oltre a quelli di esempio sul sito..
grazie! :) |
aPiso |
Originally posted by pintu
Sui computer del laboratorio per l'esame cosa viene usato? PCSpim?
Ahaha sarebbe bello eh?
Per le esercitazioni si usa MARS, che è meglio di PC Spim a mio avviso, e per l'esame di laboratorio puoi solo riempire una casella di testo su JLI, non puoi far girare il codice per vedere se funziona, deve venirti in prima botta o comunque te lo devi eseguire con carta e penna per fare un controllo... |
pintu |
ah quindi praticamente consegno un file di testo e poi se la vedono loro? Sarà perchè non ho ancora studiato ma le esercitazioni che ci sono sul sito non sono x niente chiare! Anche l'esercizio che ha postato uLori..come sarebbe risolto in assembly?? |
pintu |
Oppure questo..qualcuno è cosi paziente da provare a risolverlo?? :)
Si realizzi un programma per il calcolo della potenza. Il programma dovra:
(1) leggere da tastiera due numeri interi a; b 0;
(2) visualizzare in output la potenza ab.
Il programma deve contenere una apposita procedura power che riceve in ingresso
due parametri (a e b) e restituisce il valore calcolato ab.
Si ricorda che devono essere rispettate le convenzioni descritte a lezione. |
uLori |
Originally posted by pintu
ah quindi praticamente consegno un file di testo e poi se la vedono loro? Sarà perchè non ho ancora studiato ma le esercitazioni che ci sono sul sito non sono x niente chiare! Anche l'esercizio che ha postato uLori..come sarebbe risolto in assembly??
la risoluzione del esercizio in assembly c'è sul sito del prof..comunque ora sto iniziando a capire e fidati non è poi così difficile :)
le cose importanti sono:
-all inizio preparare lo stack pointer con il numero di spazi in base alle variabili che userai + quelle che ti servono sempre come $ra e $a0
e fai così: addi $sp, $sp, -12 (-12 lasc lo spazio per 3 dati)
sw $ra , 8($sp) salvi il registro di ritorno
sw $a0, 4($sp) salvi il dato $a0 che è il dato passato dal esercizio di solito n
-poi devi ricordati che quando fai una Jal, una chiamata ad una funzione, questa prende in ingresso sempre il dato salvato in $a0 e ti dà il risultato in uscita sempre nel registro $v0
-poi alla fine devi sempre caricare il registro di ritorno
lw $ra, 8($sp) lo carichi dalla posizione 8 xkè era li che lo avevi salvato
poi rigeneri lo stack pointer
addi $sp,$sp,12
fai un salto al registro di ritorno
JR $ra
e l'esericizio finisce :) |
CowBoy |
I miei complimenti uLori... è così che si fa!
Ciao |
pintu |
scusa uLori ma dato che non è richiesto il main, se per esempio devo risolvere l'esercizio dell'esponente, devo preoccuparmi di allocare lo stack con indirizzi di ritorno ecc o basta che mi limito a scrivere la procedura richiesta?? nel senso..nelle soluzioni proposte sul sito (se escludiamo il main) la soluzione richiesta all'esame dovrebbe essere questa:
power:
li $v0, 1
ciclopower:
beq $a1, $0, finepower
andi $t0, $a1, 1
beq $t0, $0, salta
mul $v0, $v0, $a0
addi $a1, $a1, -1
salta:
mul $a0, $a0, $a0
div $a1, $a1, 2
j ciclopower
finepower:
jr $ra # ritorno al chiamante
oppure no??
Dato che non devo neanche far girare il codice ma scrivere semplicemente un file di testo potrebbero anche accontentarsi :D :D |
uLori |
mi sà che ci vedremo all esame di gennaio :)
comunque il main non lo dovremo scrivere però l'allocazione e la preparazione dello stack si..ma è facile e ripetitivo :D |
pintu |
se riesco a prepararmi credo di si! Quando sarebbe l'appello? |
uLori |
Originally posted by pintu
se riesco a prepararmi credo di si! Quando sarebbe l'appello?
la data ancora non c'è, dobbiamo iscriverci sul sifa.. |
gab217 |
Originally posted by uLori
la data ancora non c'è, dobbiamo iscriverci sul sifa..
Esce tutto sul sifa? |
uLori |
Originally posted by gab217
Esce tutto sul sifa?
penso di si, leggendo sul sito del prof dice che serve l'iscrizione al sife per fare l'esame di laboratorio e poter verbalizzare. quindi penso prima o poi uscirà. per ora c'è solo quello di borghese.. |
gab217 |
Originally posted by uLori
penso di si, leggendo sul sito del prof dice che serve l'iscrizione al sife per fare l'esame di laboratorio e poter verbalizzare. quindi penso prima o poi uscirà. per ora c'è solo quello di borghese..
Ok perchè ancora non trovo riferimenti in merito |
uLori |
già...come facciamo per iscriverci e sapere quando è questo esameee?? |
pintu |
Sul SIFA non c'è un tubo mannaggia! Ma mettere un avviso sul sito del corso no eh??? Ragazzi mi confermate che l'esame consiste solo nella scrittura di una procedura ricorsiva?? E che il tutto va fatto in un file di testo, senza bisogno di far girare il codice?? |
uLori |
ciao, si si io sono stato dal prof qualche mese fà e anche lui mi ha confermato..bisogna solo scrivere la procedura ricorsiva senza main quindi deduco che sia impossibile da provare.. non sò se magari il main lo fà lui e lo prova o lo corregge leggendo il codice.. |
pintu |
Misteri dell'esame di architettura :D Comunque...non mi è chiara una cosa...
li $v0 1
syscall
in questo modo si richiede la print_int? L'ho preso dalle esercitazioni che ci sono sul sito.. Ma non dovrei passare un intero come argomento tramite il registro $a0?? Perchè, sempre dalle esercitazioni --->
msg1: .asciiz "stringa"
li $v0 4 #chiamata a print_string
la $a0 msg1 #carico indirizzo di msg1 in $a0
syscall |
uLori |
ma io non credo questo serva saperlo...i vari print non avvengono nella parte della procedura ricorsiva ma nel main..almeno credo.. |
pintu |
Si l'ho pensato anche io però non si sa mai :) Non ci sono altri esercizi o esempi di procedure ricorsive?? E poi un'altra cosa...Si può usare la pseudoistruzione 'move' o va sostituita con qualcos'altro?? |
uLori |
altri esercizi non sò, ma qui non c'è nessuno che ha già fatto questo esame e sà dirci gli esercizi che sono stati dati??
l'istruzione move si la puoi usare anche perchè senza non saprei come fare.. :) |
pintu |
eh infatti! :)
si comunque davvero... già il sito non è che dica molto..delle info su data e modalità d'esame non diciamo niente che è meglio! Possibile che su 775 visualizzazioni nessun'altro abbia già sostenuto questo esame?? :( |
pintu |
Sto provando a fare l'esercizio che ha postato uLori..
F(n) = n - M(F(n - 1))
M(n) = n - F(M(n - 1))
con F(0) = 1 e M(0) = 0
La funzione F dovrebbe essere cosi..
F: addi $sp $sp -8 #alloco spazio per variabil
sw $a0 0($sp) #salvo il valore di n
sw $ra 4($sp) # salvo il return address
beq $a0 $zero fineF #se n=0 salto a fineF
subi $a0 $a0 1 # n = n -1
jal F #chiamo di nuovo F
add $a0 $zero $v0 #metto il risultato di F in $a0 per passarlo come parametro alla funzione M
jal M
.
.
.
fineF: addi $v0 $zero 1
lw $a0 0($sp)
lw $ra 4($sp)
addi $sp $sp 8
jr $ra
Dopo la jal M mi sono perso :( qualcuno riesce ad aiutarmi?? |
uLori |
secondo me prima di tutto ti conviene fare i casi base
F: bne $a0, $zero, calc_f
li $v0, 1
jr $ra
calc_f: addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp)
addi $a0,$a0, -1
jal F
move $a0, $v0
jal M
lw $a0, 0($sp)
sub $v0,$a0, $v0
lw $ra, 4($sp)
addi $sp,$sp, 8
jr $ra
e poi per M è tutto uguale...
ma allora si sà quando è l'esame? |
pintu |
Grazie per la risposta! Comunque ancora niente..ho mandato una mail a Dantona (venerdi sera) ma non ha ancora risposto..spero in domani! |
aPiso |
le print ti può servire sapere cosa fanno perchè nell'esercizio "capire il codice" ci sono spesso e anche se ci arrivi lo stesso sapere prima cosa fanno aiuta :P
Dantona qualche volta non risponde...io l'ho sempre braccato in Comelico!! |
pintu |
Ma non devo solo preoccuparmi della funzione ricorsiva?? Questo esame sta diventando sempre di più un mistero o.O |
pintu |
Mi sorge un dubbio, forse stupido.. Suppongo di avere come input n = 2, quindi chiamo per la prima volta la fuzione F. Eseguo la branch che mi fa saltare a calc_f, alloco lo spazio sullo stack e salvo $a0 ( = 2) e $ra ( che contiene l'indirizzo dell'istruzione successiva alla chiamata di F), e decremento $a0 di 1 (quindi $a0 = 1).
A questo punto richiamo di nuovo F, con input $a0 = 1 giusto? La branch mi fa saltare nuovamente a calc_f, alloco nuovamente lo spazio, salvo $a0 e $ra ecc..
La mia domanda è... Questo stack che sto allocando, non centra niente con la prima chiamata che avevo fatto ma si riferisce solamente a QUESTA chiamata di F giusto? E inoltre..il valore di $a0 che ora è 1...vale solo in QUESTA chiamata? |
gab217 |
Ancora niente sulla data dell'esame ? |
pintu |
No! Dantona ha bellamente ignorato la mia mail e rischio di dover pure rifare l'orale! |
gab217 |
Sono uscite le date. |
uLori |
ma sul sifa non c'è ancora l'appello per iscriversi... |
gab217 |
Originally posted by uLori
ma sul sifa non c'è ancora l'appello per iscriversi...
No, non lo vedo per ora ci sono solo le date |
gab217 |
Originally posted by gab217
No, non lo vedo per ora ci sono solo le date
Qualcuno ha qualche es da postare in preparazione?
Grazie. |
uLori |
ecco un bel esercizio:
E(n, k) = (n − k + 1)E(n − 1, k − 1) + kE(n − 1, k) ,
con condizioni iniziali
(2) E(n, 1) = 1 , e
(3) E(n, k) = 0 , per k > n .
Per esempio,
E(3, 2) = 2E(2, 1) + 2E(2, 2) = 2 + 2E(1, 1) + 4E(1, 2) = 2 + 2 + 0 = 4
come si cestiscono 2 dati? uno è in $a0 e l'altro in $a1 ? |
gab217 |
Qst era un vecchio progetto che io avevo risolto chiamando la procedura e passando n e k rispettivamente in a0 e a1 |
gab217 |
Originally posted by uLori
ok grazie ;)
ulori scusa una cosa tu hai fatto tutti i vecchi progetti? |
uLori |
fatti no, ho preso solo le procedure ricorsive per esercitarmi per il laboratorio :) |
gab217 |
Originally posted by uLori
fatti no, ho preso solo le procedure ricorsive per esercitarmi per il laboratorio :)
Ma hai guardato solo quelli più recenti? |
uLori |
quelli di codara, se vai troppo indietro ho visto che cambia il prof, c'era un certo Marra e le procedure erano decisamente più difficili |
gab217 |
Originally posted by uLori
quelli di codara, se vai troppo indietro ho visto che cambia il prof, c'era un certo Marra e le procedure erano decisamente più difficili
Si esatto volevo proprio sapere questo. |
uLori |
io sono stato da codara a dicembre e gli ho fatto vedere alcuni esercizi che usavo per prepararmi e gli ho chiesto se anche i prossimi esami saranno simili e lui mi ha detto di si.
quindi se sappiamo fare i suoi ultimi proetti come q-numbers per esempio dovremmo essere a posto :)
una domanda. sai se esiste un comando per fare la moltiplicazione e la divisione immediata con un numero come è per la addi?
oppure và messo il numero in un registro temporaneo e poi fare la mult o div ? |
gab217 |
Che io sappia no per entrambe serve sempre un registro temporaneo |
gab217 |
Originally posted by uLori
quelli di codara, se vai troppo indietro ho visto che cambia il prof, c'era un certo Marra e le procedure erano decisamente più difficili
Per caso hai provato anche altre procedure ricorsive al di fuori del sito del prof? |
uLori |
no solo quelle del prof, spero l'esame segua sempre la stessa linea di procedure e di problemi non ce ne saranno |
gab217 |
Originally posted by uLori
no solo quelle del prof, spero l'esame segua sempre la stessa linea di procedure e di problemi non ce ne saranno
Ok, ti chiedo anche un'altra cosa all'interno della procedura segui una logica nello scegliere trai registri $s0 e $t0? |
uLori |
di registri $s non ne ho mai usati.
perchè quando preparo lo stack pointer lascio sempre uno spazio in più per salvare li i risultati parziali, che poi quando mi servono richiamo mettendoli in $t0 al momento di fare il conto |
gab217 |
Originally posted by uLori
di registri $s non ne ho mai usati.
perchè quando preparo lo stack pointer lascio sempre uno spazio in più per salvare li i risultati parziali, che poi quando mi servono richiamo mettendoli in $t0 al momento di fare il conto
Ti ringrazio per il chiarimento. Perchè in alcuni es già risolti vedevo che venivano usati anche i registri $s* ma pure io solitamente utilizzo solo quelli temporanei |
pintu |
L'esame è domani giusto? Chi lo sostiene può postare poi il testo dell'esercizio? Grazie :) |
uLori |
testo dell esame f49 del 30/1/2012:
P(n,h)=P(n-1,h)+P(n-h-1,h) se n>h+1;
P(n.h)=n+1,altrimenti. |
gab217 |
Originally posted by uLori
testo dell esame f49 del 30/1/2012:
P(n,h)=P(n-1,h)+P(n-h-1,h) se n>h+1;
P(n.h)=n+1,altrimenti.
Ma per verbalizzare, qualcuno sa come funziona? |
uLori |
Originally posted by gab217
Ma per verbalizzare, qualcuno sa come funziona?
piacerebbe saperlo pure a me, io ho scritto una mail al prof d'antona l'altro giorno ma non mi ha ancora risposto...aspettiamo... |
gab217 |
Originally posted by uLori
piacerebbe saperlo pure a me, io ho scritto una mail al prof d'antona l'altro giorno ma non mi ha ancora risposto...aspettiamo...
Siamo in due, ho scritto pure io al prof. |
uLori |
ha risposto il prof? a me no... uff |
gab217 |
Originally posted by uLori
ha risposto il prof? a me no... uff
No ancora no, appena risponde ti aggiorno per ora no. |
gab217 |
Originally posted by uLori
ha risposto il prof? a me no... uff
uLori a te per caso ha risposto? A me ancora niente. |
uLori |
no niente...prima ho scritto al prof codara..vediamo se almeno lui dice qualcosa |
uLori |
codara mi ha risposto subito, mi ha detto di di parlare con d'antona che prima o poi mi risponderà, o di passare nel suo ufficio lunedì o mercoledì pomeriggio che forse c'è.. |
gab217 |
Originally posted by uLori
no niente...prima ho scritto al prof codara..vediamo se almeno lui dice qualcosa
Nel caso fammi sapere.
Grazie |
uLori |
finalmente ha risposto, mi ha detto di passare mercoledì o giovedì pomeriggio senza dirmi un orario preciso.. |
gab217 |
Originally posted by uLori
finalmente ha risposto, mi ha detto di passare mercoledì o giovedì pomeriggio senza dirmi un orario preciso..
Si confermo ha risposto anche a me. |
pintu |
Ragazzi com'è andato poi l'esame? |
uLori |
Originally posted by uLori
testo dell esame f49 del 30/1/2012:
P(n,h)=P(n-1,h)+P(n-h-1,h) se n>h+1;
P(n.h)=n+1,altrimenti.
questo è il testo dell esame...io ho preso 26 e comunque in generale è andato bene solo 1 bocciato |
pintu |
grazie mille per averlo postato uLori :) io non ho potuto darlo perchè sono dovuto stare dietro ad algoritmi.. alla fine la modalità era quella che si diceva? Hai una casella di testo in cui scrivere il codice, senza compilatori ecc? |
pintu |
PS: scusami 26 è il voto di lab o la media con il voto di orale? |
uLori |
esatto nessun compilatore..si scrive del normalissimo testo come se si facesse su carta :) |
uLori |
ho preso 26 sia al lab che all'orale...la media vien facile ;) |
pintu |
Grazie delle info ;) spero di farcela l'esame è lunedi e inizio ora a prepararmi! Oggi provo a fare l'esercizio dell'appello poi magari lo posto e approfitto della tua pazienza per una correzione rapida :) |
uLori |
ok non c'è problema...comuqne se leggi indietro avevo fatto un post con i punti base da sapere.. |
uLori |
Originally posted by uLori
la risoluzione del esercizio in assembly c'è sul sito del prof..comunque ora sto iniziando a capire e fidati non è poi così difficile :)
le cose importanti sono:
-all inizio preparare lo stack pointer con il numero di spazi in base alle variabili che userai + quelle che ti servono sempre come $ra e $a0
e fai così: addi $sp, $sp, -12 (-12 lasc lo spazio per 3 dati)
sw $ra , 8($sp) salvi il registro di ritorno
sw $a0, 4($sp) salvi il dato $a0 che è il dato passato dal esercizio di solito n
-poi devi ricordati che quando fai una Jal, una chiamata ad una funzione, questa prende in ingresso sempre il dato salvato in $a0 e ti dà il risultato in uscita sempre nel registro $v0
-poi alla fine devi sempre caricare il registro di ritorno
lw $ra, 8($sp) lo carichi dalla posizione 8 xkè era li che lo avevi salvato
poi rigeneri lo stack pointer
addi $sp,$sp,12
fai un salto al registro di ritorno
JR $ra
e l'esericizio finisce :) |
pintu |
sisi avevo letto quando mi stavo preparando per gennaio e mi è stato utilissimo per capire il funzionamento base.. ora sono un pò arrugginito devo rimettermi a pari per lunedi :) |
pintu |
Ho provato a fare questo esercizio:
P(n, h) = P(n-1, h) + P(n-h-1, h) se n > h+1
P(n, h) = n+1 altrimenti
Provo a postare il codice anche se so per certo che è sbagliato, e ho un paio di dubbi da sciogliere!
P: addi $sp, $sp, -12 #spazio per 3 variabili
sw $ra, 0($sp) #salvo il registro di ritorno
sw $a0, 4($sp) #$a0 = n
sw $a1, 8($sp) #$a1 = h
addi $s0, $a1, 1 #$s0 = h + 1
bgt $a0, $s0, calc_P #se n > h+1 salta a calc_P
addi $a0, $a0, 1 # n = n + 1
lw $v0, $a0 # risultato = n + 1
jr $ra
calc_P: subi $a0, $a0, 1 #n = n-1
jal P #chiamo P(n-1, h)
sub $a0, $a0, $a1 #n = n - h
subi $a0, $a0, 1 #n = n -1
jal P #chiamo P(n-h-1, h)
lw $a0, 4($sp) #ripristino reg $a0
lw $ra, 0($sp) #ripristino return address
lw $a1, 8($sp) #ripristino reg $a1
addi $sp, $sp, 12 #ripristino stack
jr $ra
Dubbio (1) : Dato che la funzione ha due parametri n, h è giusto passarli come ho fatto io tramite i registri $a0, $a1?
Dubbio (2) : Prima di calcolare la funzione devo eseguire il test per vedere se n > h + 1. Va bene mettere il valore di h+1 nel registro $s0? Oppure potevo incrementare direttamente $a1 ( che contiene h) ?
Dubbio (3) : Se la mia funzione (cosi come l'ho scritta) mette sempre il risultato in $v0 non potrò mai avere il risultato giusto poichè devo sommare il risultato di P(n-1, h) a quello di P(n-h-1, h). Come posso fare? |
uLori |
1) si n verrà salvato in $a0 e h in $a1 però lo stack lo devi preparare da 16 e non 12 perchè devi lasciare un altro spazio proprio per salvare i risultati parziali che come nel punto 3 dici di non saper dove mettere
2) io ho incrementato $a1 per il test. i registra $s non li ho mai usati per nessun esercizio
3) come detto prima, per salvare i risultati parziali devi mettere il contenuto di $v0 nello stack così: sw $v0, 0($sp) in questo caso è zero perchè l'ultimo spazio libero per esempio..poi dipende da dove salvi i vari $a0,$ra ecc..
poi per ricaricare quel valore per fare il conto usi lw $t0, 0($sp)
vai a ricaricarlo in una variabile temporanea $t0 recuperandola dallo spazio 0 dello stack |
pintu |
Ma devo caricare $v0 nello stack al'inizio della procedura quando carico gli altri registri, oppure solo quando ho il risultato parziale? Madò che confusione :( |
pintu |
Una cosa..se io per eseguire il test incremento direttamente $a1 ($a1 = h), quando poi vado a chiamare P(n-1, h) , h non avrà più il suo valore originario ma sarà h = h+1 no? quindi in teoria è sbagliato.. |
pintu |
Ho fatto due modifiche ma non sono ancora sicuro!
P(n, h) = P(n-1, h) + P(n-h-1, h) se n > h+1
P(n, h) = n+1 altrimenti
P: addi $sp, $sp, -16 #spazio per 3 variabili
sw $ra, 0($sp) #salvo il registro di ritorno
sw $a0, 4($sp) #$a0 = n
sw $a1, 8($sp) #$a1 = h
sw $v0, 12($sp) #salvo reg $v0 <------
addi $a1, $a1, 1 #$s0 = h + 1 <--------
bgt $a0, $a1, calc_P #se n > h+1 salta a calc_P
addi $a0, $a0, 1 # n = n + 1
move $v0, $a0 #metto n+1 in $v0 <------------
jr $ra
calc_P: subi $a0, $a0, 1 #n = n-1
jal P #chiamo P(n-1, h)
lw $t0, 12($sp) #risultato parziale in $t0 <-----------------
sub $a0, $a0, $a1 #n = n - h
subi $a0, $a0, 1 #n = n -1
jal P #chiamo P(n-h-1, h)
add $v0, $v0, $t0 #sommo i risultati parziali <--------------
lw $a0, 4($sp) #ripristino reg $a0
lw $ra, 0($sp) #ripristino return address
lw $a1, 8($sp) #ripristino reg $a1
lw $v0, 12($sp) #ripristino reg $v0 <-----------------
addi $sp, $sp, 16 #ripristino stack
jr $ra |
uLori |
no $v0 è un registro non devi preparare lo stack salvandolo xkè all inizio è vuoto..
fai così
addi $sp, $sp, -16 #spazio per i 2 val passati, 1 per i ris temp, e 1 per il reg di ritorno
sw $ra, 0($sp) #salvo il registro di ritorno
sw $a0, 4($sp) #$a0 = n
sw $a1, 8($sp) #$a1 = h
lasi la posizione 12 dello stack pointer per salvare il valore contenuto in $v0 successivamente dopo che avrai fatto i calcoli e $v0 conterrà qualcosa |
pintu |
ah ok ho capito grazie, sempre gentilissimo! :) per quanto rigurada $t0 invece posso usarlo tranquillamente senza doverlo mettere nello stack perchè è un registro temporaneo giusto? |
uLori |
si esatto $t0 usalo come vuoi, ma ricorda che dura solo fino alla prima jal poi perde il valore...quindi ti conviene caricare un valore in $t0 per poi usarlo subito per un calcolo.. |
pintu |
quando o se hai tempo puoi postare la tua soluzione? o comunque come lo risolveresti? |
uLori |
io l'ho risolto così, non è prefetto perchè se no avrei preso 30 ma comunque almeno la base c'è :
P: addi $a1,$a1,1 #h+1
blt $a0,$a1,fine #salto se n<h a fine
addi $sp,$sp,-16
sw $ra,12($sp)
sw $a0,8($sp)
sw $a1,4($sp)
addi $a0,$a0,-1 #n-1
jal P
sw $v0,0($sp) #salvo il risultato nello stack
lw $a0,8($sp) #ricarico n originale
lw $a1,4($sp) #ricarico h
addi $a1,$a1,-1 #h-1
sub $a0,$a0,$a1 #n-h
lw $a1,4($sp) #ricarico h originale
jal P
lw $t0,4($sp) #carico il ris della prima parte di procedura
add $v0,$v0,$t0 #effettuo la somma conclusiva
lw $ra,12($sp)
addi $sp,$sp,16
jr $ra
fine: addi $a0,$a0,1 #n+1
jr $ra |
pintu |
Sperando sia utile a qualcuno, posto il testo dell'esame di oggi 27/02:
M(n) = 3*M(n-1) - 2*M(n-2) se n > 3
M(n) = 2^(n+4) - 20 altrimenti |
|
|
|
|