Sei sulla pagina 1di 57

3/8/03

Linguaggio Assembler

Andrea Coccoli
A.Coccoli@guest.cnuce.cnr.it

Indice
• Linguaggio ad alto livello, linguaggio assembler e
linguaggio macchina
• Il linguaggio assembler MIPS: istruzioni aritmetiche, di
trasferimento dati e di salto
• Conversione linguaggio assembler in linguaggio macchina
• Gestione delle procedure. Uso della pila
• Modi di indirizzamento
• Sintassi di un programma in assembler MIPS
• SPIM
• Confronto con altre architetture: PowerPC e Intel 80x86

1
3/8/03

Intr oduzione

• le CPU lavorano con linguaggio macchina


– sequenza di cifre binarie
• Il linguaggio assembler e’ la rappresentazione
simbolica (mnemonica) della codifica binaria usata dal
calcolatore (linguaggio macchina)
– simboli al posto di bit
– codici delle istruzioni (opcodes)
– registri
– uso di etichette
– macro
• La codifica binaria delle istruzioni si trova in memoria

Linguaggio m acchina

• Si intende l’insieme delle operazioni direttamente


eseguibili dall’hardware
• Ogni operazione e’ richiesta da un’istruzione
• Un insieme di istruzioni costituisce un programma
• ogni istruzione deve specificare che tipo di operazione
e’ richiesta e quali sono i suoi operandi

2
3/8/03

Linguaggio assembler
• Più primitivo dei linguaggi di alto livello
e.g., manca un controllo di flusso sofisticato
• Molto restrittivo
e.g., Istruzioni Aritmetiche del MIPS
• Noi lavoreremo con l’architettura del set di istruzioni MIPS
– simile ad altre architetture sviluppate a partire dagli anni ‘80
– usata da NEC, Nintendo, Silicon Graphics, Sony
• Obiettivi di Progetto: massimizzare la performance e
minimizzare il costo, ridurre il tempo di progettazione

.text
.align 2
.globl main
main: 00100111101111011111111111100000
subu $sp, $sp, 32 10101111101111110000000000010100
sw $ra , 20($sp ) 10101111101001000000000000100000
Programma che ca lcola e sta mpa sd $a0, 32($ sp) 10101111101001010000000000100100
sw $0, 24($ sp) 10101111101000000000000000011000
la so mma dei q uad rati dei pri mi 100 i nteri sw $0, 28($ sp) 10101111101000000000000000011100
loop: 10001111101011100000000000011100
lw $t6, 28($ sp) 10001111101110000000000000011000
mul $t7, $t6, $t 6 00000001110011100000000000011001
#inclu de <stdi o.h> lw $t8, 24($ sp) 00100101110010000000000000000001
addu $t9, $t8, $t 7 00101001000000010000000001100101
int main (int argc, char *a rgv[]) w $t9, 24($ sp) 10101111101010000000000000011100
{ addu $t0, $t6, 1 00000000000000000111100000010010
int i; sw $t 0, 28($sp) 00000011000011111100100000100001
int sum = 0 ; ble$t 0, 100, loop 00010100001000001111111111110111
for (i = 0; i <= 1 00; i = i + 1) sum = sum + i * i ; la $a0, str 10101111101110010000000000011000
printf ("The sum from 0 .. 100 is %d\n", sum); lw $a1, 24($sp) 00111100000001000001000000000000
jal printf 10001111101001010000000000011000
} move$v0, $0 00001100000100000000000011101100
lw $ra, 20($sp) 00100100100001000000010000110000
ddu $sp , $sp, 32 10001111101111110000000000010100
jr $ra 00100111101111010000000000100000
.data 00000011111000000000000000001000
.align 0 00000000000000000001000000100001
str:
.asciiz "The sum from 0 .. 100 is %d\ n"
6

3
3/8/03

Gerarchia di trasformazione
Programma in C

Compilatore

Programma in linguaggio assembler

Assemblatore

Modulo oggetto: Linguaggio macchina Modulo oggetto: Librerie

Linker

Eseguibile

Loader

Memoria

Gerarchia di trasformazione

Un programma scritto in linguaggio ad alto livello viene:


• compilato in linguaggio assembler
• assemblato per ottenere un modulo oggetto in linguaggio
macchina
• il linker combina uno o più moduli oggetto con le
procedure contenute nelle librerie per esplicitare tutti i
riferimenti incrociati
• il loader colloca il codice macchina in opportune
locazioni di memoria in modo che possa essere eseguito
dal processore.
8

4
3/8/03

Vantaggi e svantaggi del linguaggio assem bler

• Vantaggi
– velocità d’esecuzione (es.: calcolatori embedded)
– occupazione di memoria
– collegabile a programmi ad alto livello
– possibilità di usare istruzioni specializzate
• Svantaggi
– minore portabilità
– fattore di espansione elevato => minore produttività
– minore leggibilità
– no programmazione strutturata
• Nota: la performance deve essere valutata sulle
istruzioni reali
9

Gli assemblatori

• Il processo di traduzione e’ costituito da due parti:


– traduzione in indirizzi delle locazioni di memoria etichettate
– traduzione istruzioni assembler (c odice operativo, identificatori di
registri, etichette) in istruzione macc hina

• File oggetto
– etichetta esterna (o globale)
– etichetta locale (funzione static in C)
• Riferimenti in avanti => tabella dei simboli.

10

5
3/8/03

Il formato del file oggetto

• E’ composto da 6 parti
– Intestazione del file oggetto,
– Segmento di testo,
– Segmento di dato,
– Informazioni di rilocazione,
– Tabella dei simboli,
– Informazioni per il debugger
• Funzionalità aggiuntive
– direttive per la codifica dei dati
– macro

11

Linker - Loader - Uso della m emoria


• Compilazione separata => diversi moduli
• Il linker unisce i files:
– cerca le procedur e usate nelle librerie
– riloca i file oggetto
– risolve i riferimenti tra files
• Il loader (in unix):
– lettura dell’intestazione del file eseguibile per determinare la sua
dimensione
– creazione di uno spazio di indirizzamento sufficiente
– copia delle istruzioni e dei dati dal file eseguibile alla memoria
– copia nello stack degli eventuali parametri passati al programma
principale
– inizializzazione dei registri dell’elaboratore (es. stack pointer,…)
– salto ad una procedur a di inizializzazione (start-up routine) che
chiama la procedura principale del programma (main) 12

6
3/8/03

Aritm etica MIPS


• Tutte le istruzioni hanno 3 operandi
• Una linea può contenere una sola istruzione
• L’ordine degli operandi e’ fissato (destinazione per prima)
• Forma:
operatore operando1, operando2, operando3
• Significato:
operando1 = operando2 operatore operando3
• Esempio:
codice MIPS : add $s0, $s1, $s2
codice C : a = b + c

