Sei sulla pagina 1di 13

APPUNTI E LINEE GUIDA

PER GLI ESERCIZI

DI

CALCOLATORI ELETTRONICI

Yuri Gaito
APPUNTI ASSEMBLER
-Allocare variabili globali

 Interi
1) int a; a: .space 4
2) int a = 10; a: .word 10
 Caratteri
1) char c; c: .space 1
2) char c = 'h'; c: .byte 'h'
 Vettori
1) int vett [N]; vett: .space N*4
2) int b[] = {0, 1, 2, 3, 4}; b: .word 0, 1, 2, 3, 4
3) int b[] = {3, 3, 3, 3, 3}; b: .word 3:5
4) char vett[N]; vett : .space N
5) char b*+ = ,‘a’,’b’,’c’-; b: .byte ‘a’, ‘b’, ‘c’ oppure b: .ascii “abc”
 Matrici
1) int mat [i][j]; mat: .space (i*j)*4
2) char mat [i][j]; mat: .space i*J
 Stringhe
1) str = "Nuova stringa"; str: .asciiz "Nuova stringa \n"

-Allocare vettori non globali


1) Se l'area statica è vuota:
 lui $s3, 0x1000 # l'indirizzo base del vettore sarà in $s3, ovvero in 0x10000000
2) Se l'area statica non è vuota:
 lui $s3, 0x1000
 ori $s3, $s3, 0x(codifica esadecimale array precedente) # Se per esempio ho già
allocato un array di 32 interi (32x4 = 128) scriverò ori $s3, $s3, 0x0080
-Load e Store

1) lw $t0, OFFSET($t1) # Trasferisce nel registro $t0 la parola di memoria all’indirizzo


$t1+OFFSET
2) sw $t0, OFFSET($t1) # Trasferisce il contenuto del registro $t0 nella locazione di memoria
con indirizzo
$t1+OFFSET

-Accedere all'elemento di un vettore

 Vettore di caratteri (char str[])


1) add $t4, $t2, $s1 # i + indirizzo base, $t2 = i e $s1 = &str
2) lw $t4, 0($t4) # elemento i-esimo di str

 Vettore di interi (int vett[])


1) sll $t5, $t2, 2 # i*4
2) add $t5, $t5, $s0 # i + indirizzo base, $t2 = i e $s0 = &vett
3) lw $t5, 0($t5) # elemento i-esimo di vett
1
-Accedere all'elemento di una matrice
Le matrici non sono altro che dei vettori linearizzati.
1) (i*c)+j # c = numero di colonne
2) i+(j*r) # r = numero di righe

 Matrice di interi (int mat[][])


1) mult $t0,$s2 # $t0 contiene i, $s2 contiene c
2) mflo $t2 # i*c
3) add $t2,$t2,$t1 # i*c+j, $t1 contiene j
4) sll $t2,$t2,2 # (i*c+j)*4
5) add $t4,$s1,$t2 # indirizzo base matrice + (i*c+j)*4, $s1 = &mat, in $t4 c'è l'indice
dell'elemento i,j

-Ciclo FOR

for (i=0; i < dim; i++){ .....


}
1) Inizializzare l'indice sw $zero, 0($t1) # i = 0 dove $t1 contiene i
2) Mettere etichetta FOR
3) Prelevo il valore di i dalla memoria lw $t2, 0($t1)
4) La prima operazione che viene effettuata in un for è il controllo della condizione di
fine ciclo
 slt $t4, $t2, $t3 # i < dim dove $t3 contiene dim
 beq $zero, $t4, fine_for
5) Eseguire le operazioni richieste
6) Incremento l'indice addi $t2, $t2, 1
7) Aggiorno l'indice sw $t2, 0($t1)
8) Ricomincio da capo j FOR

-Gestione dell'I/O

1) Si chiama il sistema operativo (syscall) e si specifica l'operazione che deve essere


effettuata

Azione Istruzione Registri coinvolti


Print_integer li $v0,1 $a0 = integer
Print_string li $v0,4 $a0= string
Read_integer li $v0,5 integer in $v0
Read_string li $v0,8 $a0= buffer $a1=length
Exit li $v0,10 -
Print_char li $v0,11 $a0= char
Read_char li $v0,12 char in $a0

2
-Passaggio dei parametri tramite Stack

 Procedura Chiamante
1) Salvataggio dei registri modificabili $ti che contengono qualcosa che servirà in seguito
 Acquisire le risorse necessarie sullo stack addi $sp, $sp, -X
 Copiare i parametri nello stack usando l'istruzione di store
2) Salvataggio dei parametri da passare
 Acquisire le risorse necessarie sullo stack addi $sp, $sp, -X
 Copiare i parametri nello stack usando l'istruzione di store
