|
 |
Stack
- Definizione e Gestione |
SCHEDA n° 06 [
7
di 7] |
 | Nelle pagine precedenti abbiamo descritto
l'azione immediata del processore sullo stack;
in sostanza è emerso che quest'area ram è il taccuino
personale nel quale la Cpu annota informazioni
vitali per la gestione dei programmi che è chiamata ad eseguire. |
 |
Senza
lo Stack non è dunque possibile creare programmi
degni di questo nome; nessun programma può fare a meno delle
procedure (sue o di sistema) e nessuna procedura può essere
eseguita senza assicurare il rientro nel programma principale,
non appena è terminata. |
 | Lo Stack
deve essere
sempre disponibile, poiché è dentro di esso che saranno
annotati gli indirizzi a cui tornare, al
termine delle procedure (chiamate con
CALL
o
INT). |
 | Quando si progetta un sistema basato su
microprocessori non bisogna quindi dimenticare,
come primissima cosa, di inizializzare i registri che sono chiamati a
puntare lo Stack. |
 | In mancanza di questa informazione il
processore tenterà comunque di salvare l'indirizzo
in cui è posta l'istruzione successiva a quella in cui ha trovato il
comando d'esecuzione procedura: è facile immaginare che la scrittura di
questo importante dato cadrà nel nulla (chi sa dove sarà fatta...) ed è
altrettanto facile immaginare cosa succederà al ritorno della prima
procedura eseguita: il computer si
"pianterà".... |
 | Nel caso di un personal
computer, basato su processori della famiglia 80x86, il problema non si pone
perchè già all'accensione (o dopo un reset) il processore lascia SP
al valore 0000H, mentre il loader del Sistema Operativo si assume il compito
di dare a SS
il giusto valore; il puntatore SS:SP
è dunque in grado di trovare la ram necessaria allo
Stack. |
 |
Naturalmente
non devi dimenticare che SP punta sempre la locazione successiva
a quella effettivamente caricabile, per cui il fatto che SP
sia 0000H sta a indicare che la prima locazione
dello Stack è FFFFH, dentro il segmento SS, a
partire dalla quale lo Stack crescerà indietro! |
 | La disponibilità di questa risorsa (con
PUSH
e
POP) offre al programmatore una zona
di ram piuttosto grande, in cui ospitare informazioni da condividere con le
varie parti del programma: non dimentichiamo infatti che lo Stack ha un
puntatore autonomo (SS:SP) visibile da qualunque punto, anche esterno al
segmento di codice. |
 | E' per questa ragione che taluni applicativi
utilizzano lo Stack per passare i parametri,
cioè per predisporre i valori iniziali da un
ambiente diverso da quello in cui verranno poi consumati (generalmente da
una procedura). |
 | In entrambi i casi non bisogna dimenticare che
lo stack non è infinito e che il suo
uso sprovveduto provoca danni irreversibili al
programma. |
 | Desideriamo concludere questa trattazione
proponendo un codice riassuntivo, in grado di coinvolgere lo Stack in modo
verosimile; dopo quanto scritto nelle pagine precedenti eviteremo di
descrivere i dettagli evidenziando solo la dinamica dello Stack in rapporto
ai punti **XXX** di riferimento: |
1192:0100 B83412 MOV AX,1234
1192:0103 BB7856 MOV BX,5678
1192:0106 B9BC9A MOV CX,9ABC
1192:0109 50
PUSH AX
1192:010A 53
PUSH BX
1192:010B 51
PUSH CX
1192:010C E81100 CALL 0120
1192:010F 2E9A23019211 CALL 1192:0123
1192:0115 B400 MOV AH,00
1192:0117 CD16 INT 16
1192:0119 59
POP CX
1192:011A 5B
POP BX
1192:011B 58
POP AX
|
|
 |
 | Osserviamo:
 | nessuna delle istruzioni
MOV
... ha effetto sullo Stack. |
 | le prime 2 locazioni dello Stack sono
presenti d'ufficio (le carica il loader con 00H quando alloca il
programma in memoria). |
 | ciascuno dei 3
PUSH decrementa
SP di 2, lasciandolo, alla fine, al valore
FFF8H; nello Stack viene copiato il contenuto dei 3 registri coinvolti,
1234=AX,
5678=BX
e 9ABC=CX |
 | la coppia
CALL
near/RET near fa salire e
scendere lo Stack di 2 bytes; al rientro SP vale ancora
FFF8H; nello Stack viene annotato l'offset della locazione successiva a
CALL
near, 010F. |
 | la coppia
CALL
far/RET far fa salire e
scendere lo Stack di 4 bytes; al rientro SP
vale ancora FFF8H, che comunque sovrascrivono i 2 precedenti; nello Stack viene annotato il segment e l'offset della locazione successiva a
CALL
far,
1192:0115. |
 | la coppia
INT/IRET
fa salire e scendere lo Stack di 6 bytes; al rientro SP vale ancora FFF8H, che comunque sovrascrivono i 4 precedenti; nello Stack viene annotato il valore del registro delle Flag,
3202,
seguito dal segment e dall'offset della locazione successiva a
INT, 1192:0119. |
 | ciascuno dei 3
POP incrementa
SP di 2, lasciandolo, alla fine, al valore a
FFFEH. |
 | alla fine nello Stack rimane traccia della
sua operatività (in tutto 12 bytes) ma la presenza di questi valori è
del tutto ininfluente: verranno a loro volta sovrascritti, non appena si
richiederà ulteriore attività allo Stack . |
|
 |
La
struttura dello Stack è dunque di tipo LIFO (Last Input
First Output): la prima cosa che viene tolta
è l'ultima che vi è stata inserita.
Il cerchio è chiuso: avevamo cominciato descrivendo lo Stack come
una pila di piatti e così sembra sia veramente; di solito il
primo piatto che si leva è quello in cima alla pila, l'ultimo che
abbiamo aggiunto... |
|
Scheda n° 06 |
|
|
Stack
- Definizione e Gestione |
|
 |
 |
 |
| Scheda n° 06 -
7
|
©
2001-2010 - Studio Tecnico
ing. Giorgio OBER
Tutti i diritti sono riservati
|