Istruzioni e linguaggio macchina
•
I linguaggi macchina sono composti da istruzioni macchina,
codificate in binario, con formato ben definito
• processori diversi hanno linguaggi macchina simili
• scopo: massimizzare le prestazioni
• veloce interpretazione da parte del processore
• efficace traduzione/compilazione di programmi ad alto
livello
•
Linguaggi molto più primitivi dei linguaggi ad alto livello
• controllo del flusso poco sofisticato (non ci sono for, while, if)
Linguaggi molto restrittivi
• istruzioni aritmetiche con numero fisso di operandi
•
Linguaggio macchina e astrazioni
Istruzioni macchina e codifica binaria
Le istruzioni macchina, ovvero il linguaggio che la
macchina (processore) comprende, hanno bisogno
anch’esse di essere codificate in binario
• Devono essere rappresentate in binario in accordo ad
un formato ben definito
Il linguaggio macchina è molto restrittivo
• il processore che studieremo sarà il MIPS, usato da
Nintendo, Silicon Graphics, Sony...
• l’ISA del MIPS è simile ad altre architetture di CPU
sviluppate dal 1980
• le istruzioni MIPS operano su particolari supporti di
memoria denominati registri, la cui lunghezza è di 32 bit
= 4 Byte
Esempio di Istruzione MIPS
Codice C (linguaggio di programmazione di alto livello):
a=b+c
Codice Assembly (istruzioni macchina human-friendly):
add a, b, c # a è la somma di b e c
Codice Macchina (istruzioni macchina machine-friendly):
00000010001100100100000000100000
Esempio di Istruzione MIPS
Tradurre il seguente codice C in codice assembly:
a=b+c+d+e
add a, b, c
add a, a, d
add a, a, e
add a, b, c
oppure
add f, d, e
add a, a, f
Le istruzioni sono semplici: numero prefissato di operandi
Una singola riga di codice C diventa molteplici righe di codice assembly
Alcune sequenze sono migliori di altre: la seconda sequenza necessita
di una variabile (temporanea) f
Informazione e memoria
L’informazione, opportunamente codificata, ha bisogno di essere
memorizzata nel calcolatore per essere utilizzata.
In particolare i programmi (e i dati) devono essere trasferiti nella
memoria principale del computer per l’esecuzione.
Organizzazione della memoria:
• sequenza di celle (o locazioni) di lunghezza prefissata
• ogni cella è associata con un numero (chiamato indirizzo)
• se un indirizzo è espresso come numero binario di m bit
• sono indirizzabili 2m celle diverse (da 0 a 2m -1)
• indirizzi consecutivi → celle contigue
• nelle memorie attuali, ogni cella di memoria è lunga
23= 8 bit = 1 Byte
(memoria indirizzabile al Byte)
Operandi
•
In C, ogni “variable” è una locazione di memoria
•
A livello hardware, accedere alla memoria è costoso
•
Se una variable è acceduta ripetutamente, aiuterebbe “portarsela” in
“locazioni di memoria” sul chip del processore, ed effettuare le
operazioni sul chip.
•
Le “locazioni di memoria” sul chip sono chiamate registri
•
Per semplificare le operazioni, (quasi) tutte le istruzioni operano solo su
registri
•
I registri sono MOLTO costosi, quindi ce ne può essere solo un numero
limitato e prefissato
•
Ma in C possiamo usare tutte le variabili che ci pare…
Registri MIPS
•
La ISA del MIPS ha 32 registri
•
Ogni registro è “largo” 32 bit (su architetture a 64 bit, ogni
registro è largo 64 bit)
•
Qualsiasi “entità” lunga 32 bit (4 byte) è chiamata word (parola)
•
Per comodità di lettura, nel seguito indicheremo i registri come:
•
$s1, $s2, … per le variabili del linguaggio ad alto livello, e.g.,
C++ o Java
•
$t1, $t2, … per le variabili temporanee usate per tradurre le
istruzioni ad alto livello in istruzioni assembler
Stored Program
•
•
•
•
•
•
Istruzioni sono stringhe di bit
Programmi: sequenze di istruzioni
Programmi (come i dati) memorizzati in memoria
La CPU legge le istruzioni dalla memoria (come i dati)
Ciclo macchina (ciclo Fetch – Decode – Execute)
• La CPU legge (fetch) l’istruzione corrente (indirizzata da un
registro Program Counter = PC), e la pone in un registro
speciale interno
• La CPU usa i bit dell’istruzione per "controllare" le azioni da
svolgere, e su questa base esegue l’istruzione
CPU determina la “prossima” istruzione e ripete il ciclo
Operandi e memoria
•
I dati devono essere prelevati dalla memoria prima che le
operazioni possano utilizzarli
Load word
lw $t0, indirizzo-di-memoria
•
Processore
Registro
Memoria
I dati devono essere immagazzinati in memoria quando
necessario
Store word
sw $t0, indirizzo-di-memoria
Processore
Registro
Memoria
Operandi e memoria
•
Il compilatore organizza i dati del programma nella memoria
•
Conosce la locazione in memoria di ogni variabile del programma
•
Per ogni istruzione di load/store genera l’opportuno indirizzo di memoria
int a int b int c int d[10]
indirizzo base
…
Operandi immediati
•
Una istruzione potrebbe richiedere una costante come input
•
Un’istruzione immediata usa una costante numerica come uno
degli input (al posto di un operando registro)
addi $s0, $zero, 1000
# l’indirizzo base del programma è 1000
# ed è memorizzato in $s0
immediate
# $zero è un registro speciale
# contenente sempre 0
addi $s1, $s0, 0
# indirizzo della variabile a
addi $s2, $s0, 4
# indirizzo della variabile b
addi $s3, $s0, 8
# indirizzo della variabile c
addi $s4, $s0, 12
# indirizzo della variabile d[0]
Indirizzamento della memoria
•
Siccome la dimensione minima di una cella di memoria si 1 byte,
l’indirizzamento di memoria è “al byte” (indirizzamento al byte)
•
Nel MIPS (e in molte altre architetture) è obbligatorio che le parole
di memoria abbiano indirizzi multipli di 4 (vincolo di allineamento)
•
Codice C:
d[3] = d[2] + a
•
Assembler:
lw $t0, 8($s4)
# d[2] è caricato in $t0
lw $t1, 0($s1)
# a è caricato in $t1
offset
add $t0, $t0, $t1 # la somma è in $t0
sw $t0, 12($s4) # $t0 è scaricato in d[3]
Istruzioni Aritmetico/Logiche
•
•
•
•
•
•
Le istruzioni aritmetiche del MIPS permettono solo
operazioni elementari (add, sub, mult, div) tra coppie di
operandi a 32 bit
Le istruzioni logiche (and, or) sono bit a bit
Tutte le istruzioni hanno 3 operandi
L’ordine degli operandi è fisso
L’operando destinazione in prima posizione
Esempio
• Codice C: A = B + C
• Codice Assembler: add $t0, $s1, $s2
• Il compilatore associa le variabili ai registri
Codifica in formato R-Type
esempio
add $t0, $s1, $s2
semantica
$t0 = $s1 + $s2
codifica
000000 10001 10010 01001 00000 100000
op
op:
rs
rt
rd
shamt
funct
operazione base dell’istruzione
rs: registro del primo operando
rt: registro del secondo operando
rd: registro destinazione, che contiene il risultato dell’operazione
shamt: utilizzato per istruzioni di shift; posto a zero per le altre istruzioni
funct: seleziona la specifica variante dell’operazione base definita nel campo op