3) Trasferire il controllo alla procedura jal nome_procedura

 Procedura Chiamata
1) Salvare sullo stack i registri non modificabili $si che si vogliono utilizzare e il registro $ra
se verrà chiamata un'altra procedura
 Acquisire le risorse necessarie sullo stack addi $sp, $sp, -X
 Copiare i registri nello stack usando l'istruzione di store
2) Prelevare i parametri passati dallo stack usando l'istruzione di load
3) Esecuzione del compito richiesto
4) Ripristinare lo stato dei registri non modificabili
 Copiare i registri dallo stack usando l'istruzione di load
 Liberare le risorse acquisite sullo stack addi $sp, $sp, X
5) Inserire il valore di ritorno sullo stack usando l'istruzione di store
6) Ritornare al programma chiamante jr $ra

 Procedura Chiamante
1) Prelevare il risultato dallo stack usando l'istruzione di load
2) Liberare lo spazio acquisito sullo stack per copiare i parametri addi $sp, $sp, X

-Passaggio dei parametri tramite Registri

 Procedura Chiamante
1) Salvataggio dei registri modificabili $ti che contengono qualcosa che servirà in seguito
 Acquisire le risorse necessarie sullo stack addi $sp, $sp, -X
 Copiare i parametri nello stack usando l'istruzione di store
2) Salvataggio dei parametri da passare
3) Inserire i parametri nei registri $ai sw $?, 0($ai)
4) Trasferire il controllo alla procedura jal nome_procedura

 Procedura Chiamata
1) Salvare sullo stack i registri non modificabili $si che si vogliono utilizzare e il registro $ra
se verrà chiamata un'altra procedura
 Acquisire le risorse necessarie sullo stack addi $sp, $sp, -X
 Copiare i registri nello stack usando l'istruzione di store

3
2) Prelevare i parametri passati dai registri $ai usando l'istruzione move $?, $ai
3) Esecuzione del compito richiesto
4) Ripristinare lo stato dei registri non modificabili
 Copiare i registri dallo stack usando l'istruzione di load
 Liberare le risorse acquisite sullo stack addi $sp, $sp, X
5) Inserire il valore di ritorno nei registri $vi
6) Ritornare al programma chiamante jr $ra

 Procedura Chiamante
1) Prelevare il risultato move $?, $vi
2) Liberare lo spazio acquisito sullo stack per copiare i parametri addi $sp, $sp, X

Nota: Quando si fa la loadAdress (la) di una variabile globale il registro conterrà l'indirizzo della
variabile e non il suo valore! Per cui è necessario fare anche una load.

1) la $s0, r #s0 contiene l'indirizzo di r, ovvero il puntatore ad r


2) la $s2, c #s2 contiene l'indirizzo di c, ovvero il puntatore a c
3) lw $s0, 0($s0) #s0 contiene ora il valore di r
4) lw $s2, 0($s2) #s2 contiene ora il valore di c

-Tabella ASCII

4
MEMORIE
Memoria Cache

-Indirizzamento diretto

TAG BLOCCO OFFSET

1) Se non è data, determinare dimensione Cache : NumeroBlocchi * DimBlocco


2) Dimensione Indirizzo = esponente della dimensione della Memoria Centrale
3) OFFSET = esponente DimBlocco
4) BLOCCO = esponente (DimCache/DimBlocco)
5) TAG = esponente (DimMemoriaCentrale/DimCache)
6) INDIRIZZO IN CACHE10 = (BLOCCO10*DimBlocco10)+offset10
7) L'indirizzo è in cache se il TAG relativo a quel blocco è in cache accanto a quel
specifico blocco

Blocco Memoria Cache

Memoria Centrale

-Indirizzamento set-associativo

TAG SET OFFSET

1) Se non è data, determinare dimensione Cache : NumeroBlocchi * DimBlocco


2) Dimensione Indirizzo = esponente della dimensione della Memoria Centrale
3) OFFSET = esponente DimBlocco
4) SET = esponente (DimCache/DimBlocco/n°vie)
5) TAG = DimMemoriaCentrale/(DimBlocco*Set)
6) INDIRIZZO IN CACHE10 = (SET10*DimBlocco10*n°vie)+offset10

Blocco
Memoria Cache a 2 vie

Memoria Centrale

-Calcolo bit aggiuntivi per il tag


1) A seconda del tipo di indirizzamento calcolare la struttura dell'indirizzo ( OFFSET,
TAG...)
2) BIT AGGIUNTIVI = TAG*numeroBlocchi

1
Memoria Virtuale

-Indirizzo Virtuale -Indirizzo Fisico


