Istruzioni MIPS e programmazione assembly

TITLE
Assembler MIPS 32
Assembly I
Riccardo Solmi
© 2002-2004 Alberto Montresor, Riccardo Solmi
1
Indice degli argomenti
ƒ Le istruzioni assembly MIPS
• Categorie di istruzioni assembly
• Istruzioni di caricamento e salvataggio
• Gestione del segno
• Ordine dei bytes (endianness)
• Modi di indirizzamento
• Istruzioni aritmetiche, logiche e di scorrimento
• Istruzioni di confronto e salto condizionato
• Istruzioni di salto non condizionato
© 2002-2004 Alberto Montresor, Riccardo Solmi
2
1
Categorie di istruzioni assembly
ƒ Le istruzioni del linguaggio assembly MIPS possono essere
divise nelle seguenti categorie:
• Istruzioni “Load and Store”
Queste istruzioni spostano dati tra la memoria e i registri
generali del processore
• Istruzioni “Load Immediate”
Queste istruzioni caricano nei registri valori costanti
• Istruzioni “Data Movement”
Queste istruzioni spostano dati tra i registri del processore
• Istruzioni aritmetico/logiche
Queste istruzioni effettuano operazioni aritmetico, logiche o
di scorrimento sui registri del processore
© 2002-2004 Alberto Montresor, Riccardo Solmi
3
Categorie di istruzioni assembly
• Istruzioni di salto condizionato
Queste istruzioni permettono di spostare l’esecuzione da un
punto ad un altro di un programma in presenza di certe
condizioni
• Istruzioni di salto non condizionato
Queste istruzioni permettono di spostare l’esecuzione da un
punto ad un altro di un programma
ƒ NOTA:
Nel seguito, le pseudoistruzioni sono evidenziate in blu e sottolineate
© 2002-2004 Alberto Montresor, Riccardo Solmi
4
2
Architettura load and store
ƒ L'architettura MIPS è di tipo Load-and-Store
• La maggioranza delle istruzioni MIPS operano tramite i
registri interni al processore
• Esempio:
add $t0, $t1, $t2
Somma $t1+$t2 e mette il risultato in $t0
• Per questo motivo
• LOAD: i dati da elaborare devono essere prelevati dalla
memoria
• STORE: i risultati devono essere salvati in memoria
© 2002-2004 Alberto Montresor, Riccardo Solmi
5
Istruzioni load and store
lb rdest, address
Load Byte at address in register rdest
lbu rdest, address
Load Byte Unsigned at address in register rdest
lh rdest, address
Load Halfword at address in register rdest
lhu rdest, address
Load Halfword Unsigned at address in register rdest
lw rdest, address
Load Word from address in register rdest
la rdest, address
Load computed Address in register rdest
sb rsource, address
Store lower Byte at address from register rsource
sh rsource, address
Store lower Halfword at address from register rsource
sw rsource, address
Store Word at address from register rsource
© 2002-2004 Alberto Montresor, Riccardo Solmi
6
3
Esempio istruzioni load and store
ƒ Esempio:
.text
# Inizia il codice
lw $t1, operandA
# Load operandA
lw $t2, operandB
# Load operandB
add $t0, $t1, $t2
# operandA + operandB
sw $t0, result
# Store result
.data
# Iniziano i dati
operandA: .word 5
operandB: .word 7
result: .word 0
7
© 2002-2004 Alberto Montresor, Riccardo Solmi
Istruzioni load con e senza segno (bytes)
ƒ
LB $t0, address
• Carica il byte indirizzato
da address nel byte meno
significativo del registro
Memoria
address
Registro $t0
-
-
- -
• Il bit di segno viene esteso
ƒ
LBU $t0, address
• Carica il byte indirizzato
da address nel byte meno
significativo del registro
Memoria
address
Registro $t0
0 0 0
• Gli altri tre byte vengono
posti a zero
© 2002-2004 Alberto Montresor, Riccardo Solmi
8
4
Istruzioni load con e senza segno (halfword)
ƒ
LH $t0, address
• Carica i 2 byte indirizzati
da address nei 2 byte meno
significativi del registro
Memoria
address
Registro $t0
-
- -
• Il bit di segno viene esteso
ƒ
LHU $t0, address
• Carica i 2 byte indirizzati
da address nei 2 byte meno
significativi del registro
Memoria
address
Registro $t0
0 0
• Gli altri due byte vengono
posti a zero
© 2002-2004 Alberto Montresor, Riccardo Solmi
9
Endianness
ƒ Definizione di endianness
• Come viene rappresentata una word (32 bit) in 4 byte di
memoria?
• Esistono due schemi:
• Little Endian: memorizza prima la "little end" (ovvero i
bit meno significativi) della word
• Big Endian: memorizza la "big end" (ovvero i bit più
significativi) della word
• Terminologia ripresa dai Viaggi di Gulliver di Jonathan
Swift, in cui due fazioni sono in lotta per decidere se le uova
sode devono essere aperte a partire dalla "little end" o dal
"big end" dell'uovo
© 2002-2004 Alberto Montresor, Riccardo Solmi
10
5
Endianness – Esempio
Memoria
ƒ Little endian
• Cosa succede se faccio uno
lh $t0, address?
address 12
Registro $t0
00 00 34 12
34
56
78
$t0 = 0x00003412
ƒ Big endian
• Cosa succede se eseguo
un'istruzione
lh $t0, address?
Memoria
address 12
$t0 = 0x00001234
Registro $t0
00 00 12 34
34
56
78
© 2002-2004 Alberto Montresor, Riccardo Solmi
11
Endianness
ƒ Nota:
• I processori x86 sono little-endian
• MIPS può essere little endian o big endian
• L'endianness di SPIM dipende dal sistema in cui viene
eseguito, quindi in generale è little endian
ƒ Quando bisogna affrontare i problemi di endianness?
• Quando si "mischiano" operazioni su 8, 16 e 32 bit.
• Quando invece si utilizzano operazioni uniformi, non vi
sono problemi di sorta
© 2002-2004 Alberto Montresor, Riccardo Solmi
12
6
Load word vs load address
ƒ Importante differenza:
• L'istruzione lw $t0, address carica il contenuto della
word indirizzata dall'etichetta address in memoria
• L'istruzione la $t0, address carica l'indirizzo della word
indirizzata dall'etichetta address in memoria
lw $t0, address
la $t0, address
Registro $t0
address
0x00400030
0x00400031
0x00400032
0x00400033
01
00
00
00
00 00 00 01
Registro $t0
address
0x00400030
0x00400031
0x00400032
0x00400033
01
00
00
00
00 40 00 30
13
© 2002-2004 Alberto Montresor, Riccardo Solmi
Load address vs load word
ƒ Quando utilizzare load address?
• Quando vogliamo caricare in un registro l'indirizzo di una
particolare zona di memoria
• Questo registro può essere utilizzato in seguito come indice
per leggere il contenuto di byte consecutivi in memoria
• Esempio:
la $t0, spese
loop:
# Carica l'indirizzo di spese
# Carica in $t1 il contenuto della word
# indirizzata da $t0
add $t2, $t2, $t1 # Fai la sommatoria
addi $t0, $t0, 4 # Incrementa $t0 di 4 byte (1 word)
bnez $t1, loop # Continua finché non trova 0
lw $t1, ($t0)
© 2002-2004 Alberto Montresor, Riccardo Solmi
14
7
Modi di indirizzamento
ƒ
Cos'è un modo di indirizzamento?
• Un modo per esprimere un indirizzo di memoria
• NB: alla fine il risultato è sempre un indirizzo di memoria dove andrò a
leggere (load) o scrivere (store) un dato.
ƒ
Nel linguaggio macchina MIPS, esiste un solo modo di indirizzamento
• imm(register) dove l’indirizzo è dato dalla somma del valore immediato
imm più il contenuto del registro register
• Esempio: lw $t0, 4($sp) (legge una word dall’indirizzo $sp + 4)
ƒ
L’assembler fornisce per comodità più modi di indirizzamento
• Un indirizzo si può esprimere come somma di:
una identificatore + una espressione + un registro.
• Esempio: lw $t1, array + 0x100($t0) (legge una word
dall’indirizzo 0x10010104 assumendo: array = 0x10010000 e $t0 = 4)
• Ogni parte: identificatore, espressione e registro è opzionale e per
ragioni storiche ogni combinazione ha il proprio nome (vedi lucidi
seguenti)
• In alcuni casi, l'assemblatore può generare più istruzioni
© 2002-2004 Alberto Montresor, Riccardo Solmi
15
Modi di indirizzamento
ƒ (base register)
• Specifica un indirizzo tramite registro base, assumendo un
offset 0.
• L'indirizzo è dato dal contenuto del base register
• Esempio: lw $t0,($a0)
ƒ expression
• Specifica un indirizzo assoluto con una espressione fatta
solo di somme e sottrazioni di costanti espresse in decimale
o esadecimale.
• L'indirizzo è dato dal risultato dell'espressione (costante).
• Esempio: lw $t0, 0x00400000+4
• I numeri negativi vanno comunque preceduti anche dal
simbolo +. Esempio: lw $t0, 0x100100c + -4
© 2002-2004 Alberto Montresor, Riccardo Solmi
16
8
Modi di indirizzamento
ƒ expression(base register)
• Specifica un indirizzo tramite registro base e un'offset
tramite un'espressione.
• L'indirizzo è dato dal contenuto del base register + il
risultato dell'espressione
• Esempio: lw $t0, 4($sp)
ƒ Relocatable-symbol
• Specifica un indirizzo (rilocabile) tramite un identificatore.
• L'assemblatore genera le istruzioni necessarie per gestire
l'identificatore e aggiunge al modulo oggetto generato le
informazioni di rilocazione.
• Esempio: lw $t0, operandA
© 2002-2004 Alberto Montresor, Riccardo Solmi
17
Modi di indirizzamento
ƒ Relocatable-symbol(index register)
• Specifica un indirizzo base tramite un identificatore, mentre
l'offset viene specificato tramite un registro indice
• L'indirizzo è dato dalla somma dell'indirizzo associato
all'identificatore con il contenuto del registro indice.
• Esempio: lw $t0, array($t1)
ƒ Relocatable-symbol + expression
• Specifica un indirizzo base tramite un identificatore, mentre
l'offset viene specificato tramite un'espressione
• L'indirizzo è dato dalla somma dell'indirizzo associato
all'identificatore con il risultato dell'espressione
• Esempio: lw $t0, array + 4
© 2002-2004 Alberto Montresor, Riccardo Solmi
18
9
Modi di indirizzamento
ƒ Relocatable-symbol + expression(index register)
• Specifica un indirizzo base tramite un identificatore, mentre
l'offset viene specificato tramite un registro indice e
un'espressione
• L'indirizzo è dato dalla somma dell'indirizzo associato
all'identificatore con il contenuto del registro indice e il
risultato dell'espressione.
• Esempio: lw $t0, array + 4($t1)
© 2002-2004 Alberto Montresor, Riccardo Solmi
19
Istruzioni Data Movement and Load Immediate
move rdest, rsource
Move register rsource into register rdest
li rdest, imm
Move the immediate imm into register rdest
© 2002-2004 Alberto Montresor, Riccardo Solmi
20
10
Istruzioni Aritmetiche: add, sub, neg, abs
add rd, rs, rt
rd = rs + rt (with overflow)
addu rd, rs, rt
rd = rs + rt (without overflow)
addi rd, rs, imm
rd = rs + imm (with overflow)
addiu rd, rs, imm
rd = rs + imm (without overflow)
sub rd, rs, rt
rd = rs - rt (with overflow)
subu rd, rs, rt
rd = rs - rt (without overflow)
neg rd, rs
rd = - rs (with overflow)
negu rd, rs
rd = - rs (without overflow)
abs rd, rs
rd = |rs|
© 2002-2004 Alberto Montresor, Riccardo Solmi
21
Istruzioni Aritmetiche: mul, div, rem
mul rd, rs, rt
rd = rs * rt (without overflow)
mulo rd, rs, rt
rd = rs * rt (with overflow)
mulou rd, rs, rt
rd = rs * rt (with overflow, unsigned)
div rd, rs, rt
rd = rs / rt (signed with overflow)
divu rd, rs, rt
rd = rs / rt (unsigned)
rem rd, rs, rt
rd = resto di rs / rt (signed)
remu rd, rs, rt
rd = resto di rs / rt (unsigned)
© 2002-2004 Alberto Montresor, Riccardo Solmi
22
11
Istruzioni Logiche: and, or, xor, not
and rd, rs, rt
rd = rs AND rt
andi rd, rs, imm
rd = rs AND imm
or rd, rs, rt
rd = rs OR rt
ori rd, rs, imm
rd = rs OR imm
xor rd, rs, rt
rd = rs XOR rt
xori rd, rs, imm
rd = rs XOR imm
not rd, rs
rd = NOT rs
NB. XOR è un OR esclusivo. 1 XOR 1 = 0 mentre 1 OR 1 = 1.
© 2002-2004 Alberto Montresor, Riccardo Solmi
23
Istruzioni di scorrimento
sll rd, rs, rt
rd = rs shifted left rt mod 32 bits
srl rd, rs, rt
rd = rs shifted right rt mod 32 bits
sra rd, rs, rt
rd = rs shifted right rt mod 32 bits (signed)
rol rd, rs, rt
rd = rs rotated left rt mod 32 bits
ror rd, rs, rt
rd = rs rotated right rt mod 32 bits
Note:
rt può anche essere una costante es. sll $t1, $t2, 4
Shift perde dei bits da una parte e dall’altra inserisce degli zero
Rotate inserisce da una parte i bit che escono dall’altra
Left[right] sposta i bit verso quelli più[meno] significativi
© 2002-2004 Alberto Montresor, Riccardo Solmi
24
12
Istruzioni immediate
ƒ Versioni immediate (i)
• Le versioni immediate (i) delle istruzioni precedenti
utilizzano un valore costante (risultato di un'espressione) al
posto di uno degli operandi
• Non sempre è necessario specificare la i; l'assemblatore è in
grado di riconoscere anche istruzioni come
add $t0, $t0, 1
© 2002-2004 Alberto Montresor, Riccardo Solmi
25
Istruzioni di salto condizionato
beqz rs, target
Branch to instruction at target if rs = 0
bnez rs, target
Branch to instruction at target if rs ≠ 0
bgez rs, target
Branch to instruction at target if rs ≥ 0
bgtz rs, target
Branch to instruction at target if rs > 0
blez rs, target
Branch to instruction at target if rs ≤ 0
bltz rs, target
Branch to instruction at target if rs < 0
NB. b sta per branch; z sta per zero;
eq = ugual; ne = not equal; ge = greater or equal; gt = greater than;
le = less or equal; lt = less that
© 2002-2004 Alberto Montresor, Riccardo Solmi
26
13
Istruzioni di salto condizionato
beq rs, rt, target
Branch to instruction at target if rs = rt
bne rs, rt, target
Branch to instruction at target if rs ≠ rt
bge rs, rt, target
Branch to instruction at target if rs ≥ rt
bgeu rs, rt, target
Branch to instruction at target if rs ≥ rt (unsigned)
bgt rs, rt, target
Branch to instruction at target if rs > rt
bgtu rs, rt, target
Branch to instruction at target if rs > rt (unsigned)
ble rs, rt, target
Branch to instruction at target if rs ≤ rt
bleu rs, rt, target
Branch to instruction at target if rs ≤ rt (unsigned)
blt rs, rt, target
Branch to instruction at target if rs < rt
bltu rs, rt, target
Branch to instruction at target if rs < rt (unsigned)
27
© 2002-2004 Alberto Montresor, Riccardo Solmi
Branch: dettagli implementativi
ƒ Nel linguaggio macchina, l’indirizzo dell’istruzione target in
un branch viene espresso come instruction offset rispetto
all’istruzione corrente
• E’ possibile saltare 215-1 istruzioni in avanti o 215 istruzioni
indietro
ƒ In linguaggio assembly, l’indirizzo dell’istruzione target è
dato dall’etichetta associata
• Il calcolo viene fatto automaticamente dall’assembler
• Ulteriore semplificazione dell’assembler rispetto al
linguaggio macchina
ƒ Esempio:
0x00400030 beq $5, $4, 8 [stor-0x00400030]
© 2002-2004 Alberto Montresor, Riccardo Solmi
beq $a1, $a0, stor
28
14
Istruzioni di salto non condizionato
Unconditionally jump to instruction at target
j target
jal target
jr rsource
Unconditionally jump to instruction at target, and
save the address of the next instruction in register
$ra
Unconditionally jump to the instruction whose
address is in register rsource
jalr rsource, rdest
Unconditionally jump to the instruction whose
address is in register rsource and save the address
of the next instruction in register rdest
© 2002-2004 Alberto Montresor, Riccardo Solmi
29
Indice degli argomenti
ƒ Programmazione assembly
• Realizzazione delle principali strutture di controllo
• sequenze
• scelte
• ripetizioni
• Scrittura di semplici programmi assembly:
• operazioni su stringhe
• input e output su console
© 2002-2004 Alberto Montresor, Riccardo Solmi
30
15
Sequenze di istruzioni
ƒ Le istruzioni formano sempre una sequenza che corrisponde
all’ordine in cui vengono eseguite
• Il microprocessore non ha una visione di insieme del
programma: “vede” solo l’istruzione che deve eseguire e il
contenuto dei registri.
• Esegue una istruzione alla volta nell’ordine scritto in memoria
ƒ Fanno eccezione le istruzioni di salto che fanno proseguire
l’esecuzione all’indirizzo specificato.
• L’istruzione che viene eseguita dopo un salto è quella che si
trova all’indirizzo specificato come destinazione del salto.
• Se il salto è condizionato e la condizione è falsa si prosegue
normalmente con l’istruzione successiva.
31
© 2002-2004 Alberto Montresor, Riccardo Solmi
Sequenze di istruzioni e salti
ƒ L’intero programma è una sequenza
di istruzioni; con i salti posso
controllare l’ordine di esecuzione
lw $t0,x
lw $t1,y
j j1
• Il codice seguente è equivalente a
j2:neg $t2,$t2
quello sulla destra
add $t3,$t3,$t2
lw $t0,x
lw $t1,y
j j3
add $t2,$t0,$t1
j1:add $t2,$t0,$t1
mul $t3,$t0,$t1
mul $t3,$t0,$t1
neg $t2,$t2
j j2
add $t3,$t3,$t2
sw $t0,x
j3:sw $t0,x
sw $t1,y
sw $t1,y
© 2002-2004 Alberto Montresor, Riccardo Solmi
32
16
Saltare per scegliere: if
ƒ
Voglio eseguire del codice solo se una condizione (espressione) è vera
1.
2.
3.
ƒ
Codice per valutare l’espressione e mettere il risultato in un registro (o due)
Salto condizionato per saltare il codice opzionale se la condizione è falsa
Codice opzionale da eseguire solo quando la condizione è vera
Esempio in assembly: (ifelse.s)
• Se x > 0 allora y = x*2 (altrimenti y resta invariato cioè uguale a 0)
.text
.globl main
main:
lw $t0,x
blez $t0,endif
mul $t1,$t0,2
sw $t1,y
endif:
.data
x: .word 5
y: .word 0
#
#
#
#
#
Carica x
Salto se condizione falsa
codice opzionale: $t1 = x*2;
Salva $t1 nella variabile y
Fine if
# provare con 5 e -5
# y = x*2 se x>0 altrimenti y = 0
33
© 2002-2004 Alberto Montresor, Riccardo Solmi
Saltare per scegliere: if else
ƒ
Voglio eseguire del codice diverso se una condizione (espressione) è vera
oppure falsa
1.
Codice per valutare l’espressione e mettere il risultato in un registro (o due)
2.
Salto condizionato per saltare il “ramo then” se la condizione è falsa
3.
Codice da eseguire solo quando la condizione è vera (ramo then)
4.
Salto per evitare di eseguire anche il ramo else
5.
Codice da eseguire solo quando la condizione è falsa (ramo else)
NB. Posso scambiare i due rami (punti 3 e 5) se salto quando la condizione è vera
ƒ
Esempio in assembly: (ifelse.s)
•
Se x > 0 allora y = x*2 altrimenti y = -x
lw $t0, x
blez $t0, else
mul $t1,$t0,2
j end
else:neg $t1, $t0
end: sw $t1, y
© 2002-2004 Alberto Montresor, Riccardo Solmi
#
#
#
#
#
#
Carica x
Salto se la condizione è falsa
Ramo then: $t1 = x*2;
Salta fine
Ramo else: $t1 = -x;
Scrive $t1 in y
34
17
Saltare per scegliere: if annidati
ƒ
ƒ
Le scelte possono essere annidate a piacere
•
Si dice condizione annidata una che si trova nel ramo then o nel ramo
else di una scelta “contenitore”
•
Una condizione annidata nel ramo then è del tipo:
se condizione1 è vera allora:
se condizione2 è vera esegui solo codice1
altrimenti esegui solo codice2; (ramo then)
altrimenti (condizione1 falsa) esegui solo codice3
•
Una condizione annidata nel ramo else è del tipo:
se condizione1 è vera esegui solo codice1
altrimenti se condizione2 è vera esegui solo codice2
altrimenti esegui solo codice3 (ramo else)
•
Posso annidare le condizioni fino alla profondità che mi serve su ogni
ramo. (il codice naturalmente diventa sempre più complesso)
Per farlo in assembly mi basta applicare ricorsivamente i due
schemi di soluzione già visti nei due lucidi precedenti
35
© 2002-2004 Alberto Montresor, Riccardo Solmi
Esempio su if annidati
ƒ Esempio in assembly: (ifelse.s)
•
Se x > 0 allora (ramo then 1 che contiene scelta annidata)
se y >= 0 allora y = x*2 (ramo then 2)
altrimenti y = -x (ramo else 2)
altrimenti incrementa y (ramo else 1)
lw $t0,x
# Carica x
lw $t1,y
# Carica y
blez $t0,else1
# Salta se la cond1 è falsa
bltz $t1,else2
# Salta se la cond2 è falsa
mul $t1,$t0,2
# Ramo then2: $t1 = x*2
j end
# Salta fine
else2:neg $t1,$t0
# Ramo else2: $t1 = -x
j end
# Salta fine
else1:addi $t1,$t1,1 # Ramo else1: $t1 = y + 1
end: sw $t1, y
# Scrive $t1 in y
© 2002-2004 Alberto Montresor, Riccardo Solmi
36
18
Saltare per scegliere: switch
ƒ
Caso particolare del precedente: le condizioni davanti ad ogni ramo
testano valori diversi di una stessa variabile
• Posso usare degli if annidati come sopra oppure mi faccio una tabella
con i riferimenti a tutti i codici dei rami e uso la variabile come indice
per caricare dalla tabella l’indirizzo del codice dove saltare.
• Il miglioramento che si ottiene è che viene fatto un solo test anziché uno
per ogni ramo, riducendo la complessità da lineare a costante.
ƒ
Esempio in assembly: (switch.s)
• se op = 0 allora y = x*3
se op = 1 allora y = x+5
se op = 2 allora y = -x
altrimenti y = x
© 2002-2004 Alberto Montresor, Riccardo Solmi
37
Esempio su switch
ƒ
Esempio in assembly: (switch.s)
lw $t1,x
lw $t0,op
bge $t0,3,default # Salta a default se op >= 3
sll $t0,$t0,2
# $t0 = op*4
lw $t0,stable($t0) # $t0 = (stable+op*4)
jr $t0
# Salta al case corrispondente a op
case0:mul $t2,$t1,3 # $t2 = x*3
j end
case1:addi $t2,$t1,5 # $t2 = x+5
j end
case2:div $t2,$t1,2 # $t2 = x/2
j end
default: move $t2,$t1 # $t2 = x
end:sw $t2,y
# Scrive $t2 in y
.data # oltre a op, x e y
stable: .word case0,case1,case2
© 2002-2004 Alberto Montresor, Riccardo Solmi
38
19
Saltare per ripetere: while
ƒ
Voglio eseguire più volte del codice finché una espressione è vera. Non so se
l’espressione è vera all’inizio (quindi la controllo prima di eseguire il codice)
ƒ
1.
Codice per valutare l’espressione e mettere il risultato in un registro (o due)
2.
Salto condizionato per saltare il codice da ripetere se la condizione è falsa
3.
Codice da ripetere finché la condizione è vera
4.
Salto al punto 1 in modo da poter eseguire il codice un’altra volta oppure
Salto condizionato al punto 3 per eseguire un’altra volta se la condizione è vera
Esempio in assembly: (loops.s)
•
Finché x > 0 lo sommo a y (y = y + x) e lo decremento (x = x – 1)
lw $t0,x
lw $t1,y
blez $t0,end
while:
add $t1,$t1,$t0
sub $t0,$t0,1
bgtz $t0,while
end:sw $t1,y
#
#
#
#
#
#
#
#
Carica x
Carica y
Salta se condizione è falsa
(Inizio ciclo)
Effettua sommatoria
Sottrae uno
Riesegue ciclo finché cond. vera
Salva risultato in y
39
© 2002-2004 Alberto Montresor, Riccardo Solmi
Saltare per ripetere: do while
ƒ
Voglio eseguire più volte del codice finché una espressione è vera. So che
all’inizio l’espressione è vera (quindi eseguo il codice e poi controllo)
Inizializzo i registri che mi servono prima di iniziare il ciclo
1. Codice da ripetere finché la condizione è vera
2. Codice per valutare l’espressione e mettere il risultato in un registro (o due)
3. Salto condizionato al punto 1 per eseguire un’altra volta se la condizione è vera
ƒ
Esempio in assembly: (loops.s)
•
Finché x > 0 lo sommo a y (y = y + x) e lo decremento (x = x – 1)
lw $t0,x
lw $t1,y
dowhile:
add $t1,$t1 $t0
sub $t0,$t0,1
bgtz $t0,dowhile
sw $t1,y
© 2002-2004 Alberto Montresor, Riccardo Solmi
#
#
#
#
#
#
#
Carica x
Carica y
(Inizio ciclo)
Effettua sommatoria
Decrementa x
Riesegue ciclo finché cond. vera
Salva risultato in y
40
20
Saltare per ripetere: for
ƒ
Voglio eseguire del codice per un certo numero di volte; voglio anche
poter usare l’indice (numero di volte eseguite) nel codice.
Inizializzo i registri che mi servono prima di iniziare il ciclo (compreso l’indice)
1. Codice da ripetere il numero stabilito di volte
2. Incremento il registro usato come indice
3. Salto condizionato al punto 1 per eseguire un’altra volta se la condizione è vera
ƒ
Esempio in assembly: (loops.s)
•
Per 5 volte (contando da 1 a 5) sommo l’indice a y (y = y + x)
li $t0,1
lw $t1,y
loop:
add $t1,$t1,$t0
addi $t0,$t0,1
ble $t0,5,loop
sw $t1,y
#
#
#
#
#
#
#
Inizializza indice
Carica y
(Inizio ciclo)
Effettua sommatoria
Incrementa indice
Continua ciclo se <= 5 volte
Salva risultato in y
© 2002-2004 Alberto Montresor, Riccardo Solmi
41
Esercizi guidati su stringhe
ƒ length.s
• Scrivere un programma che calcoli la lunghezza di una
stringa. Esempio: “ciao” è lunga 4
ƒ count.s
• Scrivere un programma che calcoli il numero di occorrenze
di un carattere in una stringa. Esempio: “a” in “abbac” è 2
ƒ reverse.s
• Scrivere un programma che data una stringa ne produce una
scritta al contrario.
Es. “assembly MIPS” deve diventare: “SPIM ylbmessa”
• E' possibile scrivere un algoritmo che lavori "sul posto"
© 2002-2004 Alberto Montresor, Riccardo Solmi
42
21
Esercizio guidato: length.s
.text
.globl main
main:
# inizializzo un puntatore alla stringa
# e un contatore per la lunghezza
# finché non arrivo alla fine della stringa (0)
# incremento il contatore
# e faccio avanzare il puntatore
strEnd: sw $t1, result # scrivo il risultato
jr $ra
.data
str:
.asciiz "hello world!!"
result: .word 0
© 2002-2004 Alberto Montresor, Riccardo Solmi
43
Esercizio guidato: count.s
.text
.globl main
main:
# inizializzo un puntatore alla stringa
# un contatore per le occorrenze del carattere
# e il carattere da contare
# finché non arrivo alla fine della stringa (0)
# faccio avanzare il puntatore
# e se è uguale al carattere che cerco
# incremento il contatore delle occorrenze
strEnd: sw $t2, result
# scrivo il risultato
jr $ra
.data
str:
.asciiz "abceebceebeebbacacb"
char:
.asciiz "a"
result: .word 0
© 2002-2004 Alberto Montresor, Riccardo Solmi
44
22
Esercizio guidato: reverse.s
.text
.globl main
main:
# inizializzo due indici per puntare l'inizio e la fine della stringa
# sposto il secondo indice fino alla fine della stringa
# scambio i due caratteri puntati dagli indici
# e faccio avanzare gli indici (verso il centro della stringa)
# finché non ho scambiato tutto
end:
jr $ra
str:
.asciiz "0123456789" # provare anche "assembly MIPS"
.data
© 2002-2004 Alberto Montresor, Riccardo Solmi
45
Chiamate a funzioni del sistema operativo
ƒ SPIM fornisce un piccolo insieme di servizi “operatingsystem-like” attraverso l’istruzione syscall
ƒ Per richiedere un servizio:
• Si carica il numero che identifica il servizio nel registro $v0
• Eventuali argomenti vengono caricati nei registri $a0-$a1
• Eventuali risultati vengono collocati dalla chiamata di
sistema nel registro $v0
ƒ Esempio
li $v0,1
# Numero che identifica print_int
li $a0,5
# 5 è l’argomento da stampare
syscall
# procedi alla stampa
© 2002-2004 Alberto Montresor, Riccardo Solmi
46
23
Elenco System Call disponibili
Service
Code
Arguments
Results
print_int
1
$a0 = integer
print_float
2
$f12 = float
print_double
3
$f12 = double
print_string
4
$a0 = string
read_int
5
integer in $v0
read_float
6
float in $f0
read_double
7
double in $f0
read_string
8
$a0=buffer,
$a1=length
sbrk
9
$a0=amount
exit
10
address in $v0
47
© 2002-2004 Alberto Montresor, Riccardo Solmi
Esempio sulle system calls
.text
#... continua
.globl main
main:
li $v0,4
li $v0, 10
# exit
syscall
# termina programma
# print_string
la $a0,prompt
.data
syscall
# stampa il prompt
li $v0,8
# read_string
prompt: .asciiz "Come ti chiami: "
msg:
.ascii "ciao "
buffer: .space 256
la $a0,buffer
li $a1,256
syscall
# legge un nome
li $v0,4
# print_string
la $a0,msg
syscall
# stampa "ciao " + nome
© 2002-2004 Alberto Montresor, Riccardo Solmi
48
24
Esercizio
ƒ Scrivere un programma in assembly MIPS che:
• Mostra un menu con tre possibilità:
• 1) Lunghezza
Chiede un stringa e scrive la sua lunghezza;
dopo mostra di nuovo il menu
• 2) Occorrenze
Chiede una stringa e una lettera e scrive quante volte
compare la lettera nella stringa;
dopo mostra di nuovo il menu
• 3) Esci
Termina l’esecuzione del programma
• … e un prompt: Scegli (1,2,3):
© 2002-2004 Alberto Montresor, Riccardo Solmi
49
25