13

Aritm etica MIPS


• Principio di progetto1: semplificare per favorire la
regolarità
• Svantaggi della regolarità
C code: a = b + c + d;
e = f - a;

MIPS code: add $t0, $s1, $s2


add $s0, $t0, $s3
sub $s4, $s5, $s0

• Gli operandi devono essere registri


– solo 32 registri da 4Bytes (= 1 Word)
• Principio di progetto2: dimensioni minori => maggiore
velocità
14

7
3/8/03

Convenz ioni sull’uso dei registr i


Registro: locazione di memoria elementare all’interno del processore

Nome Numero Uso


$zero 0 il valore costante 0
$v0-$v1 2-3 valori per risultati di espressioni
$a0-$a3 4-7 argomenti
$t0-$t7 8-15 temporanei
$s0-$s7 16-23 salvati
$t8-$t9 24-25 altri temporanei
$gp 28 global pointer
$sp 29 stack pointer
$fp 30 frame pointer
$ra 31 return address
$at 1 riservato
$k0 26 riservato
$k1 27 riservato

15

Moltiplicazione e divisione
• Coppia di registri 32 bit (Hi,Lo) che contengono il prodotto
di una moltiplicazione (mult $s2,$s3) ed il resto ed il
quoziente, rispettivamente, di una divisione (div $s2,$s3).
• Istruzioni mflo,mfhi per acce dere ai registri Hi e Lo
• Esempio:
– mult $s2,$s3
– mflo $s1 #$s1 = Lo (copia di Lo in $s1)
• Compito del programmatore evitare l’overflow e controllare che
non ci siano divisioni improprie (per zer o).
Istruzione Esempio Significato Commenti
move from Hi mfhi $s1 $s1 = Hi Copia Hi in $s1
move from Lo mflo $s1 $s1 = Lo Copia Lo in $s1
move to Hi mthi $s1 Hi = $s1 Copia $s1 in Hi
move to Lo mtlo $s1 Lo = $s1 Copia $s1 in Lo
16

8
3/8/03

Overflow
• Il risultato dell’operazione non e’ rappresentabile
dall’hw disponibile
• I numeri rappresentabili sono
– da 0 a (232 -1) (unsigned)
– da -231 a (231-1) (signed)
• Condizioni di overflow (numeri signed):
– A>0; B>0 e si ottiene A+B<0
– A<0; B<0 e si ottiene A+B≥0
– A ≥0; B<0 e si ottiene A-B<0
– A<0;B ≥0 e si ottiene A-B ≥0
• Le operazioni addu,subu,mult, multu, div e divu
non fanno alcun controllo sull’overflow
17

Istruzioni Aritmetiche
Istruzione Esempio Significato Commenti

add add $s1,$s2,$s3 $s1 = $s2 + $s3 3 operandi; eccezione possibi le


add immediate addi $s1,$s2,100 $s1 = $s2 + 100 + cost; eccezione possibile
add unsigned addu $s1,$s2,$s3 $s1 = $s2 + $s3 3 operandi; nessuna eccezione
add imm. unsign. addiu $s1,$s2,100 $s1 = $s2 + 100 + costante; nes suna eccezione
subtract sub $s1,$s2,$s3 $s1 = $s2 – $s3 3 operandi; eccezione possibi le
subtract unsigned subu $s1,$s2,$s3 $s1 = $s2 – $s3 3 operandi; nessuna eccezione
multiply mult $s2,$s3 Hi, Lo = $s 2 x $s3 64-bit prodotto con s egno
multiply unsi gned multu $s2,$s3 Hi, Lo = $s 2 x $s3 64-bit prodotto senza segno
divide div $s2,$s3 Lo = $s 2 ÷ $s3, Lo = quoziente, Hi =
resto
Hi = $s2 mod $s3
divide unsigned divu $s2,$s3 Lo = $s 2 ÷ $s3, Quoziente & res to senza segno
Hi = $s2 mod $s3
shift right arit. sra $s 1,$s2,10 $s1 = $s2 >> 10 Shift a destra (segno esteso)
shift right arit.var. srav $s 1,$s2, $s3 $s1 = $s2 >> $s3 Shift aritm. a destra di # bi t 18
var.

9
3/8/03

Qualche esem pio (NB: non assem bler puro)


• Esempio1
#a = b + c + d + e
add a, b, c #a = b + c
add a, a, d #a = a + d
add a, a, e #a = a + e

• Esempio2
#f = (g + h) - (i + j)
add $t0, g, h #$t0 = g + h
add $t1, i, j #$t1 = i + j
sub f, $t0, $t1 #f = $t0 - $t1

19

Registri e Memoria
• Le istruzioni aritmetiche Control Input
Memory
operano su registri Datapath Output
– solo 32 registri
Processor I/O
– ogni registro 1W (4B )

• il compilatore associa
0 8 bits of data
variabili con registri 1 8 bits of data
• Cosa succede con 2 8 bits of data

programmi con tanti dati 3 8 bits of data


4 8 bits of data
(variabili, array)?
5 8 bits of data
– usiamo la memoria, che
contiene anche i programmi 6 8 bits of data
– Memoria MIPS indirizzata al Byte ...

20

10
3/8/03

Indir izzam ento al byte


• E’ l’indirizzamento usato dalla maggior parte delle
architetture
• MIPS:
– le parole iniziano sempre ad indirizzi multipli di 4 (vincolo di
allineamento)
– Indirizzo = indirizzo base + offset x 4
• Ordinamento dei byte in memoria
– big endian (MIPS, Sparc, Motorola 68k)
l’indirizzo di una parola corrisponde all’indirizzo del byte più
significativo
– little endian (Intel 80x86, DEC Alpha)
l’indirizzo di una parola corrisponde indirizzo del byte meno
significativo

21

Or dinamento dei byte in m emoria

22

11
3/8/03

Or ganizzazione della memoria

• L’indirizzamento al byte e’ comodo, ma i dati sono


memorizzati in “words” (32 bits o 4 bytes)
• I registri contengono 32 bits di dati
• Organizzazione della memoria:
– 232 bytes con indirizzi da 0 a 2 32-1
– 230...words con indirizzi 0, 4, 8, ... 232-4 0 32 bits of data

• Le words sono allineate 4 32 bits of data

– quali sono i due bits meno significativi 8 32 bits of data

dell’indirizzo di una parola? 12 32 bits of data

23

Istruzioni di trasferimento dati


• sw (Store Word) reg. => word in memoria
• lw (Load Word) word in memoria => reg.
• Forma:
operatore registro, offset(indirizzo_base)
# offset e’ opzionale