N°PAGINA VIRTUALE OFFSET N°PAGINA FISICA OFFSET
N°PAGINA VIRTUALE
1) Dimensione indirizzo = esponente della dimensione della Memoria Virtuale(Fisica)
2) OFFSET = esponente DimPagina
3) N°PAGINA VIRTUALE(FISICA) = esponente (DimMemoriaVirtuale(Fisica)/DimPagina)
4) INDIRIZZO MEMORIA CENTRALE10 = (IndirizzoPaginaFisica10*DimPagina10)+offset10
5) L'indirizzo è in memoria centrale se nella TLB (tabella delle pagine) il bit di validità
relativo allo specifico n°pagina è settato a 1

N°PAGINA VIRTUALE OFFSET

1 IndirizzoPaginaFisica

N°PAGINA FISICA OFFSET


N°PAGINA VIRTUALE

-Calcolo numero bit TLB

1) Calcolare N°PAGINA VIRTUALE


2) Calcolare N°PAGINA FISICA
3) Calcolare NumeroRighe della TLB ( una tabella delle pagine ha un numero di righe
pari a quello del numero di pagine virtuali)
4) Calcolare DimRiga :
 Bit di uso (1)+
 Bit di validità (1)+
 Bit di modifica (dipende dall'algoritmo di sostituzione)+
 Numero Bit PaginaFisica
5) DIMENSIONE TLB = n°PaginaVirtuale*DimRiga

-Potenze di 2

20 1 28 256 216 65536


21 2 29 512 217 131072
22 4 210 1024 218 262144
23 8 211 2048 219 524288
24 16 212 4096 220 1048576
25 32 213 8192 221 2097152
26 64 214 16384 222 4194304
27 128 215 32768 223 8388608 Memoria
2
Moduli Memoria

N dispositivi di memoria di capacità C e parallelismo P


possono essere utilizzati sia per realizzare un’unica
memoria di capacità NC e parallelismo P sia per realizzare
un’unica memoria di capacità C e parallelismo NP.

-Realizzare una memoria con capacità NC

Con solo 2 moduli Con più di 2 moduli

-Realizzare una memoria con parallelismo NP

-Allocare indirizzi successivi su moduli diversi


Normalmente Indirizzi successivi
Normalmente gli indirizzi successivi
vengono allocati sullo stesso
modulo. Nell'esempio a sinistra i bit
da 0 a 12 vanno sull'Adress Bus e il
bit 13 va in AND col CS per
selezionare il modulo. Per allocare
indirizzi successivi su moduli diversi
si usa il bit meno significativo per
selezionare il modulo, quindi il bit 0
andrà in AND col CS e i bit da 1 a 13
andranno sull'Adress Bus.
3
PROCESSORE
-Determinare dipendenze

1) Le indipendenze che determinano situazioni di stallo sono solo le RAW


2) Segnare i registri che vengono letti e scritti ricordando che:
 add $s1, $s5, $s3 -------> s5,s3 sono letti, s1 viene scritto
 sw $s1, 0($s2) -------> s2,s1 sono letti
 lw $s1, 4($s2) -------> s2 è letto, s1 viene scritto
 bne $s1, $s2, 25 -------> s1,s2 sono letti
 beq $s1, $s2, 25 -------> s1,s2 sono letti
 slt $s1, $s2, $s3 -------> s2,s3 sono letti, s1 viene scritto
3) Verificare per ogni istruzione se i registri letti sono stati precedentemente scritti

-Calcolare colpi di clock per eseguire un blocco di codice

1) Determinare le dipendenze tra le istruzioni


2) Ricorda che:
IF/ID ID/EXE EXE/MEM MEM/WB

IF ID MEM WB
EXE
3) A seconda del tipo di propagazione valutare se inserire o meno delle bolle (Ricorda che è
possibile propagare solo in avanti e non in colpi di clock precedenti!)
4) Per capire se si può propagare o meno considera dove il dato è pronto e dove ti serve

-Fasi esecuzione istruzioni


1) Load: IF-ID-EXE-MEM-WB --------> Accesso Memoria Istruzioni e Dati
2) Store: IF-ID-EXE-MEM --------> Accesso Memoria Istruzioni e Dati
3) Aritmetico-Logiche: IF-ID-EXE-WB --------> Accesso Memoria Istruzioni
4) Branch: IF-ID-EXE --------> Accesso Memoria Istruzioni
MOLTIPLICATORI
-Settare i valori iniziali dei registri

1) Il Prodotto sarà di 2n bit, dove n è il numero di bit di Moltiplicatore e Moltiplicando


2) Aggiungi al Moltiplicando n zero davanti
3) Il Moltiplicatore resta uguale (n bit)

