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