• sw ha la destinazione come ultimo operando


• Esempio:
C code: A[9] = h + A[8];
MIPS code: # h<=>$s2; A[0]<=>$s3
lw $t0, 32($s3)
add $t0, $s2, $t0
sw $t0, 36($s3)
24

12
3/8/03

Un esempio
swap(int v[], int k);
{ int temp;
temp = v[k]
v[k] = v[k+1];
v[k+1] = temp; swap:
} add $t1, $a1, $a1
add $t1, $t1, $t1
add $t1, $a0, $t1
lw $t0, 0($t1)
lw $t2, 4($t1)
sw $t2, 0($t1)
sw $t0, 4($t1)
jr $ra

#v<=>$a0; k<=>$a1; temp<=>$t0

25

Esempio con indice variabile

• g = h + A[i]
g $s1
h $s2
A $s3 (indirizzo base)
i $s4 (offset)

MIPS code: add $t1, $s4, $s4


add $t1, $t1, $t1
add $t1, $t1, $s3
lw $t0, 0($t1)
add $s1, $s2, $t0

26

13
3/8/03

Spilling

• In memoria si mettono le variabili meno usate


• Ricorda: gli operandi aritmetici sono registri, non celle
di memoria
– tempo accesso ai registri e’ minore
– throughput migliore
• 1 ciclo di clock:

– lettura due registri,


– esecuzione operazione
– scrittura risultato

27

Istruzioni di trasferimento dati


ISTRUZIONE ESEMPIO SIGNIFICATO

caricamento di li $s1, 10 $s1 = 10


una costante
caricamento costante la $s1, ind $s1 = ind
di tipo indirizzo (32bit)
caricamento del byte lb $s1, ind $s1 = (ind)
memorizz. all’indirizzo ind
caricamento della lw $s1, ind $s1 = (ind)
word memorizz.
all’indirizzo ind
memorizz. del byte sb $s1, ind ind = ($s1)
contenuto nel registro
$s1 all’indirizzo ind
memorizz. della word sw $s1, ind ind = ($s1)
contenuto nel registro
$s all’indirizzo ind

28

14
3/8/03

Riassum endo

• MIPS
– load/store word, con indirizzamento al byte
– aritmetica solo su registri

• Istruzioni Significato
add $t1, $t2, $t3 $t1 = $t2 + $t3
sub $t1, $t2, $t3 $t1 = $t2 - $t3
lw $t0, 100($t1) $t0 = Memory[$t1+100]
sw $t0, 100($t1) Memory[$t1+100] = $t0

29

Linguaggio m acchina

• Istruzioni, registri e words di dati sono di 32 bits


– sono rappresentati all’interno del calcolatore come serie di
segnali elettrici
– ovvero, numeri in base 2
• Esempio: add $t0, $s1, $s2
– I registri sono numerati: $t0=8, $s1=17, $s2=18
• Formato istruzione R-type:
000000 10001 10010 01000 00000 100000

op rs rt rd shamt funct
6 bit 5 bit 5 bit 5 bit 5 bit 6 bit

30

15
3/8/03

Linguaggio m acchina

• op : codice operativo (opcode) dell’istruzione


• rs: primo operando (registro)
• rt: secondo operando (registro)
• rd: registro destinazione, che contiene il risultato
dell’operazione
• shamt: valore dell’offset (scalamento, shift amount)
• funct: seleziona una variante dell’operazione base
specificata dall’opcode (codice funzione, function code)

31

Rappresentazione delle istruzioni


• Formato istruzione (R-type): 3 registri
• le istruzioni lw e sw?
– 2 registri e una costante
– 5 bit non sono sufficienti
– occorre nuovo formato
• Formato istruzione (I-type)
6bit 5bit 5bit 16bit

op rs rt address
opcode base Dest(lw)

• Spazio di indirizzamento: ±215=±213 parole

• Principio di progetto 3:
– un buon progetto richiede buoni compromessi
32

16
3/8/03

Rappresentazione delle istruzioni

• esempio
lw $t0, 32($s3)
lw $8, 32($19)

35 19 8 32

op rs rt address
opcode base Dest

• Compromesso di progetto
– anche lw/sw sono lunghe 1w, con displacement costante (operando
immediato di 16 bit) inserito direttamente nell’istruzione

33

Concetto di programma m emorizzato


• Le istruzioni sono stringhe di bits
• I programmi sono memorizzati in memoria
– semplificazione hw/sw dei calcolatori

memoria per dati, programmi,


Processore Memoria compilatori, editor, etc

• Ciclo Fetch & Execute


– l’istruzione corrente viene letta e messa in uno speciale registro interno
– i bit nel registro “controllano” le azioni seguenti
– viene letta la nuova istruzione e cosi’ via
34

17
3/8/03

Ciclo fetch&execute

Instruction Fetch

Instruction Decod e

Operand Fetch

Execute

Result Sto re

Next Instruction

35

Programm a memor izzato

memory

OS
code
Program 1
data
CPU
unused

Program 2

unused

36

18
3/8/03

Or ganizzazione della memoria


0x7fffffff
stack Segmento stack

Dati dinamici
Segmento di dato
Dati statici
0x10000000

text Segmento di codice

0x400000
Riservata

37

Istruzioni di controllo
• Istruzioni per prendere le decisioni
– alterano il controllo del flusso (sequenziale)
– cambiano quindi la prossima istruzione da eseguire
• Istruzioni MIPS di salto condizionato
bne $t0, $t1, Label # branch if not equal
beq $t0, $t1, Label # branch if equal

• Esempio: if (i==j) h = i + j;
bne $s0, $s1, Label
add $s3, $s0, $s1
Label: ....

38

19
3/8/03

Istruzioni di controllo
• Salto non condizionato
j label

• Esempio (costrutto if...then...else):


if (i != j) h=i+j; beq $s4, $s5, Lab1
else h=i-j; add $s3, $s4, $s5
j Lab2
Lab1: sub $s3, $s4, $s5
Lab2: ...

39

Istruzioni di controllo
• Esempio costrutto while:
while (vett[i] == k) i=i+j;
– i, j e k sono contenuti nei registri $s3, $s4 e $s5 e l’indirizzo base
di vet t in $s6
ciclo:add $t1, $s3, $s3 #t1 =2*i
add $t1, $t1, $t1 #t1 =4*i
add $t1, $t1, $s6 #t1 = indirizzo di vett[i]
lw $t0, 0($t1) #t0 = vett[i]
bne $t0, $s5, esci #vai a esci se
#vett[i] = k
add $s3, $s3, $s4 #i=i+j
j ciclo #vai a ciclo
Esci: ...