-Algoritmo

1) Se il Moltiplicatore = 1 (guarda primo bit da destra), somma il Moltiplicando al Prodotto e


metti il risultato nel registro Prodotto
2) Scorri il Moltiplicando a sinistra di 1 bit
3) Scorri il Moltiplicatore a destra di 1 bit
4) Se non sei arrivato all'n-esimo passo comincia da capo (n è il numero di bit degli operandi)

-Circuito logico

-Calcolo del segno

Se Moltiplicando e Moltiplicatore sono dati in modulo e segno per eseguire la moltiplicazione si


esegue la moltiplicazioni senza segno (togliendo il primo bit a sinistra a entrambi) e si calcola il
segno del risultato con la XOR (dà 1 soltanto se uno dei due è 1).

1
DIVISORI
-Settare i valori iniziali dei registri

1) Il Resto sarà di 2n bit, dove n è il numero di bit del Divisore, ed è uguale al Dividendo al quale
bisogna aggiungere n zero davanti (Resto = n0+Dividendo)
2) Aggiungi al Divisore n zero in coda
3) Il Quoziente è 0 (n bit)

-Algoritmo

1) Sottrai il registro Divisore dal registro resto e metti il risultato nel registro Resto
2) Controlla Resto (guarda primo bit da sinistra)
a) Se il Resto è ≥ 0 esegui lo scorrimento a sinistra del registro Quoziente mettendo un 1
nel nuovo bit più a destra
b) Se il Resto è < 0 Ripristina il valore originale sommando il registro Divisore al registro
Resto e mettendo la somma nel registro Resto. Esegui inoltre lo scorrimento a sinistra del
registro Quoziente, forzando a 0 il nuovo bit meno significativo.
3) Esegui lo scorrimento a destra di 1 bit del registro Divisore
4) Se non sei arrivato all'n+1-esimo passo comincia da capo (n è il numero di bit degli
operandi)

-Circuito logico

-Calcolo del segno

Se Dividendo e Divisore sono dati in modulo e segno per eseguire la divisione si esegue la divisone
senza segno (togliendo il primo bit a sinistra a entrambi) e si calcola a parte il segno. Il Quoziente è
negativo se i segni di Dividendo e Divisore sono opposti, il Resto, quando non è 0, ha lo stesso
segno del dividendo.

Dividendo Divisore Quoziente Resto


+ + + +
+ - - +
- + - -
- - + -

2
MACCHINE ELEMENTARI

-ENCODER

n-Ingressi m-Uscite
È una macchina che riceve in ingresso n
. .
bit e ha in uscita log2 n = m bit che
. .
. . rappresentano una specifica codifica
. .

EN

-DECODER
m-Uscite
n-Ingressi
È una macchina che riceve in ingresso n
.
bit e ha in uscita 2m di cui solo 1/m è
. .
.
.
.
. selezionato come attivo

EN

-MULTIPLEXER
S
n-Ingressi m-Uscite
È una macchina che seleziona una delle
M 2n entrate in base al segnale di selezione
U S
X

EN

-CONTATORE È una macchina utilizzata spesso per i ciclo


temporali prefissati
O
EN EN= abilitazione
Div
Clock Clock = frequenza
Rip Up/Down = conto a crescere o decrescere
Up/Down
Load = per precaricare un valore
Load Reset I = valore da caricare
I
Reset = resetta il contatore
O = valore di conteggio in uscita
Div = fine del conteggio
1
-COMPARATORE
È una macchina utilizzata per confrontare due
A Max > valori (A e B)

B Equal = Max -> A>B


Min < Equal -> A=B
Min -> A<B

-ADDIZIONATORE

R
A
È una macchina utilizzata per sommare due
O numeri (A e B). L'uscita O contiene la loro somma
mentre R e r sono rispettivamente il riporto in
B uscita e in entrata
r

-SOTTRATTORE
È una macchina utilizzata per sotrrarre due
R
A numeri (A e B). L'uscita O contiene la loro
O differenza mentre R e r sono rispettivamente il
Zero riporto in uscita e in entrata. Il segnale zero
B P/N rappresenta che la sottrazione è zero (quindi i
r
numeri sono uguali), il segnale P/N rappresenta
se la somma è positiva o negativa.

-REGISTRO A SCORRIMENTO

Po È una macchina che dispone di un segnale di shift


EN Po
Si So
che carica nell'i-esimo flip flop il valore
........ dell'elemento i-1.
SH Pi . Quando Pi è basso, il circuito riceve Si (riceve
Pi
serialmente). Quando Pi è alto cioè che c'è sul
dataBus Pi è caricato nello shift register (riceve in
parallelo)

Potrebbero piacerti anche