Esercitazione 3
Introduzione allo SPIM
Pseudo-Istruzioni
Claudia Raibulet
[email protected]
Introduzione a SPIM
SPIM





SPIM è un software per simulare programmi
scritti per MIPS R2000/R3000
Nome: SPIM è MIPS letto all’incontrario
Può leggere ed eseguire file in linguaggio
assembler
È un sistema autosufficiente per eseguire
programmi MIPS
Contiene un debugger e fornisce alcuni servizi
system like (syscall)
SPIM

Versione 6.5

Per Windows: pcspim
• Editore: notepad o winedit

Per Unix: xspim
• Editore vi, emacs ….

Il sorgente generato deve avere l’estensione .s
(assembler)
Processo che porta al file ESEGUIBILE
Source
file
Assembler
Object
file
Source
file
Assembler
Object
file
Linker
Source
file
Assembler
Object
file
Program
library
Executable
file
Il linker
Object file
sub:
·
·
·
Object file
Instructions
Relocation
records
main:
jal ???
·
·
·
jal ???
Executable file
Linker
call, sub
call, printf
C library
print:
main:
jal printf
·
·
·
jal sub
printf:
·
·
·
sub:
·
·
·
·
·
·

Il linker svolge tre tipi di compiti:
• cerca nelle librerie le procedure usate dal programma
• determina le locazioni di memoria che ciascun modulo occuperà e
riloca le istruzioni aggiornando i riferimenti assoluti
• risolve i riferimenti fra i file
Schema del processore MIPS R2000
Memory
CPU
Coprocessor 1 (FPU)
Registers
Registers
$0
$0
$31
$31
Arithmetic
unit
Multiply
divide
Lo
Arithmetic
unit
Hi
Coprocessor 0 (traps and memory)
Registers
BadVAddr
Cause
Status
EPC
Memoria
Sistemi basati sul processore
MIPS dividono la memoria in
tre parti:



7fffffffhex
text segment: inizia
all’indirizzo 0x00400000
e contiene le istruzioni del
programma
data segment: inizia
10000000hex
all’indirizzo 0x10000000
e contiene i dati del programma400000hex
stack segment: inizia
all’indirizzo 0x7FFFFFFF
Stack segment
Dynamic data
Static data
Data segment
Text segment
Reserved
Direttive del MIPS
.ascii str
- mette in memoria la stringa str e non
aggiunge alla fine in carattere NULL
.asciiz str
- mette in memoria la stringa str terminata
dal carattere NULL
.data <addr> - gli elementi successivi sono memorizzati nel
segmento di dato (a partire dall’indirizzo addr se
specificato)
.space n
- alloca n byte di spazio nel segmento di dato
.text <addr> - gli elementi successivi sono memorizzati nel
segmento di testo dell’utente (a partire
dall’indirizzo addr se sepecificato)
.word w1, ..., wn – memorizza gli n valori su 32 bit in parole
consecutive della memoria
…
Struttura di un programma

Area dati:
• contiene i dati utilizzati dal programma
• nella memoria fisica si trova a partire dall’indirizzo 0x10000000
• nel sorgente assembly viene identificata dalla direttiva “.data”

Area codice:
• contiene il codice assembly (le istruzioni)
• nella memoria fisica si trova a partire dall’indirizzo 0x00400000
• nel sorgente assembly viene identificata dalla direttiva “.text”

Un punto di inizio del programma:
• nel caso si opera senza trap.handler è identificato dalla etichetta “__start”
• nel caso si operi con il trap.handler è identificato dalla etichetta “main”
Registri MIPS
Chiamate di sistema: SYSCALLs




Modellano servizi analoghi a quelli di un sistema
operativo – l’istruzione syscall
$v0 – contiene il codice della chiamata di sistema
$a0 - $a3 – contengono gli argomenti della
chiamata di sistema (o $fl2 – valori in virgola
mobile)
$v0 ($f0) – contiene il risultato della chiamata di
sistema
Chiamate di sistema - codici
Esempio chiamate di sistema

Si chiede di leggere un numero intero e di scrivere come
risposta: “Valore inserito = “ e il numero.
.data
str:
.asciiz “Valore inserito = “
.text
li $v0, 5
# codice chimata di sistema per read_int
syscall
# legge numero
add $t0, $v0, $zero # salva numero letto in $t0
la $a0, str
# indirizzo della stringa da stampare
li $v0, 4
# codice chimata di sistema per print_string
syscall
# stampa stringa
add $a0, $t0, $zero # numero da stampare
li $v0, 1
# codice chimata di sistema per print_int
syscall
# stampa intero
Pseudo-istruzione: move
move registroDestinazione, registroSource
add $t0, $v0, $zero
<=>
move $t0, $v0
SPIM – menù File

File -> Open
• legge un sorgente assembly e lo ASSEMBLA per
mezzo dell’assembler interno dello SPIM
• se il sorgente è corretto sintatticamente lo carica in
memoria a partire da un certo indirizzo definito dalle
convenzioni di uso della memoria
SPIM – menù Simulator

Simulator -> Clear Register
• azzera tutti i registri interni del processore
• il programma caricato in memoria resta invariato

Simulator -> Reinitialize
• inizializza il simulatore, azzera i registri e la memoria
• il programma caricato in memoria viene cancellato

Simulator -> Reload
• ricarica da file e assembla l’ultimo programma caricato in precedenza
• utile dopo correzioni e modifiche o dopo una re-inizializzazione del
simulatore