40

20
3/8/03

Istruzioni di controllo
• Istruzione set on less than:
#if $s1 < $s2 then
slt $t0, $s1, $s2 # $t0 = 1
# else $t0 = 0
• Questa istruzione puo’ essere utilizzata per creare “blt” che non
e’ predefinita nel linguaggio MIPS. Per fare questo e’ necessario
l’uso del registro $zero.

• Formato J-Type

J op 26 bit address

6 bit 26 bit

41

Comando FOR

• C code:
for (i=0; i != n; i = i+k)
a = a+b;

• MIPS:
add $t0, $zero, $zero # i=$t0=0
Loop:
beq $t0, $s0, Exit # if (i== n) goto Exi t
add $s1, $s1, $s2 # a = a+b ;
add $t0, $t0, $t1 # i = i+k ;
j Loop # goto Loop
Exit:

42

21
3/8/03

Comando Case/Switch

• Comando Case/switch
– puo’ essere tradotto in una catena di if-then-else
– caso peggiore: tempo di esecuzione proporzionale al numero di casi
– puo’ essere reso più veloce con una jump address table
ind. in cui si trovano le sequenze di istruzioni = vettore con indirizzi delle
etichette

• Nuova istruzione:
salto tramite registro jr $t0 (jump register )
• switch (k){
case 0: f = i+j; break;
case 1: f = g+h; break;
case 2: f = g-h; break;
case 3: f = i-j; break;
}
43

Comando Case/Switch
slt $t3, $s5, $zero
Assembler code: bne $t3, $zero, Exi t
slt $t3, $s5, $t2
1. test se 0 <= k <= 3 beq $t3, $zero, Exi t
2. calcola indirizzo add $t1, $s5, $s5
3. trova indirizzo di salto e salta add $t1, $t1, $t1
4. esegue il codice add $t1, $t1, $t4
lw $t0, 0($t1)
Data: jump table
jr $t0
$t4 address L0 L0: add $s0, $s3, $s4
$t4+4 address L1 j Exit
L1: add $s0, $s1, $s2
$t4+8 address L2
j Exit
$t4+12 address L3
L2: sub $s0, $s1, $s2
j Exit
$t4 <-> base
$t2 <-> 4 L3: sub $s0, $s3, $s4
$s5 <-> k Exit:
44

22
3/8/03

Istruzioni di confronto
Istruzione Esempio Significato Commenti
set less than slt $s1,$s2,$s3 if ($s2<$s3) $s1=1; Confronto tra registri
else $s1=0 (con segno)
set less than imm. slti $s1,$s2,100 if ($s2<100) $s1=1; Confronto registro-costante
else $s1=0 (con segno)
set less than uns. sltu $s1,$s2,$s3 if ($s2<$s3) $s1=1; Confronto tra registri (senz a
else $s1=0 segno)
set l. t. imm. uns. sltiu $s1,$s2,100 if ($s2<100) $s1=1; Confronto registro-costante
else $s1=0 (senz a segno)

45

Branch e Branch&Link
Istruzione Esempio Significato Commenti

branch on equal beq $s1,$s2,L if ($s1 == $s2) go to L Test di uguaglianza; PC-rel.


branch on not eq. bne $s1,$s2,L if ($s1!= $s2) go to L Test di disuguaglianza; PC-rel.
branch gr. eq. zero bgez $s1, L if ($s1>= $0) go to L Test di non negativo; PC-rel.
branch gr. th.. zero bgtz $s1, L if ($s1> $0) go to L Test di positivo; PC-rel.
branch less eq. zero blez $s 1, L if ($s1<= $0) go to L Test di non positivo; PC-rel.
branch less th. zero bltz $s1, L if ($s1< $0) go to L Test di negativo; PC-rel.

branch gr. eq. zero bgezal $s1, P if ($s1>= $0) { Test di non negativo; PC-rel.
and link $ra = PC + 4; Per le chiamate a procedura
go to P}

branch less th. zero bltzal $s1, P if ($s1< $0) { Test di negativo; PC-rel.
and link $ra = PC + 4; Per le chiamate a procedura
go to P} 46

23
3/8/03

Jump

Istruzione Es. Significato Commenti


jump j Lab go to Lab Salta all’istruzione di etichetta Lab
jump register jr $ra go to $ra Per i ritorni da procedura
jump and link jal Proc $ra = PC + 4; Per le chiamate di procedura
go to Proc
jump and link jalr $s1 $ra = PC + 4; Per le chiamate di procedura
reg. go to $s1

47

Procedure/Funzioni
• Molto utili in linguaggi di alto livello
– astrazione - riusabilita’ - strutturazione/modularità
• Chi si “occupa” della chiamata
– il compilatore nei linguaggi ad alto livello
– il programmatore in assembler
• Passi necessari
– passare i parametri al chiamato
– salvare l’indirizzo di ritorno e passare il controllo alla procedura
– allocare spaz io per variabili locali
– eseguire il corpo della procedura
– passare i risultati al chiamante
– riportare il controllo al punto di partenza

48

24
3/8/03

Indir izzo di ritor no


• E’ necessario salvare l’indirizzo di ritorno
Istruzione jump and link
jal indirizzo
esegue l’istruzione memorizza ta ad indirizzo e pone in $ra l’indirizzo
dell’istruzione successiva a jal indirizzo
• Istruzione di ritorno
jr $ra
esegue l’istruzione il cui indirizzo e’ contenuto in $ra
• L’indirizzo dell’istruzione corrente e’ contenuto nel registro
riservato PC (Program Counter)
– jal mette in $ra il valore (PC)+4
– jr $ra mette in PC $ra

49

Chiamata di una pr ocedura

chiamante
chiamato
... label: ...
... ...
jal label ...
$ra ... ...
... ...
... ...
... jr $ra
... ...

E se il chiamato chiama un’altra procedura? 50

25
3/8/03

Chiamate annidate
chiamante
chiamato/
chiamante
... chiamato
loc: ...
...
...
jal loc loc2: ...
$ra ...
... ...
jal loc2
... ...
$ra ...
...
...
...
...
...
...
jr $ra
jr $ra
...

51

Passaggio dei parametri

• Il programma chiamante puo’ passare dei parametri alla


procedura chiamata
• La convenzione usata per il passaggio dei parametri al
chiamato:
– Si usano i registri $a0...$a3 (4 registri in tutto)
• Se ho più di 4 parametri da passare o più chiamate
innestate?
Occorre una struttura dati per memorizzare le variabili
locali del chiamato e gestire le chiamate annidate:
PILA (Stack)

52

26
3/8/03

Uso della pila (stack)

• L’indirizzo dell’istruzione corrente e ’ contenuto nel registro


