Pages: 1 ... 22 23 [24]   Go Down
Print
Author Topic: AA 2010-2011: Quesiti a risposta aperta  (Read 83832 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
Gladior
Matricola
*
Offline Offline

Posts: 87


« Reply #345 on: 05-09-2012, 18:05:19 »

Esercizio : metodo ricorsivo fattoriale

.main
.var
fatt
risul
.end-var
BIPUSH 5
ISTORE fatt
LDCW OBJREF
ILOAD fatt
INVOKEVIRTUAL fatt
ISTORE risul
ILOAD risul
OUT
.end-main

.method fatt(a)
.var
fatt
.end-var
LDCW OBJREF
ILOAD a
BIPUSH 1
IFICMPEQ base
ILOAD a
BIPUSH 1
ISUB
INVOKEVIRTUAL fatt
ISTORE fatt
ILOAD a
ILOAD fatt
IMUL
ireturn
base:
          BIPUSH 1
          IRETURN
.end-method
Mi sembra sostanzialmente corretto, a meno di due correzioni, una di forma, l'altra di sostanza.
Forma: la sintassi IJVM prevede il codice operativo simbolico LDC_W, non LDCW.
Sostanza: l'istruzione LDC_W OBJREF nel metodo fatt(a) dovrebbe essere spostata tre righe più avanti: va infatti eseguita solo se subito dopo si carica lo stack con i parametri e quindi si invoca un metodo; ora, nel caso in cui il test IFICMPEQ abbia esito positivo, si salta a base senza invocare alcun metodo, e dunque aver caricato anche in questo caso OBJREF nello stack produce un'alterazione erronea del contenuto di SP.
Per quanto riguarda la sintassi il simulatore riconosce LDCW e non LDC_W (errore)
Per quanto riguarda la sostanza non avevo considerato il fatto che il metodo non si richiamase nemmeno una volta nel caso in cui il fattoriale sia uguale a 1! quindi risulta inutile caricare objref sullo stack è alterare inutilmente il contenuto di SP
quindi abbiamo
.main
.var
fatt
risul
.end-var
BIPUSH 5
ISTORE fatt
LDCW OBJREF
ILOAD fatt
INVOKEVIRTUAL fatt
ISTORE risul
ILOAD risul
OUT
.end-main

.method fatt(a)
.var
fatt
.end-var
ILOAD a
BIPUSH 1
IFICMPEQ base
LDCW OBJREF
ILOAD a
BIPUSH 1
ISUB
INVOKEVIRTUAL fatt
ISTORE fatt
ILOAD a
ILOAD fatt
IMUL
ireturn
base:
          BIPUSH 1
          IRETURN
.end-method
Logged
Gladior
Matricola
*
Offline Offline

Posts: 87


« Reply #346 on: 05-09-2012, 18:26:30 »

Questo è un esercizio simile a quello che richiede di scrivere un metodo ricorsivo per il fattoriale.
Ho svolto l'esercizio nel caso in cui non è richiesto un metodo ma un semplice codice IJVM che calcoli il fattoriale,nel caso specifico il programma risulta essere eccessivamente lungo?
È evidente che il programma è molto più lungo del necessario.
Quote
Ho fatto in modo che  il valore del primo BIPUSH  corrisponde al fattoriale da calcolare.
Il programma funziona il mio dubbio è nel caso in cui mi dovrebbe capitare un esercizio del genere nel compito sarebbe valutato eccesivamente lungo?
Potrebbe darmi qualche dritta per ridurre il numero di istruzioni ovviamente nel caso specifico ? Magari prossimamente postero il metodo ricorsivo utilizzando l'istruzione IMUL.
Ho visto che ne ha prodotto due versioni, suppongo che la seconda rimpiazzi la prima, guarderò pertanto solo quest'ultima. Quanto alla presente soluzione, non ricorsiva, ho la netta sensazione che la fonte di prolissità del programma stia nell'idea che l'uso dell'istruzione IMUL sia lecito solo nella soluzione ricorsiva. Non è così: si può produrre un calcolo non ricorsivo del fattoriale mediante un ciclo di moltiplicazioni, in una macchina che disponga della moltiplicazione, più o meno come si calcola il prodotto mediante un ciclo di addizioni in una macchina che non disponga dell'istruzione di moltiplicazione. Va bene come dritta?

.constant
OBJREF 0x10
.end-constant
.main
.var
fatt
risul
.end-var
LDCW OBJREF
IN
ISTORE fatt
ILOAD fatt
INVOKEVIRTUAL fattoriale
ISTORE risul
ILOAD risul
OUT
HALT
.end-main

.method fattoriale(fatt1)
.var
cont
.end-var
ILOAD FATT1
ISTORE CONT
CICLO: ILOAD CONT
            BIPUSH1
            ISUB
            ISTORE CONT
            ILOAD CONT
            ILOAD FATT1
            IMUL
            ISTORE FATT1
            ILOAD CONT
            IFEQ FINE
            GOTO CICLO
FINE: ILOAD FATT1
         IRETURN
.end-method

Quando ho scritto il codice non ho considerato volutamente l'istruzione IMUL era un modo per esercitarmi.

« Last Edit: 05-09-2012, 18:30:22 by Gladior » Logged
Giuseppe Scollo
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 1.507


« Reply #347 on: 06-09-2012, 17:03:37 »

imul1  MAR=SP=SP-1;rd
imul2  H=0//AZZERA SOMMA PARZIALE
imul3  H=H+MDR//INCREMENTA PRODOTTO PARZIALE
imul4  TOS=TOS-1;if(Z) goto imul5 ; else goto imul3       
imul5  MDR=TOS=H;wr;goto Main1//PUSH SULLO STACK DEL RISULTATO , AGGIORNO TOS E SALTO ALLA MICROROUTINE DI FETCH
Che succede se il parametro in cima allo stack, ovvero anche il contenuto iniziale di TOS, vale 0?
Logged
Giuseppe Scollo
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 1.507


« Reply #348 on: 06-09-2012, 17:10:21 »

Per quanto riguarda la sostanza non avevo considerato il fatto che il metodo non si richiamase nemmeno una volta nel caso in cui il fattoriale sia uguale a 1!
OK, ma noti che questo accade sempre (cioè, per qualsiasi valore iniziale del parametro) esattamente una volta, cioè quando la sequenza di invocazioni ricorsive giunge all'invocazione finale.
Logged
Gladior
Matricola
*
Offline Offline

Posts: 87


« Reply #349 on: 06-09-2012, 17:56:30 »

imul1  MAR=SP=SP-1;rd
imul2  H=0//AZZERA SOMMA PARZIALE
imul3  H=H+MDR//INCREMENTA PRODOTTO PARZIALE
imul4  TOS=TOS-1;if(Z) goto imul5 ; else goto imul3      
imul5  MDR=TOS=H;wr;goto Main1//PUSH SULLO STACK DEL RISULTATO , AGGIORNO TOS E SALTO ALLA MICROROUTINE DI FETCH
Che succede se il parametro in cima allo stack, ovvero anche il contenuto iniziale di TOS, vale 0?
Nel caso specifico credo che la condizione non sia mai soddisfatta cioè TOS=TOS-1 cioè 0=0-1 cioè TOS=-1, quindi la modifica da opportare è la seguente.
imul1  MAR=SP=SP-1;rd
imul2  H=0//AZZERA SOMMA PARZIALE
imul3  H=H+MDR//INCREMENTA PRODOTTO PARZIALE
imul4  Z=TOS ;if(Z) goto imul6 ; else goto imul5     
imul5 TOS=TOS-1; goto imul3
imul6  MDR=TOS=H;wr;goto Main1//PUSH SULLO STACK DEL RISULTATO , AGGIORNO TOS E SALTO ALLA
« Last Edit: 06-09-2012, 18:05:44 by Gladior » Logged
Giuseppe Scollo
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 1.507


« Reply #350 on: 10-09-2012, 14:23:44 »

la modifica da opportare è la seguente.
imul1  MAR=SP=SP-1;rd
imul2  H=0//AZZERA SOMMA PARZIALE
imul3  H=H+MDR//INCREMENTA PRODOTTO PARZIALE
imul4  Z=TOS ;if(Z) goto imul6 ; else goto imul5     
imul5 TOS=TOS-1; goto imul3
imul6  MDR=TOS=H;wr;goto Main1//PUSH SULLO STACK DEL RISULTATO , AGGIORNO TOS E SALTO ALLA
Non mi pare che il risultato sia sempre corretto. Se il parametro in cima allo stack vale 0, ma l'altro parametro vale n > 0, che risultato dà?
Logged
Pages: 1 ... 22 23 [24]   Go Up
Print
Jump to: