CALCOLATORI ELETTRONICI
Gestione delle subroutine
SUBROUTINES / 1
Vantaggi delle subroutines
In maniera analoga alle funzioni/metodi dei linguaggi ad alto
livello, anche in assembly le subroutines garantiscono una
maggiore semplicità, modularità e riusabilità del software.
Inoltre riducono il consumo di memoria necessario per la
memorizzazione del codice, nel caso in cui un determinato insieme
di istruzioni debba essere richiamato più volte durante
l’elaborazione.
SUBROUTINES / 2
Salto a sottoprogramma
L’istruzione di salto a subroutine (JSR) permette di saltare da un
programma – programma principale – ad un altro programma –
sottoprogramma.
Esempio
JSR moltiplicazione
;salta al sottoprogramma “moltiplicazione”
L’esecuzione del sottoprogramma termina con l’istruzione RET, con
la quale si ritorna ad eseguire il programma principale, o meglio il
programma chiamante.
SUBROUTINES / 3
Programma principale
Sottoprogramma A
1. chiamata
JSR A
2. chiamata
1. risposta
JSR A
2. risposta
RET
JMP e JSR / 1
La sintassi di JSR (Jump To Subroutine) è la stessa dell’istruzione di salto
incondizionato JMP, cioè:
JSR <dest>
dove dest è l’indirizzo di memoria della prima istruzione della subroutine
espresso sotto forma di numero binario a 32 bit o di riferimento simbolico(label).
JMP e JSR / 2
Differenza tra JMP e JSR
A differenza dell’istruzione JMP, il microprogramma associato
all’istruzione JSR, prima di rimpiazzare il contenuto del PC con
l’indirizzo <dest>, deve memorizzarne il valore in memoria.
In questo modo, al termine della subroutine, l’esecuzione può
riprendere dall’istruzione successiva alla JSR.
L’area di memoria preposta alla memorizzazione degli indirizzi
di ritorno delle subroutines deve permettere di gestire
efficientemente anche situazioni più complesse, in cui i
sottoprogrammi chiamano a loro volta altri sottoprogrammi
(nested subroutines).
SUBROUTINES ANNIDATE
Programma
principale
Sottoprogr.
A
Sottoprogr.
C
Sottoprogr.
B
1
2
JSR A
3
JSR B
6
5
JSR C
4
JSR A
RET
RET
RET
STACK / 1
La gestione dei sottoprogrammi è basata su una struttura dati
chiamata stack (pila), gestita con una tecnica LIFO (Last In First
Out): gli elementi vengono prelevati a partire dall’ultimo che è
stato memorizzato.
L’operazione di inserimento di un elemento alla sommità (top)
dello stack è chiamata push, mentre l’operazione inversa è
chiamata pop.
STACK / 2
Le operazioni di PUSH e POP, sebbene disponibili nel set di
istruzioni del PD32, vengono comunque implementate come
pseudoistruzioni di movimento dati.
Le pseudoistruzioni non sono implementate a livello hardware, ma
sono messe a disposizione dall’assemblatore che provvede a
mapparle nelle istruzioni del microprocessore equivalenti.
GESTIONE STACK PD32 / 1
Nel PD32 lo stack è costituito da
longword e ad esso è associato un
particolare registro detto SP (Stack
Pointer) che nel PD32 coincide con il
registro R7. Tale registro punta sempre
alla cima (top) dello stack.
STACK
BASE
elem.1 byte 4 LSB
elem.1 byte 3
elem.1 byte 2
elem.1 byte 1 MSB
elem.2 byte 4 LSB
elem.2 byte 3
elem.2 byte 2
S
S-1
S-2
S-3
S-4
S-5
S-6
Per “ragioni storiche”, nel PD32 lo
stack cresce verso indirizzi di memoria
decrescenti. Sia S l’indirizzo iniziale
S-7
dello stack (base), allora gli n elementi
elem.2 byte 1 MSB S-8
presenti sono
memorizzati nelle
locazioni consecutive:
TOP
S, S-4, S-8,…,S-4*n
S-8
R7
GESTIONE STACK PD32 / 2
Come detto in precedenza le istruzioni PUSH e POP non sono vere e
proprio istruzioni che appartengono al set del PD32, bensì sono
istruzioni che il compilatore traduce in particolari MOV.
BASE S
e_b4
PUSH:
e_b3
e_b2
e_b1
inserisce elemento “e” in pila
S
S-1
S-2
S-3
S-4
S-5
S-6
S-7
S-8
R7
GESTIONE STACK PD32 / 2
Come detto in precedenza le istruzioni PUSH e POP non sono vere e
proprio istruzioni che appartengono al set del PD32, bensì sono
istruzioni che il compilatore traduce in particolari MOV.
BASE S
e_b4
POP:
e_b3
e_b2
e_b1
estrae l’elemento “e” dalla pila
S-4
S-1
S-2
S-3
S-4
S-5
S-6
S-7
S-8
R7
STACK & PD32 / 2
Le pseudoistruzioni per la gestione dello stack
PSEUDOISTRUZIONE
OP.
COMMENTO
PUSH
S
Inserisce in cima allo stack una longword indirizzata
dall’operando sorgente S. Viene tradotta come: MOVL S, -(R7)
POP
D
Estrae dallo stack una longword e la pone nella locazione
indicata dall’operando D. Viene tradotta come: MOVL (R7)+, D
PUSHSR
POPSR
-
Inserisce lo Status Register in cima allo stack. Viene tradotta
come: MOVRFRSR -(R7)
-
Ripristina lo Status Register con la longword presente in cima
allo stack. Viene tradotta come: MOVTOSR (R7)+
ESEMPIO PUSH
… E DOPO
PRIMA DI ESEGUIRE PUSH R6…
000027FC BASE
78
56
34
000027F8
12
TOP
000027FC BASE
78
56
34
000027F8
12
44
000027F4
R6
PC
R7
11223344
00000410
000027F8
R6
PC
R7
33
22
11
11223344
00000414
000027F4
TOP
ESEMPIO POP
… E DOPO
PRIMA DI ESEGUIRE POP R5…
000027FC BASE
78
56
34
000027F8
12
44
000027F4
R5
PC
R7
33
22
11
FFFFFFFF
00000414
000027F4
000027FC BASE
78
56
34
000027F8
12
TOP
R5
PC
R7
11223344
00000418
000027F8
TOP
STACK E SUBROUTINE
L’istruzione JSR inserisce (PUSH) in cima allo stack il valore del
PC, ovvero l’indirizzo di ritorno della subroutine. In maniera
analoga, l’istruzione RET estrae dalla cima dello stack una
longword che memorizza all’interno del PC. Nella successiva fase
di fetch sarà quindi caricata nell’IR l’istruzione che segue la JSR.
Lo stack è inoltre utilizzato dalla subroutine chiamata per salvare i
registri che saranno utilizzati e quindi sovrascritti, così da poterne
ripristinare il valore originale prima di eseguire il RET. Questa
operazione assicura che la funzione chiamante trovi i registri
inalterati una volta terminata l’esecuzione della subroutine.
Direttive di definizione variabili
Sintassi: label dl/dw/db n {,nj}
Dichiara una variabile di nome label inizializzata al valore n.
Eventuali altri numeri specificati oltre il primo sono allocati
consecutivamente in memoria a partire dall’indirizzo associato a
label. Tale indirizzo è scelto dall’assemblatore!
var1
DW
4
var1 è un place-holder per una word collocata in memoria in una
locazione scelta dall’assemblatore ed inizializzata a 4.
var2
DL
4, 22h, 3
alloca 3 longwords inizializzate a 4, 22h e 3. var2 punta alla prima
locazione
Utilizzo subroutine mondo reale
1. Implementazione di chiamate a funzioni /
metodi
2. Interruzione asincrona del flusso di
esecuzione di un programma
3. Implementazione di porzioni di codice per la
gestione di eventi (Gestione driver )
• ….un milione di altri usi……
Scarica

Gestione delle subroutine