riservato PC (Program Counter)
• L’istruzione jal mette in $ra il valore (PC)+4
• jr mette in PC ($ra)
• Il programma chiamante puo’ passare dei parametri alla
procedura chiamata
• La convenzione usata per il passaggio dei parametri:
– uso dei registri $a0...$a3 (4 registri in tutto)
– se ho più di 4 parametri da passare o più chiamate innestate si usa
la PILA

53

Uso della pila (stack)


• Stack Pointer $sp
– punta sempre alla cima dello stack high
(all’ultima parola) $fp old addresses

• Struttura dati LIFO ...


– push: sub $sp, $sp, 4 ...
sw $t0, ($sp) ...

– pop: lw $t0, ($sp) $sp new


low
add $sp, $sp, 4 addresses

• Frame Pointer $fp


– indirizza la prima parola dello stack frame di una procedura
• Stack frame
– segmento dello stack che contiene i registri salvati da una
procedura e le variabili locali
54

27
3/8/03

Stack frame
Scopo
• memorizzare i dati di una $fp Argomento 5
Argomento 6
procedura in una struttura singola
...
• si puo’ accedere ai dati con $fp ...
• usare $sp puo’ essere difficile Registri
perche’ la pila puo’ variare salvati Stack
frame
• E’ necessario?
– si, per le chiamate ricorsive Variabili
– si, per chiamate di procedure locali
complesse
– no, per programmi semplici
$sp
– I compilatori lo usano!
• Contenuti
– argomenti non passati con a0-a3
– valori di registri salvati Lo stack cresce
verso il basso
– variabili locali della procedura
55

Stack Frame

argomento 5 $fp
SF argomento 6
procedura A
...
SF
procedura B Registri
SF salvati
procedura C
variabili
locali
$sp
stack
cresce verso
il basso

56

28
3/8/03

Convenz ioni nella chiamata di pr ocedure -1


• Programma chiamante e chiamato devono stabilire una
ben definita sequenza di passi
• Il chiamante:
– passa gli argomenti se ce ne sono. Fino a 4 si usano i registri $a0-
$a3. I successivi in pila.
– salva i registri $a0-$a3 e $t0-$t9 se intende usarli dopo la
chiamata
– esegue jal (salta alla prima istruzione del chiamato e salva in
$ra l’indirizzo di ritorno)
• Il chiamato (prima di eseguire le proprie istruzioni):
– alloca memoria per lo stack frame. Se lo stack frame e’ di 32 byte,
$sp = $sp - 32
– salva i registri $s0-$7, $fp, $ra prima di alterarli
– inizializza il frame pointer. $fp = $sp + 32 - 4
– se non ci sono dati locali nella pila $fp non serve
57

Convenz ioni nella chiamata di pr ocedure -2

• Il chiamato (dopo avere eseguito le proprie istruzioni):


– mette il valore risultato in $v0 (se esiste)
– ripristina tutti i registri che aveva salvato prima dell’esecuzione
della procedura
– libera lo stack frame. $sp = $sp + 32
– Ritorna al programma chiamante : jr $32

58

29
3/8/03

Convenz ioni sull’uso dei registr i

Preservato in u na
chiamata a
No me Numero Uso p ro ced ura?
$zero 0 il valore costante 0 n.a.
$v0-$v1 2-3 valori per risultati di espressioni no
$a0-$a3 4-7 argomenti si
$t0-$t7 8-15 temporanei no
$s0-$s7 16-23 salvati si
$t8-$t9 24-25 altri temporanei no
$gp 28 global pointer si
$sp 29 stack pointer si
$fp 30 frame pointer si
$ra 31 return address si

59

Ottimizz azione delle chiamate

• Tipi di chiamate di procedura


– non-foglia
• procedure che chiamano altre procedure

• procedure ricorsive

– foglia
• procedure che non effe ttuano chiamate

– che richiedono l’uso della pila per variabili locali


– che non richiedono uso della pila

60

30
3/8/03

Compilare una procedura “foglia”

void swap(int v[], int k) swap: add $t0,$a1,$a1


{ add $t0,$t0,$t0
int tmp; add $t0,$a0,$a0
tmp = v[k]; lw $t1,0($t0)
v[k] = v[k+1]; lw $t2,4($t0)
v[k+1] = tmp; sw $t2,0($t0)
} sw $t1,4($t0)
jr $ra

Caller:
add $a0,$s1,$zero
add $a1,$s2,$zero
jal swap

61

Compilare una procedura “non foglia”


int squ are (int a){ square:
retu rn a*a; mul $v0,$a0 ,$a 0 #pseudoistr.

} jr $ra

int pol y(i nt x){ poly: addi $sp,$sp ,-8


retu rn squar e(x )+x+1 ; sw $ra,4($ sp)
} sw $a0,0($ sp)
jal square
lw $a0,0($ sp)
add $v0,$v0 ,$a 0
addi $v0,$v0 ,1
lw $ra,4($ sp)
addi $sp,$sp ,8
jr $ra

62

31
3/8/03

Funzione ricorsiva

Funzione C per il calcolo del fattoriale :


int fact (int n)
{
if (n<1) return (1)
else return (n*fact(n-1));
}

Fattoriale : n! = n* (n-1)!
0! = 1

63

Funzione ricorsiva
instruction
address
1000 fact: addi $sp,$sp,-8
1004 sw $ra,4($sp)
1008 sw $a0,0($sp)
1012 slti $t0,$a0,1 # test if n<1
1016 beq $t0,$zero,L1 # if n>=1 goto L1
1020 addi $v0,$zero,1 # return 1
1024 addi $sp,$sp,8 #
1032 jr $ra
1036 L1: addi $a0,$a0,-1
1040 jal fact # call fact with (n-1)
1044 lw $a0,0($sp)
1048 lw $ra,4($sp)
1052 addi $sp,$sp,8
1056 mul $v0,$a0,$v0 # return n*fact(n-1)
1060 jr $ra
64

32
3/8/03

Funzione ricorsiva

low address
$a0 = 0 $v0 = 1
$ra = 1044
$a0 = 1 100 addi $a0,$zero,3
$v0 = 1
$ra = 1044
$a0 = 2 104 jal fact
$v0 = 2
$ra = 1044 108 ....
$a0 = 3
$sp $v0 = 6
$ra =108
filled

high address

65