Simulator -> Go
• esegue un programma a partire da un indirizzo specificato (default
0x00400000)

Simulator -> Continue/Break
• sospendo o prosegue l’esecuzione di un programma (utile nei cicli
infiniti)
SPIM – menù Simulator

Simulator -> Single Step
• esegue una sola istruzione e si ferma

Simulator -> Multiple Steps
• esegue un certo numero di istruzioni e si ferma

Simulator -> Breakpoints
• imposta una locazione del programma nella quale l’esecuzione si
arresta

Simulator -> Set Value
• imposta un registro interno o una locazione di memoria ad un valore

Simulator -> Display Symbol Table
• stampa nella Message Window il valore numerico assunto dalle
etichette simboliche utilizzate e dichiarate visibili a livello globale
(direttiva .globl) nel programma assembly

Simulator -> Settings
• apre il pannello di impostazioni dello SPIM
SPIM – menù Window

Le sue voci permettono di visualizzare le varie
viste se aperte in finestre differenti, aprire o
cancellare la Console e scegliere se visualizzare la
barra con le icone
SPIM – menù Help

Aiuto in linea delle funzionalità principali di
SPIM
Esercizio 1

Si chiede di impostare il valore del registro $t0 a 3, e
il valore del registro $t1 a 2. Si chiede di inserire la
rappresentazione esadecimale dell’istruzione
add $t2, $t0, $t1
all’indirizzo 0x00400000 dell’area di testo. Si chiede
si eseguire l’istruzione e di verificare che nel registro
$t2 è memorizzata la somma dei valori contenuti nei
registri $t0 e $t1.
Esercizio 2

Esempio di espansione di pseudo-isytruzione “lw”
.globl __start
.data 0x10010004
# il punto di partenza del programma deve
# essere dichiarato globale
# dichiarazione di inizio area dati utente
loc_dato:
.word 0x12345678
# etichetta inizio dato
# dato da caricare
.text
__start:
# dichiarazione di inizio area programma
# utente
# punto di partenza programma utente
lw $s0, loc_dato
# carica il dato nel registro $s0
Esercizio 3

Esempio di uso delle modalità di indirizzamento
MIPS e della differenza tra istruzioni la e lw
.globl __start
.data
par_0:
.word 0xAA55AA55
par_1:
.word 0x12345678
par_2:
.word 0xABCDEF01
.text
__start:
li $t0, 4
li $s0, 0x10010000
la $t1, 0x1001004
lw $s1, 0x1001004
la $t2, ($s0)
lw $s2, ($s0)
la $t3, 4($s0)
lw $s3, 4($s0)
la $t4, par_1
lw $s4, par_1
la $t5, par_0+4
lw $s5, par_0+4
la $t6, par_0+4($t0)
lw $s6, par_0+4($t0)
Esercizio 4
.globl __start
.data
pippo:
.ascii "topolino"
.byte 0
minni:
.asciiz "to"
buffer:
.space 10
eol:
.asciiz "\n"
.text
__start:
# stampa la stringa identificata dall'etichetta pippo
la $a0, pippo
li $v0, 4
syscall
# stampa a capo: stampa la stringa dall'etichetta eol
la $a0, eol
li $v0, 4
syscall
la $t0, pippo
addi $t0, $t0, 1
move $a0, $t0
li $v0, 4
syscall
# stampa a capo
# stampa la stringa dall'etichetta eol
la $a0, eol
li $v0, 4
syscall
syscall
# leggi una stringa
li $a1, 10
la $a0, buffer
li $v0, 8
syscall
la $a0, buffer
li $v0, 4
syscall
Esercizio 5
.globl __start
.data
#array inputImage di 50 elementi InputImage[i] i=0,49
inputImage:
.word 163, 165, 165, 165, 165, 163, 163, 164, 165, 167,
.word 154, 157, 155, 153, 151, 146, 146, 151, 156, 159,
.word 145, 144, 135, 126, 123, 132, 142, 147, 151, 151,
.word 133, 115, 81, 59, 61, 78, 103, 120, 136, 147,
.word 128, 91, 44, 18, 22, 46, 74, 94, 120, 148,
.text
__start:
la $t0,inputImage
# stampa l'undicesimo elemento dell'array
lw $a0,40($t0)
li $v0, 1
syscall
Esercizio 6

Si consideri un array di 20 elementi. Si chiede di stampare ogni
valore dell’array su una riga partendo dall’ultimo elemento.
.globl __start
.data
A:
.word 1,2,3,4,5,6,7,8,9,10,
.word 11,12,13,14,15,16,17,18,19,20
# stringa eol - a capo
eol:
.asciiz "\n"
.text
__start:
# in $t0 l'indirizzo dell'array A
la $t0, A
# inizializzare l'offset
addi $t0, $t0, 76
# inizializzare l'indice dell'array
li $t1, 20
# indice di controllo
ciclo:
# stampa i-esimo elemento
lw $a0, 0($t0)
li $v0, 1
syscall
# stampa a capo
li $v0, 4
la $a0, eol
syscall
# ricalcola offset
addi $t0, $t0, -4
# decrementa di 1 l'indice
addi $t1, $t1, -1
# se $t1 e zero, il ciclo e' finito
beq $t1, $zero, exit
# torna a ciclo:
j ciclo
exit:
Scarica

Esercitazione 3