L'operazione si chiama shift left logical e si indica con sll
.
Non è altro che l'operazione di shift a sinsitra.sll x9, x22, x19
(shift di una sola posizione)
x9 = x22 << x19
Versione immediata: shift left logical immediateslli x9, x22, 5
(shift di 5 posizioni)
x9 = x22 << 5
L'operazione si chiama shift right logical e si indica con srl
.
Non è altro che l'operazione di shift a sinsitra.srl x9, x22, x19
(shift di una sola posizione)
x9 = x22 >> x19
Versione immediata: shift right logical immediatesrli x9, x22, 5
(shift di 5 posizioni)
x9 = x22 >> 5
Lo shift aritmetico è uguale allo shift logico, solo che con questa operazione, il bit più significativo viene mantenuto, mentre quello meno significativo viene sostituito con un bit nullo (0).
sll
)Può essere sia positivo, quando il bit più significativo è 0, o negativo, quando il bit più significativo è 1.
L'operazione si chiama shift right arithmetic e si indica con sra
ed srai
la sua versione immediata.sra x9, x22, x19
x9 = x22 >> x19
srai x9, x22, 5
x9 = x22 >> 5
Le istruzioni sll
, srl
, sra
si rappresentano in linguaggio macchina con il formato R. Mentre slli
, srli
, srai
si rappresentano in linguaggio macchina con il formato I (vengono utilizzati 6 bit meno significativi del campo immediato per codificare la costante, gli altri sono posti a zero).
Come sappiamo lo shift a sinistra di i
posizioni calcola una moltiplicazione per i
posizioni calcola una divisione intera per
long i, j;
long v[10];
// altro codice
v[i] = v[j];
long i, j;
long v[10];
// altro codice
v[i] = v[j];
Posti: i = x9; j =x21; v = x19;
//v[j]
addi x6, x21, 0
slli x6, x6, 3
add x6, x6, x19
ld x6, 0(x6)
//v[i]
addi x7, x9, 0
slli x7, x7, 3
add x7, x7, x19
sd x6, 0(x7)
//v[j]
addi x6, x21, 0
slli x6, x6, 3
add x6, x6, x19
ld x6, 0(x6)
//v[i]
addi x7, x9, 0
slli x7, x7, 3
add x7, x7, x19
sd x6, 0(x7)
long i, j;
long v[10];
// altro codice
v[i] = v[j];
Posti: i = x9; j =x21; v = x19;
//v[j]
addi x6, x21, 0
slli x6, x6, 3
add x6, x6, x19
ld x6, 0(x6)
//v[i]
addi x7, x9, 0
slli x7, x7, 3
add x7, x7, x19
sd x6, 0(x7)
=== end-multi-column
NOTA il codice assembly si riferisce SOLO all'assegnamento
v[i] = v[j]
.
Per calcolare v[j]
:
j è una variabile che contiene un valore.
Con la prima riga di assembly, viene salvato il contenuto di x21 nel registro x6.
Viene fatto uno shift a sinistra (ovvero una moltiplicazione per
Perché viene fatta questa cosa?
x6 prende il valore di x21 (
j
), sapendo di doversi spostare alla j-esima posizione di memoria del vettorev
e sapendo chev
è un vettore dilong
, il che vuol dire che ogni posizione dell'arrayv
avrà dimensione di una double word, che è 8 byte e che è, allora viene fatto uno shift a sinistra di 3. É come se j indicasse il numero della posizione all'interno di v
, ma bisogna far in modo che ogni posizione sia grande.
Infatti nella riga:add x6, x6, x19
: x6 viene utilizzato come scostamento all'interno di x19 (che ricordiamo salva solo l'indirizzo base div
, ovverov[0]
). A questo punto x6 contiene l'indirizzo esatto di della posizionej
div
.
Infatti nella riga: add x6, x6, x19
: x6 viene utilizzato come scostamento all'interno di x19 (che ricordiamo salva solo l'indirizzo base di v
, ovvero v[0]
). Questa operazione salva in x6, la somma tra x19 e x6, ovvero, a questo punto x6 contiene l'indirizzo esatto di della posizione j
di v
.
Nella riga: ld x6, 0(x6)
: viene fatto un caricamento dalla memoria:
0(x6)
che non è altro che v[j]
.v[j]
Operazioni analoghe vengono fatte per v[i]
usando come registro x7.
Ultima riga da analizzare: sd x6, 0(x7)
, x7 contiene l'indirizzo della posizione i
di v
.
La riga assembly effettua uno store in memoria:
v[j]
)v[i]
.NOTA: nella parte di codice per v[i]
manca il load dalla memoria, che consente ad x6 di contenere il valore di v[j]
e non il suo indirizzo, come invece è per x7, in cui questa operazione di caricamento dalla memoria non viene fatta.