Istruzioni Logiche
Istruzione Esempio Significato Commento
and and $s1,$s2,$s3 $s1 = $s2 & $s3 3 reg. operands; Logical AND
or or $s1,$s2,$s3 $s1 = $s2 | $s3 3 reg. operands; Logical OR
xor xor $s1,$s2,$s3 $s1 = $s2 ^ $s 3 3 reg. operands; Logical XOR
nor nor $s1,$s2,$s3 $s1 = ~($s2 |$s 3) 3 reg. operands; Logical NOR
and immediato andi $s1,$s2,10 $s1 = $s2 & 10 Logical AND reg, constant
or immediato ori $s1,$s2,10 $s1 = $s2 | 10 Logical OR reg, constant
xor immediato xori $s1, $s2,10 $s1 = ~$s2 &~10 Logical XOR reg, constant
shift left logical sll $s1,$s2,10 $s1 = $s2 << 10 Shift left by constant
shift right logical srl $s1,$s2,10 $s1 = $s2 >> 10 Shift right by constant
shift right arithm. sra $s1,$s2,10 $s1 = $s2 >> 10 Shift right (si gn extend)
shift left logical sllv $s1,$s2,$s3 $s1 = $s2 << $s3 Shift left by variable
shift right logical srlv $s1,$s2, $s3 $s1 = $s2 >> $s3 Shift right by variable
shift right arithm. srav $s1,$s2, $s3 $s1 = $s2 >> $s3 Shift right arith. by variable

66

33
3/8/03

Costanti
• Le costanti sono utilizzati frequentemente (50% degli
operandi). Esempio: A = B + 5;
• Possibile soluzione:
– mettere le costanti in memoria e caricarle nei registri

• Istruzioni MIPS per manipolare costanti:


– particolari versioni delle istruzioni aritmetiche (sempre I-type)
– operando immediato di 16 bits
addi $29, $29, 4
slti $8, $18, 10
andi $29, $29, 6
ori $29, $29, 4

67

Come caricare costanti lunghe 32 bits


• Si procede in due passi.
• Esempio: caricare 0xaabbccdd.
– Si caricano i 16 bit più significativi
lui $t0, 1010 1010 1011 1011
• Bit meno significativi posti a zero

– Si caricano i 16 bit meno significativi (ori, add i)


ori $t0, $t0, 1100 1100 1101 1101
0xaabb 0x0000
0x0000 0xccdd

0xaabb 0xccdd

• Nota differ enza tra ori e addi (est. segno)


• Principio di progetto 4:
– rendere veloce l’evento più frequente (costanti come parte
dell’istruzione re nde la loro esecuzione più veloce)
68

34
3/8/03

Caricam ento di costanti


• Load 0x12345678 in R8 (LI $8, 0x12345678)
Zero Fill

lui $8, 0x1234 1234 0000


ori $8, 0x5678 1234 5678

• Load 0x1234 in R8 (LI $8, 0x1234)


Sign Extended

addi $8, $zero, 0x1234 0000 1234

• Load -1 in R8 (LI $8, -1) Sign Extended

addi $8, $zero, -1 FFFF FFFF


69

Indir izzam ento nei salti

• Istruzioni:
bne $t4,$t5,Label #Salta a Label se $t4!=$t5
beq $t4,$t5,Label #Salta a Label se $t4==$t5
j Label #Salta Label

• Formato: gli indirizzi non sono di 32 bits


I op rs rt 16 bit address

J op 26 bit address

70

35
3/8/03

Indir izzam ento nei salti

• L’istruzione di salto condizionato (branch) ha


solo 16 bits per l’indirizzo di salto
• Indirizzamento PC-relative
PC = registro + indirizzo di salto
– il programma puo’ raggiungere la dimensione di 232 (4Gb)
– si puo’ saltare fino ad una distanza ±215 word (±128Kb)
(principio di località)
Importante:
• l’offset e’ relativo all’indirizzo dell’istruzione successiva (PC+4)
• l’offset usa un indirizzame nto relativo alle parole (deve esser e
moltiplicato per 4 prima di essere sommato a PC+4)
71

Modi di indir izzam ento

72

36
3/8/03

Indir izzam ento Base + Offset

Intervallo ± 32 Kb
dalla base

73

Indir izzam ento PC-relative (branch)

74

37
3/8/03

Indir izzam ento PC-relative (jump)

75

Pseudoistruzioni

• Sono istruzioni accettate dall’assemblatore MIPS che


non hanno corrispettivo nel linguaggio macchina per
uno dei seguenti motivi:
– usano un’operaz ione non implementata dallo hardware
– usano un modo di indirizzamento esteso, non implementato dallo
hardware
• L’assemblatore le espande in sequenze di poche
istruzioni binarie, usando il registro $1 ($at), riservato
a questo scopo

76

38
3/8/03

Pseudo Istruzioni

• aritmetiche
– abs, neg, negu, mul, mlo, mlou, div, divu, rem, remu
• logiche
– not
– rol, ror
• di trasferimento dati
– la, ld, ulh, ulhu, ulw, li
– sd, ush, usw
– move
• di confronto
– seq, sge, sgeu, sgt, sgtu, sle, sleu, sne

77

Pseudo Istruzioni

• di controllo
– b, beqz, bge, bgeu, bgt, bgtu, ble, bleu, blt, bltu, bnez
• dei coprocessori
– mfc1.d
• floating-point
– li.s(.d), l.s(.d),s.s(.d)

78

39
3/8/03

Pseudoistruzioni: esempi

• la $4, label
lui $1, UpperPartLabelAddress
ori $4, $1, LowerPartLabelAddress

• bge $8,$9,address
slt at,$8,$9
beq at,$zero, address

• move $8,$10
addu $8, $0, $10

79

Pseudoistruzioni: esempi

• abs $9,$8 addu $9,$0,$8


bgez $8,$L
sub $9,$0,$8
$L: ...
• abs $8,$8 bgez $8,$L
sub $8,$0,$8
$L: ...

80

40
3/8/03

Pseudo-Indirizzam ento

• Si ha quando il modo di indirizzamento usato non è


direttamente fornito dal processore
• Anche in questo caso una singola (pseudo)istruzione
viene tradotta in una sequenza di più istruzioni di
macchina
• Esempio:
J Label

81

Riassum endo

• Tutte le istruzioni sono lunghe 32 bits (1 word)


• Solo tre i formati delle istruzioni:
R op rs rt rd shamt funct
I op rs rt 16 bit address
J op 26 bit address

MIPS operands
Name Example Comments
$s0-$s7, $t0-$t9, $zero, Fast locations for data. In MIPS, data must be in registers to perform
32 registers $a0-$a3, $v0-$v1, $gp, arithmetic. MIPS register $zero always equals 0. Register $at is
$fp, $sp, $ra, $at reserved for the assembler to handle large constants.
Memory[0], Accessed only by data transfer instructions. MIPS uses byte addresses, so
230 memory Memory[4], ..., sequential words differ by 4. Memory holds data structures, such as arrays,
words Memory[4294967292] and spilled registers, such as those saved on procedure calls.

