Laboratorio di Architettura
Lezione 4
Andrea Torsello
Dipartimento di Informatica
Università “Ca’Foscari” di Venezia
Lab. Architettura - Lezione 4
p.1/73
La scorsa volta
Abbiamo visto le istruzioni per la manipolazione di dati
(operazioni aritmetiche, ed operazioni logiche)
Lab. Architettura - Lezione 4
p.2/73
Riassunto
+, -, *, /, <: add, sub, mult, div, slt
and, or, xor, nor
Lab. Architettura - Lezione 4
p.3/73
Mancano. . .
Le SHIFT
Lab. Architettura - Lezione 4
p.4/73
LE SHIFT’s
Shift right (sposta a destra)
1011111111111111 ⇒ 0101111111111111
Shift left (sposta a sinistra)
1011111111111111 ⇒ 1011111111111110
Sono istruzioni “ibride”, nel senso che agiscono sia a
livello di bit che a livello di word
Lab. Architettura - Lezione 4
p.5/73
Shift’s
Cosa fanno le shifts?
A livello di bit, spostano appunto a destra o a sinistra
A livello di WORD:
Uno shift a sinistra MOLTIPLICA per DUE
Uno shift a destra DIVIDE per DUE
ATTENZIONE ai numeri negativi...
Lab. Architettura - Lezione 4
p.6/73
Spostamenti (shifts)
Lo shift (spostamento) di un numero avviene a destra o a
sinistra:
SHIFT A DESTRA: si cancella la cifra più a destra, e si
mette uno zero a sinistra
SHIFT A SINISTRA: si cancella la cifra più a sinistra, e
si mette uno zero a destra
ATTENZIONE: lo shift è SEMPRE inteso per numeri
binari (la cifra è un bit)
Lab. Architettura - Lezione 4
p.7/73
ESEMPI
Shift a destra di
10111011
è
01011101
Shift a sinistra di
10111011
è
01110110
Lab. Architettura - Lezione 4
p.8/73
SHIFT MULTIPLO
Lo shift classico è di una posizione
Ovviamente, può essere di più posizioni:
Lo shift a destra di n posizioni si ottiene facendo lo
shift a destra n volte
Lo shift a sinistra di n posizioni si ottiene facendo lo
shift a sinistra n volte
Lab. Architettura - Lezione 4
p.9/73
ESEMPI
Shift di tre posizioni a destra di
10111011
è
00010111
Shift di tre posizioni a sinistra di
10111011
è
11011000
Lab. Architettura - Lezione 4
p.10/73
Spostamenti (cont.)
Tornando al linguaggio macchina, si possono
effettuare:
Shifts a destra di n posizioni
Shifts a sinistra di n posizioni
Lab. Architettura - Lezione 4
p.11/73
SHIFT A DESTRA
In assembly:
srl dest, reg2, spost
srl = shift right logical, e spost è il numero di shifts che
si devono fare
In linguaggio macchina dunque:
0 0 reg2
Lab. Architettura - Lezione 4
p.12/73
dest
spost
variant=2hex
SHIFT A SINISTRA
In assembly:
sll dest,reg2,spost
sll = shift left logical, e spost è il numero di shifts che
si devono fare
In linguaggio macchina dunque:
0 0 reg2
Lab. Architettura - Lezione 4
dest
spost
variant=4hex
p.13/73
Cosa vedremo
Tutti gli effetti collaterali di queste istruzioni
Le loro varianti
Come da queste operazioni basilari se ne derivano
altre più potenti
(soprattutto) a cosa servono veramente
Lab. Architettura - Lezione 4
p.14/73
Le tre famiglie fondamentali
Come detto, ci sono tre famiglie fondamentali di istruzioni,
per:
1. Manipolazione di dati
2. Movimento di dati
3. Flusso di dati
Lab. Architettura - Lezione 4
p.15/73
Cosa ci manca ancora
Ci manca:
1. movimento di dati, e
2. flusso di dati
Lab. Architettura - Lezione 4
p.16/73
2. MOVIMENTO DI DATI
Occorrono istruzioni anche per spostare i dati. . .
Da registri a memoria (STORE)
Da memoria a registri (LOAD)
Da registri a registri (MOVE)
Lab. Architettura - Lezione 4
p.17/73
STORE
Due tipi di istruzione store: permettono di spostare
WORDS: numeri di 32 bits
BYTES: numeri di 8 bits
Lab. Architettura - Lezione 4
p.18/73
STORE WORD
In assembly:
sw reg2,indirizzo(reg1)
mette il valore di reg2 alla locazione di memoria
indirizzo+reg1
Lab. Architettura - Lezione 4
p.19/73
ESEMPIO DI SW
Esempio:
sw $t0,8($t1)
Supponiamo che $t0= 12345678hex e $t1=40
Allora l’istruzione mette il valore di $t0 (12345678hex )
nella memoria all’indirizzo 48 (8+40)
Lab. Architettura - Lezione 4
p.20/73
STORE BYTE
In assembly:
sb reg2,indirizzo(reg1)
mette il byte più basso di reg2 alla locazione di
memoria indirizzo+reg1
Lab. Architettura - Lezione 4
p.21/73
ESEMPIO DI SB
Esempio:
sb $t0,7($t1)
Supponiamo che $t0= 12345678hex e $t1=40
Allora l’istruzione mette il byte più basso di $t0 (78hex )
nella memoria all’indirizzo 47 (7+40)
Lab. Architettura - Lezione 4
p.22/73
LOAD
Tre tipi di istruzione load, che permettono di caricare nei
registri:
Dalla memoria: WORDS (parole a 32 bits), e BYTES
(8 bits)
Direttamente un numero a 16 bits
Lab. Architettura - Lezione 4
p.23/73
LOAD WORD
In assembly:
lw reg2,indirizzo(reg1)
mette in reg2 il valore presente nella locazione di
memoria indirizzo+reg1
Esempio:
lw $t0,8($t1)
mette in $t0 il valore presente in 8($t1)
Lab. Architettura - Lezione 4
p.24/73
LOAD BYTE
In assembly:
lbu reg2,indirizzo(reg1)
ATTENZIONE: non è “lb”
mette nel byte più basso di reg2 il BYTE presente nella
locazione di memoria indirizzo+reg1
Lab. Architettura - Lezione 4
p.25/73
ESEMPIO DI LBU
Esempio:
lbu $t0,7($t1)
Supponiamo che $t0= 12345678hex , $t1=40, e che
all’indirizzo 47 ci sia il byte ABhex
Allora eseguendo l’istruzione avremo in $t0 il valore
finale di 123456ABhex
Lab. Architettura - Lezione 4
p.26/73
LOAD UPPER IMMEDIATE
In assembly:
lui reg2, numero
mette nei 16 bit PIÙ ALTI (UPPER) di reg2 il valore
numero
Lab. Architettura - Lezione 4
p.27/73
ESEMPIO DI LUI
Esempio:
lui $t0,ABCDhex
Supponiamo che $t0= 12345678hex
Allora eseguendo l’istruzione avremo in $t0 il valore
finale di ABCD5678hex
Lab. Architettura - Lezione 4
p.28/73
. . .e la metà bassa?
Per caricare un valore nella metà bassa si può usare
una addi o una ori:
ori $t0, $zero, ABCDhex
il valore finale in $t0 sarà 0000ABCDhex
Per mettere 12345678hex in $t0 possiamo fare:
ori $t0, $zero, 5678hex
lui $t0, 1234hex
NOTA: $zero è un registro particolare che contiene
sempre il valore 0
Lab. Architettura - Lezione 4
p.29/73
la
Il nostro assembler ci viene incontro offrendoci una
pseudo-istruzione:
la $t0, 12345678hex
la non è una vera istruzione in linguaggio macchina,
ma l’assembler si preoccupa di trasformarla in una
sequenza di istruzioni adatta
Lab. Architettura - Lezione 4
p.30/73
NOTA IMPORTANTISSIMA
Tutte le istruzioni di LOAD e STORE, in generale,
funzionano rispettando il cosiddetto principio
fondametale di
ALLINEAMENTO DELLA MEMORIA
Quando si sposta un dato di taglia n, si può operare
solo su indirizzi di memoria multipli di n
Lab. Architettura - Lezione 4
p.31/73
ESEMPIO di allineamento
Usando sw o lw, si agisce su WORDS (parole), che
sono lunghe 4 bytes
gli indirizzi che si possono usare sono solo i multipli di
4
Lab. Architettura - Lezione 4
p.32/73
ESEMPI allineamento words
Si consideri l’istruzione
sw $t0,7($t1)
Se $t1=1, l’istruzione è legale (7+1=8)
Se $t1=2, l’istruzione è illegale (7+2=9)
Se $t1=3, l’istruzione è illegale (7+3=10)
Lab. Architettura - Lezione 4
p.33/73
E NEL CASO DEI BYTES?
Nel caso di istruzioni che manipolano un byte (sb, lbu),
il principio di allineamento dice che ogni indirizzo deve
essere multiplo di 1 byte
Quindi qualsiasi indirizzo va bene:
nessuna restrizione!
Lab. Architettura - Lezione 4
p.34/73
MOVE
Infine, ci sono istruzioni che permettono di spostare
dati internamente, da certi registri ad altri registri
Servono per recuperare i valori dei registri Hi e Lo
(quelli usati per moltiplicare e dividere)
Lab. Architettura - Lezione 4
p.35/73
Recuperare i dati da Lo e Hi
mfhi dest
Move From Hi: muove il contenuto di Hi nel registro
dest
mflo dest
Move From Lo: muove il contenuto di Lo nel registro
dest
Lab. Architettura - Lezione 4
p.36/73
3. FLUSSO DI DATI
Sono le istruzioni che permettono di spostarsi all’interno del
programma stesso, facendo salti in avanti o all’indietro
Lab. Architettura - Lezione 4
p.37/73
Il flusso standard di istruzioni
Normalmente, l’esecuzione è sequenziale
C’è un registro dedicato, il program counter (contatore
di programma), o PC, che dice al computer dove si
trova la prossima istruzione da eseguire
Il flusso standard è: esegui l’istruzione all’indirizzo
indicato da PC, e avanza all’istruzione successiva
(PC = PC + 4)
Lab. Architettura - Lezione 4
p.38/73
MODIFICARE IL FLUSSO
Le istruzioni per la modifica del flusso servono a
modificare il PC
Avendo accesso al PC, possiamo ridirigere
l’esecuzione del programma in ogni punto, facendo
salti in avanti e indietro, e abbandonando quindi il
flusso standard, sequenziale, delle istruzioni.
Lab. Architettura - Lezione 4
p.39/73
Due tipi di “salti”
Si può toccare il PC in due modi, corrispondenti a due tipi di
salti
SALTO RELATIVO: si specifica la distanza a cui si salta
PC = PC + distanza
SALTO ASSOLUTO: si specifica direttamente
l’indirizzo a cui si salta
PC = indirizzo
Lab. Architettura - Lezione 4
p.40/73
SALTI RELATIVI
Hanno tutti la forma
condizione reg1 reg2 indirizzo
Il significato è: se reg1 e reg2 soddisfano la
condizione, allora salta relativamente con distanza
specificata in indirizzo (PC = PC + indirizzo*4),
altrimenti prosegui come al solito con l’istruzione
successiva (PC = PC + 4)
Lab. Architettura - Lezione 4
p.41/73
OSSERVAZIONE
In tutti i salti relativi, la distanza si ottiene moltiplicando
indirizzo per 4
(PC = PC + indirizzo*4)
MOTIVO: possiamo avvantaggiarci del fatto che tutte le
istruzioni hanno lunghezza fissa (4), per saltare molto
più distante.
Inoltre, garantiamo principio di allineamento
Lab. Architettura - Lezione 4
p.42/73
POSSIBILI SALTI RELATIVI
Branch EQual
beq reg1 reg2 indirizzo
Salta relativamente se reg1=reg2
Branch Not Equal
bne reg1 reg2 indirizzo
Salta relativamente se reg1 6= reg2
Lab. Architettura - Lezione 4
p.43/73
SALTI ASSOLUTI
In questi salti, si specifica direttamente l’indirizzo dove
andare nel programma
Tre possibili salti assoluti:
1. Jump
2. Jump and link
3. Jump register
Lab. Architettura - Lezione 4
p.44/73
JUMP
Formato: jump indirizzo
Cosa fa: PC = indirizzo*4
NOTA: anche qui, ci si avvantaggia del fatto che le
istruzioni hanno lunghezza fissa e del principio di
allineamento
istruzione di tipo J
6 bits 26 bits
op
indirizzo
Lab. Architettura - Lezione 4
p.45/73
JUMP AND LINK
Formato: jal indirizzo
Cosa fa: salta, ma si ricorda come tornare indietro
PRIMA, salva PC+4 (l’istruzione successive) nel registro
speciale $ra
POI salta: PC = indirizzo*4 (come jump)
Lab. Architettura - Lezione 4
p.46/73
JUMP REGISTER
Formato: jr reg1
Cosa fa: salta all’indirizzo specificato nel registro reg1:
PC = reg1
Lab. Architettura - Lezione 4
p.47/73
RIASSUNTO FINALE
1. Manipolazione di dati:
add, sub, mult, div, slt
sll, srl
and, or, nor, xor
addi, slti, andi, ori, xori
2. Movimento di dati:
sw, sb, lw, lbu, lui, mfhi, mflo
3. Flusso di istruzioni:
beq, bne, jump, jal, jr
Lab. Architettura - Lezione 4
p.48/73
E Ora?
Ora che finalmente abbiamo le “basi” di un linguaggio
macchina, possiamo passare a cose un po’ più stimolanti,
quali
vedere come funziona in pratica
fare un’analisi critica
scoprire qual’è la sua potenza
Lab. Architettura - Lezione 4
p.49/73
Le basi? ALTRE ISTRUZIONI?
Il linguaggio macchina MIPS ha ALTRE ISTRUZIONI
che non abbiamo considerato
Per in nostri scopi, non sono strettamente necessarie
Ma soprattutto ci sono motivi architetturali per la scelta
di queste istruzioni, e ne parleremo, ora che finalmente
abbiamo il linguaggio
le altre istruzione le trovate descritte nell’appendice A
del libro di testo
Lab. Architettura - Lezione 4
p.50/73
MA. . .
Ve ne voglio aggiungere una in particolare, vista la sua
stranezza
Formato assembly: nop
Rappresentazione linguaggio macchina:
0 0 0
0 0 0
Cosa fa: NIENTE! (nop = No OPeration)
Lab. Architettura - Lezione 4
p.51/73
QUIZ
Secondo voi, PERCHÉ c’è questa istruzione?
Nota: c’è IN OGNI LINGUAGGIO MACCHINA, non è
solo una stranezza di MIPS
Lab. Architettura - Lezione 4
p.52/73
Compilazione
Come si passa da un linguaggio di alto livello a uno di
basso livello?
Cioè a dire, come lavora un compilatore, che
effettivamente traduce un linguaggio in linguaggio
macchina?
Lab. Architettura - Lezione 4
p.53/73
Alto Livello
Come esempio di passaggio da alto a basso livello,
useremo il linguaggio di programmazione C
Per chi non fosse familiare col C, ricordo i puntatori
presenti su
http://www.dsi.unive.it/∼lab-arch
Lab. Architettura - Lezione 4
p.54/73
Metodologia di Programmazione
Mosteremo una possibile compilazione da C a
linguaggio macchina
⇒ utile concettualmente
⇒ evidenzia man mano le differenze tra alto e basso
livello, cosa avviene veramente nella macchina
⇒ programmi più efficienti e veloci
Lab. Architettura - Lezione 4
p.55/73
Programmi C
Sono fatti da istruzioni che manipolano variabili
Esempio:
a = b+c;
if (a<d) e=32;
Lab. Architettura - Lezione 4
p.56/73
Istruzioni
Intuitivamente, è ovvio che avremo un modo per
simulare le istruzioni in linguaggio macchina
Ad esempio, per simulare
a=b+c;
useremo la add in assembly
Lab. Architettura - Lezione 4
p.57/73
Variabili
Ma l’altro punto cruciale da considerare è come si
rappresentano le variabili in linguaggio macchina
Cioè, come rappresento “a”, “b”, “c” per poi eseguire
“a=b+c” ?
Lab. Architettura - Lezione 4
p.58/73
C e Linguaggio Macchina
Mentre il C ha istruzioni e variabili. . .
Il linguaggio macchina ha istruzioni e memoria (interna
ed esterna)
⇒ quindi, dovremo trovare una adeguata
rappresentazione delle variabili in memoria
Lab. Architettura - Lezione 4
p.59/73
Variabili e Memoria
La memoria si distingue in interna (registri) ed esterna
(semplicemente “memoria”)
I registri sono in numero fisso, mentre la memoria è
potenzialmente illimitata
Siccome anche il numero di variabili in un programma,
in generale, non è fisso
⇒ la scelta naturale è di mettere i valori delle variabili
in memoria
Lab. Architettura - Lezione 4
p.60/73
Variabili ⇒Memoria
Quindi, per ogni variabile del programma, ad esempio
“a”, “b”, “c”
Avremo una corrispondente posto in memoria:
‘‘a’’ ⇒ 200
‘‘b’’ ⇒ 360
‘‘c’’ ⇒ 380
Ma. . .
Lab. Architettura - Lezione 4
p.61/73
Differenze: Tipi di Dato
In linguaggi tipo il C, ci sono diversi tipi di dato:
caratteri, interi (normali corti lunghi), stringhe, reali
(floating point a singola o doppia precisione) eccetera
Ognuno di questi tipi ha una certa taglia se espresso in
bits (ad esempio, caratteri: 8, interi corti: 16; reali: 32 o
64; stringhe: 8*(lunghezza della stringa + 1)
Lab. Architettura - Lezione 4
p.62/73
Tipi in Linguaggio Macchina
Mentre la “taglia” di un dato è abbastanza trasparente
all’utente in linguaggi di alto livello (tipo il C). . .
. . . in linguaggio macchina ogni cosa deve essere
esplicitata, e quindi bisogna avere la taglia di ogni tipo
di dato, e avere abbastanza celle di memoria per ogni
variabile di quel tipo
Lab. Architettura - Lezione 4
p.63/73
Esempi
In C, variabili “a”, “b”, “c” di tipo intero “long” (32 bits)
⇒ Si deve assegnare a ogni variabile lo spazio
corrispondente in memoria
Esempio:
a ⇒ 200, . . .,203 (4 bytes, 32 bits)
b ⇒ 360, . . .,363 (4 bytes, 32 bits)
c ⇒ 380, . . .,383 (4 bytes, 32 bits)
Lab. Architettura - Lezione 4
p.64/73
Taglie piccole e grandi
Nell’esempio precedente, eravamo fortunati perché la
taglia era giusto 32 bits (4 bytes)
⇒ nessun problema col principio di allineamento
Ma, in generale, le taglie possono essere varie
⇒ una scelta possibile è di arrotondare sempre in
eccesso a multipli di 4, per non avere problemi
Lab. Architettura - Lezione 4
p.65/73
Esempio
In C:
if (valore==true) . . .
Dove “valore” è una variabile booleana
⇒ in principio, basta un bit, o un byte
⇒ per non avere problemi, possiamo prenderci 4 byte
in memoria:
valore ⇒ 500, . . ., 503 (anche se useremo solo un bit
di 500)
Lab. Architettura - Lezione 4
p.66/73
POSSIBILITÀ
Ovviamente, ci sono infinite possibilità quando si
esegue la compilazione
A noi, interessa solo la correttezza della compilazione
Ma in generale, contano anche compattezza e velocità
(spazio e tempo)
Quindi magari usare 4 bytes per un bit può essere
troppo dispendioso. . .
Lab. Architettura - Lezione 4
p.67/73
Semplice Compilazione
In C: a = b+c;
Mappatura delle variabili (double):
a ⇒ 100, . . ., 103
b ⇒ 104, . . ., 107
c ⇒ 108, . . ., 111
Vorremmo poter fare in assembly:
add mem100, mem104, mem108
Lab. Architettura - Lezione 4
p.68/73
Ma. . .
“add” funziona con registri, non con memoria esterna
⇒ occorre prima passare i valori delle variabili da
memoria a registri (LOAD), fare le operazioni che
vogliamo, e poi rimetterle in memoria (STORE)
Lab. Architettura - Lezione 4
p.69/73
Semplice Compilazione (2)
Volevamo poter fare in assembly:
add mem100, mem104, mem108
⇒
lw $t0, 104 # carica ‘‘b’’ in t0
lw $t1, 108 # carica ‘‘c’’ in t1
add $t2,$t0,$t1 # mette la
#somma in t2
sw $t2, 100 # mette t2 in ‘‘a’’
Lab. Architettura - Lezione 4
p.70/73
ATTENZIONE
Ricordarsi che in assembly il nome del registro va
preceduto con “$”
Quindi, add $t2,$t0,$t1
E NON add t2,t0,t1
Vedremo in seguito perché
NOTA: Non è così in generale per tutti gli assembly.
Lab. Architettura - Lezione 4
p.71/73
Ricapitolando. . .
In C: a = b+c;
Si può tradurre (data la mappatura
a ⇒ 100, . . ., 103
b ⇒ 104, . . ., 107
c ⇒ 108, . . ., 111 )
Con:
lw $t0, 104 # carica ‘‘b’’ in t0
lw $t1, 108 # carica ‘‘c’’ in t1
add $t2,$t0,$t1 # mette la somma in t2
sw $t2, 100 # mette t2 in ‘‘a’’
Lab. Architettura - Lezione 4
p.72/73
Numeri
In C: a = 24
Usiamo un registro speciale, $zero, che ha sempre il
valore zero
In assembly:
addi $t0,$zero,24 # metti 0+24 in t0
sw $t0, 100 # metti t0 in ‘‘a’’
Naturalmente, ci sono molti altri modi per inserire un
numero. . . provate.
Lab. Architettura - Lezione 4
p.73/73