Guida al Linguaggio Assembler
Si dice
che un linguaggio di programmazione è a basso o ad alto livello a seconda
della maggiore o minore corrispondenza con l'hardware. Partiamo quindi da
linguaggio macchina che è basato principalmente su valori numerici
per memorizzare ed eseguire programmi,passiamo
quindi al linguaggio assembler più comprensibile a mente umana per
il fatto che usa simboli invece di numeri per la rappresentazioni di dati,per
poi arrivare al linguaggio di alto livello con il quale è possibile
scrivere programmi con un linguaggio simile a quello naturale.
Es.
Linguaggio macchina = 00100111101010010001111011001011 e il corrispondente
linguaggio
assembler può essere:addiu $s2 ,$s2, 32
Da qui possiamo
incominciare a capire il nome di questo linguaggio Assembler
in pratica è uno strumento che traduce programmi scritti nel linguaggio
assembly in linguaggio macchina. L’assembler
legge un file sorgente
in Assembler e produce un file contenente linguaggio macchina!
Perchè allora usare e
conoscere il linguaggio Assembler?La conoscenza di quei linguaggi a basso
livello che sono gli assembler è importante se non indispensabile ad un
programmatore sia per capire poi i linguaggi come il (C,Java,..)
sia per sfruttare a pieno le risorse disponibili ad un programma.
Quindi quali sono i vantaggi
del linguaggio Assembler?I principali vantaggi sono la velocità
di esecuzione utile quindi ad esempio per
la programmazione di centraline ABS che richiedono una velocità ci esecuzione
molto bassa, ma anche per ottimizzare programmi scritti
nel linguaggio ad alto livello nei loro punti critici dal punto di vista
delle performance, ma questo linguaggio ha anche lati negativi come
tutti i linguaggi macchina: per prima cosa non è portabile (viene
usato per un particolare processore)seconda cosa è complesso
portando facilmente all’errore il programmatore.
Quindi
il compito del linguaggio Assembler è quello di semplificare al programmatore
l’uso del linguaggio macchina diretto, dando la possibilità di creazione
etichette, definire macro, aggiungere commenti.
Su cosa lavoriamo?
Lavoreremo principalmente
su un simulatore non avendo a disposizione l’architettura desiderata.
Il programma che useremo
è il SPIM è un simulatore che esegue programmi
per le architetture R2000/R3000 SPIM può leggere ed assemblare programmi
scritti in linguaggio assembly MIPS e SPIM contiene
inoltre un debugger per poter analizzare il
funzionamento dei programmi prodotti.
Dove
possiamo trovare il nostro programma per simulare l’architettura richiesta?
http://www.cs.wisc.edu/~larus/spim.html
oppure QUI
Ora abbiamo
tutto quello che ci serve………
Introduzione alle principali caratteristiche
del linguaggio Assembler
Direttive:
le direttive forniscono informazioni
utili all’Assembler per organizzare il codice alcuni esempi possono essere:
Ese p;
#stampo la stringa
la $a0, etc1
#metto
nel registro la stringa
syscall
#chiamata
di sistema
li $v0, 5 #leggo un intero da tastiera usando i codici syscall(vedi Tab. 2)
syscall
#
move
$s0,$v0 #memorizzo il numero digitato
in un registro ($s0 vedi Tab. 1) di
memorizzazione permanente
addi
$t0,$s0,1 #aggiungo 1 al valore contenuto
nel registro (vedi Tab. 3)
li $v0, 4
# stampo la stringa etc2
la $a0, etc2 # metto nel registro la stringa
syscall
move $a0,$t0 #per stampare il valore contenuto in $t0 devo metterlo in $a0 infatti il codice
li $v0, 1
#di stampa per gli interi
(vedi Tab.2) legge i dati solo dal Reg.
$a0
syscall
li $v0,10
#codice
di uscita questo codice deve SEMPRE essere messo alla fine di ogni
programma
#
per la terminazione dello stesso
syscall
Istruzioni
di Confronto e di Branch
:
Tabella
4
Istruzioni
di confronto:
slt
rd, rs, rt Set
register rd
to
1 if rs
<
rt,
0 otherwise
(with
overflow)
sltu
rd, rs, rt Set
register rd
to
1 if rs
<
rt,
0 otherwise
(without
overflow)
slti
rd, rs, imm Set
register rd
to
1 if rs
<
imm,
0 otherwise
(with
overflow)
sltiu
rd, rs, imm Set
register rd
to
1 if rs
<
imm,
0 otherwise
(without
overflow)
Istruzioni
di Branch :
beq
rs, rt, target Branch
to instruction at target
if
rs
=
rt
bne
rs, rt, target Branch
to instruction at target
if
rs
!=
rt
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
beqz
rs, target Branch
to instruction at target
if
rs
=
0
bnez
rs, target Branch
to instruction at target
if
rs
!=
0
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)
j
target Unconditionally
jump to instruction at target
jal
target Unconditionally
jump to instruction at target,
and
save
the address of the next instruction in register
$ra
jr
rsource 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
A cosa
servono le istruzioni di Branch e Jump?
Le istruzioni di
Branch servono per creare dei cicli
infatti se noi abbiamo un blocco di istruzioni attraverso il Branch
possiamo ripetere questo blocco fino a quando la condizione del branch
non sia verificata…….
Esempio:
|
loop:
add
$s0, $s0, 1 #addiziona
1 al reg $s0 fino a quando $s0 non diventa
>=0 bgez
$s0 , exit #una
volta che $s0 è diventato maggiore di 0 allora il ciclo provocato
dal “j”si interrompe perché
#l’istruzione “bgez”
fa saltare il programma all’etichetta “exit” (vedi tabella 4 per
tutti i tipi di Brach) j
loop #fa
tornare l’esecuzione del programma all’etichetta “loop”
exit: li $v0,10
#codice
di uscita questo codice deve SEMPRE essere messo alla fine di ogni
programma
#
per la terminazione dello stesso syscall |
A cura di Marco Fattorosi Barnaba