82

41
3/8/03

Riassum endo
MIPS assembly language
Category Instruction Example Meaning Comments
add add $s1, $s2, $s3 $s1 = $s2 + $s3 Three operands; data in registers

Arithmetic subtract sub $s1, $s2, $s3 $s1 = $s2 - $s3 Three operands; data in registers

add immediate addi $s1, $s2, 100 $s1 = $s2 + 100 Used to add constants
load word lw $s1, 100($s2) $s1 = Memory[ $s2 + 100] Word from memory to register
store word sw $s1, 100($s2) Memory[$s2 + 100] = $s1 Word from register to memory
Data transfer load byte lb $s1, 100($s2) $s1 = Memory[ $s2 + 100] Byte from memory to register
store byte sb $s1, 100($s2) Memory[$s2 + 100] = $s1 Byte from register to memory
load upper lui $s1, 100 $s1 = 100 * 2
16 Loads constant in upper 16 bits
immediate

branch on equal beq $s1, $s2, 25 if ($s1 == $s2) go to Equal test; PC-relative branch
PC + 4 + 100

branch on not equal bne $s1, $s2, 25 if ($s1 != $s2) go to Not equal test; PC-relative
PC + 4 + 100
Conditional
branch set on less than slt $s1, $s2, $s3 if ($s2 < $s3) $s1 = 1; Compare less than; for beq, bne
else $s1 = 0

set less than slti $s1, $s2, 100 if ($s2 < 100) $s1 = 1; Compare less than constant
immediate else $s1 = 0

jump j 2500 go to 10000 Jump to target address


Uncondi- jump register jr $ra go to $ra For switch, procedure return
tional jump jump and link jal 2500 $ra = PC + 4; go to 10000 For procedure call

83

Riassum endo
• Tutte le istruzioni modificano tutti i 32 bits del registro destinazione (incluso
lui, lb, lh) e tutte leggono i 32 bits della sorgente (add, sub, and, or, …)
• Le istruzioni Immediate aritmetiche e logiche sono estese nel seguente modo:
– gli operandi logici immediati sono “zero extended” a 32 bits
– gli operandi aritmetici immediati sono “sign extended” a 32 bits (incluso addu)
• I dati caricati da lb e lh sono estesi nel seguente modo:
– lbu, lhu “zero extended”
– lb, lh “sign extended”
• Overflow puo’ verificarsi con:
– add, sub, addi
• non puo’ verificarsi con:
– addu, subu, addiu, and, or, xor, nor, shifts, mult, multu, div, divu

84

42
3/8/03

Summar y

• Instruction complexity is only one variable


– lower instruction count vs. higher CPI / lower clock rate
• Design Principles:
– simplicity favors regularity
– smaller is faster
– good design demands compromise
– make the common case fast

85

Il sim ulatore SPIM


• E’ un simulatore dell’architettura MIPS R2000/R3000,
inclusi il coprocessore 1, parte del coprocessore 0 e un
terminale memory-mapped.
• Esiste in una versione per Windows (PCSpim) che:
– accetta un programma scritto in linguaggio assembly, completo di
direttive e di pseudoistruzioni
– dispone di un debugger che consente di inserire breakpoint e di
eseguire a singoli step
• E’ fedele, anche se:
– usa quale ordinamento dei byte quello (little-endian o big-endian)
proprio dello hardware su cui gira (Win-SPIM è little-endian)
– non rispetta i tempi di esecuzione, inclusi i ritardi delle istruzioni
di moltiplicazione e divisione, di quelle floating-point e ogni
latenza di memoria
86

43
3/8/03

Assem bler di Spim

• Il programma è organizzato in linee


• Ogni linea può contenere un commento che parte dal
carattere # e si estende fino alla fine della linea
• Ogni linea che non sia bianca o contenga solo un
commento, può essere una istruzione (o pseudo-
istruzione) o una direttiva
• Spazi, tab e virgole (,) fungono da separatori
• Gli identificatori sono sequenze di caratteri
alfanumerici (lettere, cifre, $), underscore(_) e punto (.)
che non incominciano per cifra
87

Assem bler di SPIM

• Lettere minuscole e maiuscole non sono equivalenti


• Le etichette (label) si definiscono scrivendole all’inizio
della linea, seguite da due punti (:)
• I mnemonici di istruzioni, pseudoistruzioni, direttive e
registri ($0-$31, $zero, $at, ...) sono riservati
• I numeri si indicano in decimale (default) o, se
preceduti da 0x in esadecimale
• Le stringhe si racchiudono tra “, con:
– newline \n
– tab \t
– quote \”
88

44
3/8/03

Struttura di un programm a assem bler


.data #segmento dati
elemento: .word 10
.text #segmento codice
.global main #main
main: ...

• Global vs. External:


– .global etichetta: rende etichetta visibile agli altri files
– .extern etichetta: etichetta e’ dichiarato come global in un altro file

89

Direttive

• Le principali direttive all’assemblatore sono:


– .data, .kdata
– .text, .ktext
– .space
– .ascii, .asciiz, .byte, .double, .float, .half, .word
– .align

90

45
3/8/03

.data, .kdata

• .data introduce dati da caricare nel segmento dati


• .kdata introduce dati da caricare nel segmento dati
del kernel
• I dati sono caricati, nel segmento dati, a partire
dall’indirizzo 0x10010000 in modo da poter essere
agevolmente indirizzati tramite $gp
• I dati sono caricati, nel segmento dati del kernel, a
partire dall’indirizzo 0x90000000

91

Global Pointer
• Disponendo di un offset a 16 bit le istruzioni di
load/store non possono accedere direttamente ai dati
statici:
lui $16, 0x1000
lw $2, 0x8000($16)
• Conviene dedicare un registro (per convenzione $28)
come puntatore globale, caricandovi l’indirizzo
0x10008000 (è automatico in SPIM), in modo da
rendere direttamente accessibili i primi 64KB dei dati
statici:
lw $2, 0($28)
92

46
3/8/03

.text, .ktext

• .text introduce istruzioni e word da caricare nel


segmento testo
• .ktext introduce istruzioni e word da caricare nel
segmento testo del kernel
• Istruzioni e word sono caricate a partire dall’indirizzo
0x00400000 nel segmento testo e 0x80000000 nel
segmento testo del kernel

93

.space

• .space n alloca n byte, non inizializzati, nel segmento


corrente
• usato per dichiarare array ed altre strutture dati
– buffer: .space 100

• usato nel segmento testo del kernel per porre il trap


handler (start-up program) a partire dall’indirizzo
0x8000080
– .ktext
– .space 0x80

