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