Istruzioni base Assembly RISC-V
Argomenti trattati:
- Prima parte:teoria, formato delle istruzioni, cosa accade in memoria e nella CPU
- Seconda parte:istruzioni, come utilizzarle
Ci sono delle direttive all’assembler che rendono il codice assembly più espressivo e leggibile. .text permette di usare delle etichette, per indicare porzioni di codice, un po come il goto del C. .align indica l’allineamento su n byte, cioè l’istruzione una volta messa in memoria deve cominciare da un indirizzo che è un multiplo di 2^n.Quindi tutte le istruzioni che seguono devono essere posizionate in memoria centrale in un indirizzo multiplo di 2^n. .globl main indica che questa posizione di memoria puo essere usata anche in altre unità del programma stesso.L’istruzione .globl indica che il simbolo main sarà accessibile anche dall’esterno del file. .asciiz “SIMBOLI” significa che ciascuno dei simboli verra rappresentato con un byte in memoria cosi come vuole la codifica ASCII e verrà terminato con un byte a zero. Le istruzioni comprese nel linguaggio macchina di qualsiasi computer sono classificabili in 4 categorie: Non essendoci cicli come il for, while ecc… posso ricrearle tramite le istruzioni che modificano il program counter. I 32 registri di RISC-V, nominati da 0 a 31, possono essere chiamati con la seguente notazione: Per codificarli, essendone 32 bastano 5 bit. Non confondere variabile con registro: una variabile è un ingombro di memoria caratterizzato da un nome e un tipo, mentre il registro è solo un ingombro che si trova dentro la CPU e non in RAM. Una word sono 32 bit, una half word sono 16 bit, una double word sono 64 bit.Quindi i registri contengono un ingombro di una double word. Un’istruzione che prova a modificare x0 non ha alcun effetto:x0 mantiene il valore di default 0. I registri si possono anche chiamare con nomi simbolici che specificano l’utilizzo(n.b. i registri sono general purpose, quindi si possono utilizzare come si preferisce): ci sono registri che non possono essere chiamati e non si puo operare al loro interno: Il formato dell’istruzione significa guardare quei 32 bit di cui è composta l’istruzione assembly e guardare quindi i suoi campi. rs è il registro sorgente(esempio gli addendi di una addizione), rd(dove il risultato va salvato) è il registro destinazione. L’immediate è una costante, quindi un valore numerico che si scrive direttamente nell’istruzione. Ogni istruzione può al massimo: Ecco i 6 tipi di formato di istruzioni in assembly RISC-V:
ATTENZIONE:
Il fatto di avere solo due operazioni semplifica l’HW ma complica alcuni aspetti. SOMMA questa operazione esegue l’addizione tra il contenuto di x4,x7 e poi lo salva(store) in x2. SOTTRAZIONE Sono istruzioni che si occupano di trasferire dati dalla memoria centrale ai registri(load-ld) o viceversa(store-st). formato: OPERATORE registro indirizzo memoria ld sta per load double(double word), mentre sd store double. LOAD l'istruzione di load trasferisce una copia della parola contenuta in una specifica locazione di memoria (a 64 bit) mettendola in un registro della CPU, e lasciando inalterata la parola di memoria: la memoria è vista come un array di celle.Leggere una locazione di memoria significa richiederne una copia e trasferirla in CPU. La locazione di memoria è indicata con la modalità BASE REGISTER + OFFSET STORE E’ la duale della load, solo che avrò un registro sorgente anzichè un indirizzo destinazione. L'istruzione di store trasferisce una parola da un registro della CPU (64 bit) mettendola in una specifica locazione di memoria, sovrascrivendo il contenuto precedente di quella locazione: CARICAMENTO DI COSTANTE O DI INDIRIZZO LABEL serve ad indicare il valore dell’indirizzo di memoria di un dato. La load immediate consente di caricare una costante da 32 bit anzichè una da 20. La differenza tra la e ld è che la trasferisce un indirizzo, mentre ld il contenuto in quell’ingombro. Quindi le pseudo istruzioni vengono estese dall’assembler in quanto non sono presenti nella CPU in origine. SALTO CONDIZIONATO: SALTO INCONDIZIONATO CON COLLEGAMENTO: il calcolo dell’indirizzo destinazione di salto è relativo (a PC o rs1) FORMATO B – opcode:(opcode) identifica il tipo di istruzione lo spiazzamento (rispetto al PC) ha a disposizione solo 12 bit in questo formato deve fare riferimento ad half word (mezza parola), pertanto esso termina sempre con un bit 0 che viene sottointeso nella rappresentazione binaria, consentendo di raddoppiare lo spazio di offset Prima di sommare l’offset al PC, il processore riporta a byte l’offset (già esteso in segno) tramite moltiplicazione per due(scorrimento a sx di una posizione e aggiunta di un bit 0 a dx). l’indirizzamento relativo al Program Counter permette di fare salti condizionati ad aree di memoria il cui indirizzo non è esprimibile con solo 12 bit. – per esprimere l’etichetta L1 si dispone solo di 12 bit (per il principio di località degli indirizzi di memoria è utile calcolare l’indirizzo di destinazione del salto come offset rispetto all’istruzione corrente) Per permettere salti in avanti e indietro, l’offset è rappresentato in complemento a 2. l’assemblatore sostituisce l’etichetta L1 con lo spiazzamento Il valore del campo indirizzo può anche essere negativo(salto all’indietro). FORMATO J Lo spiazzamento rispetto al PC ha a disposizione solo 20 bit e deve fare riferimento a half word.Pertanto esso termina sempre con un bit 0 che viene sottointeso nella rappresentazione binaria, consentendo di raddoppiare lo spazio di offset il modulo HW ESTENSIONE DEL SEGNO, durante la fase di decodifica del codice operativo, ri-costruisce l’offset da 20 bit, lo prolunga fino a 64 bit mediante estensione del segno e aggiunge il bit 0 finale (meno significativo) sottointeso nella rappresentazione binaria dell’istruzione (nella figura si vede estensione a 32 bit). pertanto, prima di sommare l’offset al PC, il processore riporta a byte l’offset (già esteso in segno) tramite moltiplicazione per due(scorrimento a sx di una posizione e aggiunta di un bit 0 a dx). Dipende, posso utilizzare due convenzioni: RISC-V UTILIZZA LITTLE ENDIAN come endianess. N.b. il NOT è una pseudoistruzione
PRIMA PARTE
.text #indica che le linee successive contengono istruzioni o dati
.data #idem
.align n # indica l'allineamento su n byte
.globl main #etichetta main è globale,quindi visibile da altri file
.asciiz #area di memoria che memorizza una stringa terminata da NULL
x+NUMERO REGISTRO
----esempio----
x0 #indico il registro 0(che per default ha e mantiene il valore zero)
REGISTRI NON REFERENZIABILI hi, lo Registri per moltiplicazioni e divisioni pc Program Counter
esattamente che cosa fa l’istruzione, in aggiunta a quanto già indicato dal codice operativoSECONDA PARTE
Istruzioni aritmetico-logiche
add x2,x4,x7
sub x2,x4,x7 #x4-x7 e salva il tutto in x2
Trasferimento da o verso memoria
Pseudo-istruzioni
li t0 , 4 #carica la costante 4 in t0 (load immediate)
la a0, LABEL #carica l'indirizzo LABEL in a0 (load address)
Istruzioni di Salto
• identificato da uno
spiazzamento in CPL2: 12 bit per i formati B e I,
e
20 bit per il formato J
l’indirizzo di un’istruzione è a parola, ossia è sempre multiplo di 4
• convenzioni e operazioni HW apposite assicurano che la somma di
registro base
e spiazzamento
produca sempre un indirizzo di istruzione che sia multiplo di 4.formato beq, bne, bge, blt B jump & link: jal J jal da registro: jalr I
– rs1:primo operando sorgente
– rs2: secondo operando sorgente (dato da scrivere in memoria)
– funct3: indicano la variante specifica dell’istruzione per effettuare
il confronto tra rs1 e rs2
– imm[12:1]:valore ricostruito dello spiazzamento su 12 bit in CPL2
il modulo HW
ESTENSIONE DEL SEGNO, durante la fase di decodifica del codice operativo, ri-costruisce l’offset da 12 bit, lo prolunga fino a 64 bit mediante estensione del segno e aggiunge il bit 0 finale (meno significativo) sottointeso nella rappresentazione binaria dell’istruzione (nella figura si vede estensione a 32 bit).esempio: bne s0, s1, L1 #esegui e vai a L1 se il contenuto di s0 è != da quello di s1
– ⇒ il valore di L1 è calcolato rispetto al Program Counter in modo da saltare di 2^12 mezze parole avanti o indietro rispetto all’istruzione corrente
alla mezza parola relativo a PC: (L1− PC) / 2, dove
– PC contiene l’indirizzo dell’istruzione di salto
– la divisione per due serve per calcolare l’indirizzo di mezza parolaDichiarazione di una costante
•eqv NUM1, 200 # come "#define NUM1 100" in C
Come memorizzare una costante da 8 byte?
Altre istruzioni