94

47
3/8/03

.ascii, .asciiz

• .ascii stringa Carica stringa in memoria, senza


terminarla con nul
• .asciiz stringa Carica stringa in memoria,
terminandola con nul
• .asciiz “Input data:\n”

95

.byte, .half, .w ord, .float, .double


• Consentono di caricare più numeri nei formati byte,
halfword, word, float e double in posizioni consecutive di
memoria
– .byte b1, ..., bn
– .half h1, ..., hn
– .word w1, ..., wn
– .float f1, ..., fn
– .double d1, ..., dn
• Gli interi sono esprimibili in decimale o esadecimale
• I float e double vanno espressi in decimale, con .
obbligatorio dopo parte intera ed esponente (e) opzionale

96

48
3/8/03

__start
• E’ l’etichetta che, per default, specifica la prima
istruzione eseguibile del programma
• E’ di solito definita nel trap file, dove è associata al
codice
__start:
. . .
jal main
li $v0 10 # syscall 10 (exit)
syscall

• In questo caso è sufficiente che il programma contenga


la funzione main, secondo la convenzione C.
97

Caratter istiche essenziali di PCSpim


http://www.cs.wisc.edu/~larus/spim.html

• clear : pulisce registri e memoria


• load : carica il programma
• run : esegue il programma
• step : esecuzione single-step
• breakpoint : set/delete breakpoints

• Nota:
– Codice di Startup e’ pre-caricato.
– Pseudo-istruzioni sono espanse in istruzioni reali.

98

49
3/8/03

Chiamate di sistem a (system call)

• Interfaccia attraverso la quale il programma


interagisce col sistema operativo
• Modalita’ d’uso:
– mettere il parametro in un registro ($a0, $a1)
– specificare il tipo di system call (mettendo un parametro nel
registro $v0)
– syscall
• Esempio
move $a0, $t2
li $v0, 1
syscall

99

System call

100

50
3/8/03

Architecture alternative

• Design alternative:
– provide more powerful opera tions
– goal is to reduce number of instructions executed
– danger is a slower cycle time and/or a higher CPI

• Sometimes referred to as “RISC vs. CISC”


– virtually all new instruction sets since 1982 have been RISC
– VAX: minimize code size, make assembly language easy
– instructions from 1 to 54 bytes long!
• We’ll look at PowerPC and 80x86

101

Power PC
• Indexed addressing
– example: lw $t1,$a0+$s3
#$t1=Memory[$a0+$s3]
– What do we have to do in MIPS?

• Update addressing
– update a register as part of load (for marching through arrays)
– example: lwu $t0,4($s3)
#$t0=Memory[$s3+4];$s3=$s3+4
– What do we have to do in MIPS?
• Others:
– load multiple/store multiple
– a special counter register “bc Loop”
– decrement counter, if not 0 goto loop

102

51
3/8/03

80x86
• 1978: The Intel 8086 is announced (16 bit architecture )
• 1980: The 8087 floating point coprocessor is added
• 1982: The 80286 increases address space to 24 bits, +instructions
• 1985: The 80386 extends to 32 bits, new addressing modes
• 1989-1995: The 80486, Pentium, Pentium Pro add a few
instructions (mostly designed for higher performance)
• 1997: MMX is added
– “This history illustrates the impact of the “golden handcuffs” of
compatibility

“adding new features as someone might add clothing to a packed bag”

“an architecture that is difficult to explain and impossible to love”

103

A dom inant architecture: 80x86


• See your textbook for a more detailed description
• Complexity:
– Instructions from 1 to 17 bytes long
– one operand must act as both a source and destination
– one operand can come from memory
– complex addressing modes
– e.g., “base or scaled index with 8 or 32 bit displacement”
• Saving grace:
– the most frequently used instructions are not too difficult to build
– compilers avoid the portions of the architecture that are slow
• “what the 80x86 lacks in style is made up in quantity,
making it beautiful from the right perspective”
104

52
3/8/03

Registri 80386

105

Istruzioni 80x86

106

53
3/8/03

Formati istruzioni 80x86

107

esempio

# This i s the data segme nt


.data
string 0: .asciiz "This is a text string \n"
item0: .word 99
array0 : .word 11 22 33 44 55 66 77 88 99

108

54
3/8/03

esempio

# EXAMP LE I: Pr int a st rin g on the cons ole .


# The meth od is to load the add res s of the stri ng into
# $a0 a nd then use a sysca ll to print the strin g.

la $a0, string0 # Load the base address


# of strin g0 in to $a0
li $v0, 4 # Set $ v0 to 4, this
# tells syscall to
# print th e tex t string
# speci fie d by $a0
syscall # Now p rin t the text
# strin g to the console

109

esempio

# EXAMP LE II: L oad an i nte ger from the dat a seg men t
# and prin t it.
lw $a0, item0 # Load the valu e of ite m0
# into $a0
li $v0, 1 # Set $ v0 to 1, this tells
# sysca ll to print the
# integ er speci fie d by $a0
syscall # Now p rin t the in teger

110

55
3/8/03

esempio

# EXAMPLE III: Read an integer from the console.

li $v0, 5 # Set $v0 to 5, this tells


# syscall to read an
# integer from the console
syscall # Now read the integer.
# The integer is now in $v0.

111

esempio
# EXAMP LE IV: Prin t an ele ment fro m an int eger arr ay
# in the dat a seg men t.
li $t0, 3 # Set t 0 t o 3, the inde x of
# the elem ent w e are fe tch ing
li $t1, 4 # Set t 1 t o 4, thi s is the
# size in bytes of an e lem ent
mul $t2 , $ t1, $ t0 # t2 = t1 * t0, so t2 i s t he
# BYTE off set o f t he el eme nt
lw $a0, array0( $t2 ) # L oad the ele ment of the
# array ; n ote that the fir st
# eleme nt in the a rray has
# an of fse t of zer o
li $v0, 1 # Set $ v0 to 1, this tells
# sysca ll to print the
# integ er speci fie d by $a0
syscall # Now p rin t the in teger
112

56
3/8/03

esempio

# EXAMPLE V: Halt the program.


li $v0, 10 # set $v0 to 10, this tells
# syscall to end execution
syscall

113

esempio
C MIPS
=== ======
global var .data
x = y; lw $t0, y
sw $t0, x
x = y + z; lw $t0, y
lw $t1, z
add $t0, $t0, $t1
sw $t0, x
char s[] = "hello\n"; s: .asciiz "hello\n"
x = s[2]; li $t0, 2
lb $t1, s($t0)
x = s[y]; lw $s0, y
lb $s1, s($s0)
114

57

Potrebbero piacerti anche