Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Calcolo della prossima potenza di A
A-Aadd.s $f3, $f2, $f3 #1^ modo
1+(A-A)add.s $f4, $f2, $f1
1+Asub.s $f4, $f4, $f1 #2^ modo
(1+A)-Ac.eq.s $f3, $f4
li controlla se sono uguali
bc1f errore
se l'ugualianza è falsa si salta all'etichetta
mul.s $f1, $f1, $f0
altrimenti calcola la prossima potenza di A con cui lavorare
j ciclo
errore: j errore
se si fa il calcolo con l'8 potenza si nota un particolare:
quando si fa la somma in parentesi ossia (1+A) è stato oggetto di un errore perché quando si sommano due numeri in virgola mobile per poter sommare le mantisse bisogna prima traslare il numero più piccolo di un numero di posizioni che renda congruente il peso associato ad ogni cifra. Traslando 1 di tante posizioni quante servono per poter sommare in decimale 10^8, ha portato a perdere un 1 portando ad avere che in $f4 il risultato che si ottiene è 0 e non 1, perché (1+A) è diventato uguale ad A ed A-A=0 portando ad avere (si vedano fp3 e fp4), portando ad avere un
confronto poi conc.eq.s$f3
, $f4
che è falso e ci fa saltare all'etichetta errore perché non è stata soddisfatta la condizione di uguaglianza.
Quindi:
# Risultato dell'esecuzione:
# fino alla 7-ma potenza di A produce risultati che sono uguali
# come si sa 10^7 richiede 24 bit che sono esattamente quelli che servono
# per rappresentare la mantissa 23 bit + 1 dell'hidden bit.
# All'8-va potenza (10^8 richiede 28 bit) l'incolonnamento
# necessario per gli addendi richiederebbe la traslazione
# di 28 bit per l'"1" (il primo addendo riportato nella formula (1+A)-A):
# troppi per i 24 bit della mantissa che sono (23 + 1)
# quindi ciò che è successo è che traslando il numero più piccolo per
# equiparare i pesi abbiamo perso il bit meno significativo del numero più piccolo
# e non siamo riusciti a sommare 1 e non aver sommato 1 ha comportato a un errore
# producendo un risultato incongruente.
# Esso era un altro
<h2>esempio per tenere conto di mantenere una massimaattenzione per i numeri in virgola mobile.</h2>
<p>Programma che permette di riconoscere gli effetti<br>
dell'arrotondamento nelle somme iterate.<br>
Il ciclo accumula iterativamente un valore:<br>
se il valore in base 2 è periodico il risultato,<br>
viene arrotondato.<br>
Il programma, ogni 4 somme effettuate, confronta<br>
il risultato con lo stesso valore teorico ottenuto<br>
però come prodotto per 4.<br>
Uso dei registri:<br>
t0 puntatore area con i valori di partenza; t1 = conta<br>
le somme; f1= addendo; f2 = somma parziale, parte da zero;<br>
f3 = 4 usato per calcolare e mettere in f5 il secondo<br>
fattore per calcolare il prodotto in f4; t3 conta 20<br>
coppie di valori diversi da inviare alla console.</p>
<pre>
<code>
.data 0x10010200
num: .float 0.0, 1.1, 4.0
new: .asciiz "\n"
.text 0x400200
la $t0, num
li $t3, 20
#contatore coppie di valori al maxvisualizzabili
li $t1, 4
#n° somme da voler effettuare
lwc1 $f2, ($t0)
lwc1 $f1, 4($t0)
mov.s $f4, $f1
lwc1 $f3,
8($t0)mov.s $f5, $f3
somma: add.s $f2, $f2, $f1
addi $t1, $t1, -1
bne $t1, $zero, somma
mul.s $f4, $f1, $f5
add.s $f5, $f5, $f3
#ci serve aggiornare il fattore moltiplicativo
li $t1, 4
#reimpostato per poter effettuare la somma 4 volte
c.eq.s $f2, $f4
bc1f cons
j somma
cons: li $v0, 2 #print float
mov.s $f12, $f2
syscall
li $v0, 4 #print string: a capo
la $a0, newline
syscall
li $v0, 2 #print float
mov.s $f12, $f4
syscall
li $v0, 4 #print string: a capo
la $a0, newline
syscall
addi $t3, $t3, -1
bne $t3, $zero, somma
#per fare visualizzazioni
end: j end
#1.1 è un numero periodico che vede ripetersi 1100 all'infinito.
#Se vedo la mantissa del numero ho:
#L'ultimo valore non è c ma è d perché si hanno 2 bit aggiuntivi alla mantissa detti guardia ed arrotondamento che sono posti a 11 perché il numero è di continuo 1100 e termina con 00 e i successivi 2 bit sono 11 ed essendo questi appunto aggiuntivi ai bit della mantissa e posti a 11 si comprende che il migliore arrotondamentosarà fatto al valore superiore quindi verso + infinito e quindi compare d perché si è approssimati lievemente in eccesso per ridurre l'errore di rappresentazione. Le approssimazioni fatte durante la somma hanno cumulato un piccolo errore che nel binario che rappresenta la realtà di rappresentazione i valori sono differenti. Non sempre l'arrotondamento è in eccesso per le somme e in difetto per le sottrazioni.
DOMANDE ESAME:
1) Si descrivano i problemi relativi al passaggio dei parametri nel caso di richiamo di sottoprogrammi e le convenzioni previste per le funzioni realizzate dai registri del processore MIPS, anche in considerazione della necessità di preservare/ non preservare le informazioni. In particolare, nel caso di richiamo di sottoprogrammi, si presenti e si commenti il coinvolgimento dello stack e dei registri ra, sp.
Risposta: i registri sono una risorsa pregiata, quindi tanto più si usano bene tanto più risolviamo in fretta.iproblemi perchè sono pochi e sono nella cpu, ossia sono particolar modo veloci da accedere, leistruzioni che fanno uso dei registri fanno tutti i calcoli nei registri e abbiamo tutta la convenienzanel mettere nel loro interno quello che serve e ho lo spilling che è la tecnica con la quale quando soche una cosa viene usata di rado è inutile lasciare un registro bloccato lo riverso in memoria.A questo si lega la convenzione di uso dei registri.Il concetto è che se ho una chiamata al sottoprogramma il main program che si compone di unaserie di istruzione per lavorare si appoggia su una serie di registri, anche un altro sottoprogrammache voglio raggiungere si appoggia sui registri.La soluzione che funziona è che dico che permetto a chiunque di usare qualsiasi registro ma talesoluzione ha un piccolo svantaggio perché nel momento in cui si dice salta da un programma a unaltro questo non può usare i registri allegramente perché quandosi torna al punto di partenza il punto di partenza si trova dei valori cambiati che erano dei valori con la quale la esecuzione doveva procedere. Ci aspettiamo un contenitore che serva per poter passare da chi chiama a chi viene chiamato i parametri di riferimento e uno per restituire il risultato. Ad esempio, immagino un sottoprogramma che calcola il seno. Per dire "calcola il seno", devo dire quale è l'angolo e tale programma restituisce il valore. Ho i registri argomento a0-a3 che servono per passare le informazioni che devono essere elaborate. I registri valore v0-v1 sono il tramite attraverso il quale restituire l'informazione. Se i registri non bastano, bisogna usare la memoria. Ad esempio, se voglio trasferire un intero vettore, non c'è un registro che tenga per fare ciò. In tal caso, bisogna appoggiarsi alla memoria, ma dobbiamo dire a chi deve gestire tale vettore che tale vettore dove sta, di quanti elementi si compone e ciò lo faccio con i registri ad.es ho un registro che dice dove inizia l'area un altro che dice quanto è grande l'area e stesso discorso vale anche per la restituzione del risultato. Nel MIPS è stabilita la convenzione d'uso dei registri per cercare di minimizzare i travasi in memoria e le letture per ridurre i tempi. Potrei dire chiunque può usare tutto ma se così si fa tutto deve essere salvato nel momento in cui si va in un sottoprogramma. Per attenuare tale problema è introdotta la convenzione d'uso dei registri che dice i registri s sono liberamente usabili dal main program, i t dal sottoprogramma. Se siamo fortunati gli s ci bastano per il main, per il t ci bastano per il singolo sottoprogramma da eseguire tale da non dover accedere alla memoria. Ma non sempre è così, posso dire uso t nel main program ma ho un pericolo perché quando arriverò nel punto dove sto per richiamare un sottoprogramma so che esso tali registri t li può cambiare.allora effettuo WRITE dei registri che so di usare contro la regola chiamosottoprogramma che fa i calcoli che deve e quando deve essere restituito il controllo faròl’operazione di READ dei dati che sono stati salvati in memoria tale da ripartire con la certezza che it che il sottoprogramma che cmq potrebbe aver cambiato li ho messi in memoria e li ho recuperati.Tale discorso vale in maniera duale per il sottoprogramma dove posso usare dei registri s se ne hola necessità ma ho l’obbligo di scriverli in memoria e recuperarli per restituirli a chi l’ha chiamatocome sono stati ricevuti (push e pop).Ma se ho un sottoprogramma 2 ulteriore al quale il sottoprogramma 1 deve richiamare, il 2 puòcambiare tutti i t che vuole che deve essere tenuto conto quindi prima di fare la chiamata saràcompito del chiamante dover salvare e poi ripristinare.Chi chiama si cautelerà dal perdere le informazioni inserendo in memoria tutto ciò che staUsando eche sa che può essere chiamato, se ad es sto usando da t0 a t3 e non sto usando da t4 a t9 quindi quelli che non uso non li salvo. C'è comunque il rischio di fare salvataggi inutili. Su chi grava la responsabilità di salvare? Su chi viene chiamato perché si salvano solo quelli che si suppone vengano modificati, altrimenti chi chiama dovrebbe salvarli tutti. In VM non ci sono convenzioni e quindi se fosse il main a salvare dovrebbe salvare tutti i registri.
2) Si descriva il funzionamento dell'istruzione lui. Le pseudoistruzioni li e la fruiscono dell'istruzione lui. Risposta: nel formato immediato non abbiamo la possibilità di avere 32 bit nel campo operandi. Lui fa un caricamento della parte alta di un numero a 16 bit e azzera i bit bassi, è utile per caricare una costante; se voglio caricare una costante intera devo usare 2 istruzioni, con lui metto apposto la parte alta ed azzero la bassa con la ori modifico la parte bassa.
lasciando inalterata laparte alta.Siamo avvantaggiati perché l’ambiente di collaudo ci autorizza ad usare una rosa di pseudoistruzionili, la;tali comandi ci autorizzano a scrivere li $t0, 0x12345678 un numero che richiede 32 e sarà compitodell’assemblatore spezzare in 2 e caricare la parte alta e la bassa.Abbiamo una migliore usabilità dei comandi ma il vincolo di 32 bit c’è comunque.Le cifre esadecimali da mettere sono 8 perché ogni cifra valore 4 bit.Si discuta la differenza nel modo in cui vengono tradotte dall’assemblatore nelle vere istruzioni delprocessore MIPS le 3 pseudoistruzioni seguenti:
- la $a0, itinere
- ...