Sezione

Indirizzi Base Registri Interni
Area Comunicazione BIOS Funzioni BIOS Funzioni DOS
Prefazione Capitolo 1 Capitolo 2 Schede
Libreria ASM Libreria MAC Palestra Progetti ASM
Info Download INDICE

Schede del Tutorial

Home » Programma il Computer » Tutorial Assembly

Le Schede del Tutorial

  Stack - Definizione e Gestione

SCHEDA n° 06 [ 4  di 7] 

    

    Lo Stack nella gestione di Procedure FAR
     
bulletQuando il processore esegue un'istruzione di chiamata (CALL ProcFar) di Procedura FAR provvede ai seguenti compiti:
bulletcalcola l'indirizzo Offset dell'istruzione successiva a quella che sta eseguendo, sommando 0005 (numero di bytes del codice macchina corrispondente a CALL ProcFar) all'indirizzo corrente.
bulletdecrementa il valore corrente di SP e lo utilizza per puntare la locazione in cui scrivere la parte alta del registro CS.
bulletdecrementa ancora il valore di SP e lo utilizza per puntare la locazione in cui scrivere la parte bassa di CS.
bulletdecrementa ancora SP e lo utilizza per puntare la locazione in cui scrivere la parte alta dell'indirizzo di offset calcolato poco fa.
bulletdecrementa ancora SP e lo utilizza per puntare la locazione in cui scrivere la parte bassa dell'indirizzo di cui sopra.
bulletcarica IP con l'indirizzo di offset ProcFar, primo operando dell'istruzione.
bulletcarica CS con l'indirizzo di segment ProcFar, secondo operando dell'istruzione, obbligando di fatto se stesso a saltare al nuovo indirizzo CS:IP.
bulletDopo l'esecuzione di CALL ProcFar, il processore si trova in tutt'altro ambiente, lontano dal programma principale da cui è partito, probabilmente addirittura in un altro segmento; si mette ad eseguire diligentemente tutte le istruzioni della procedura, in attesa della RET, che gli consentirà di tornare nel suo percorso nativo, naturalmente subito dopo l'istruzione CALL.
bulletQuando il processore esegue l'istruzione RET (probabilmente l'ultima della Procedura FAR in cui è stato costretto a saltare) provvede ai seguenti compiti:
bulletpreleva il byte contenuto nella locazione attualmente puntata da SP, lo trasferisce nella parte bassa di IP.
bulletincrementa il valore di SP e lo utilizza per puntare la locazione da cui prelevare il byte da utilizzare come parte alta di IP.
bulletincrementa ancora SP e lo utilizza per puntare la locazione da cui prelevare la parte bassa di CS.
bulletincrementa ancora SP e lo utilizza per puntare la locazione da cui prelevare la parte alta di CS.
bulletincrementa ancora il valore di SP.
bulletsalta alla locazione di programma indicata dal nuovo valore di CS:IP, praticamente l'indirizzo logico completo della locazione del programma principale successiva a quella con la CALL che l'aveva costretto ad uscirne.
bulletDopo l'esecuzione di RET, il processore è dunque rientrato nei ranghi...

      

Ricorda... Nonostante la apparente somiglianza con quello della pagina precedente l'istruzione RET è ora completamente diversa: recupera dallo Stack 4 bytes invece di 2. Poichè corrisponde ad una chiamata FAR è l'assemblatore stesso a codificarla in modo adeguato: dalle figure in dotazione possiamo vedere che la RET FAR ha codice operativo CBH, mentre quello della RET NEAR è C3H

      

bulletI movimenti del processore e dei suoi registri possono essere monitorati, sviluppati e analizzati in ambiente Debug, con l'aiuto di una semplice sequenza di istruzioni usata come banco di prova; a sinistra osserviamo i valori dei registri e a destra l'aspetto dello Stack, nelle varie fasi:

      

0DE0:0100 B80201     MOV AX,0102
0DE0:0103 9A0C01E00D CALL 0DE0:010C  
0DE0:0108 B44C       MOV AH,4C
0DE0:010A CD21       INT 21
0DE0:010C 01C3       ADD BX,AX       
0DE0:010E CB         RETF            



-R   punto *1* --------------------------
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFFE
DS=0DE0 ES=0DE0 SS=0DE0 CS=0DE0 IP=0100
0DE0:0100 B80201     MOV AX,0102

-T   punto *2* --------------------------
AX=0102 BX=0000 CX=0000 DX=0000 SP=FFFE
DS=0DE0 ES=0DE0 SS=0DE0 CS=0DE0 IP=0103
0DE0:0103 9A0C01E00D CALL 0DE0:010C

-T   punto *3* --------------------------
AX=0102 BX=0000 CX=0000 DX=0000 SP=FFFA
DS=0DE0 ES=0DE0 SS=0DE0 CS=0DE0 IP=010C
0DE0:010C 01C3       ADD BX,AX

-T   punto *4* --------------------------
AX=0102 BX=0102 CX=0000 DX=0000 SP=FFFA
DS=0DE0 ES=0DE0 SS=0DE0 CS=0DE0 IP=010E
0DE0:010E CB         RETF

-T   punto *5* --------------------------
AX=0102 BX=0102 CX=0000 DX=0000 SP=FFFE
DS=0DE0 ES=0DE0 SS=0DE0 CS=0DE0 IP=0108
0DE0:0108 B44C       MOV AH,4C
--- punto *1* e *2* ---
0DE0:FFFC ??
0DE0:FFFD ??
0DE0:FFFE 00 <- SP=FFFE
0DE0:FFFF 00

--- punto *3* ---------
0DE0:FFF8 ??
0DE0:FFF9 ??
0DE0:FFFA 08 <- SP=FFFA
0DE0:FFFB 01
0DE0:FFFC E0
0DE0:FFFD 0D
0DE0:FFFE 00 
0DE0:FFFF 00

--- punto *4* ---------
0DE0:FFF8 ??
0DE0:FFF9 ??
0DE0:FFFA 08 <- SP=FFFA
0DE0:FFFB 01
0DE0:FFFC E0
0DE0:FFFD 0D
0DE0:FFFE 00 
0DE0:FFFF 00

--- punto *5* ---------
0DE0:FFF8 ??
0DE0:FFF9 ??
0DE0:FFFA 08
0DE0:FFFB 01
0DE0:FFFC E0
0DE0:FFFD 0D
0DE0:FFFE 00 <- SP=FFFE
0DE0:FFFF 00 

      

bulletAll'inizio (punto *1*), poichè la coppia di registri CS:IP contiene 0DE0:0100, il processore si trova costretto ad eseguire l'istruzione MOV AX,0102
bulletil puntatore di Stack punta la locazione SP=FFFE, a dimostrazione del fatto che il sistema operativo ha già consumato per sè una posizione di Stack (leggi la nota, PSP- offset 0000, se non ricordi o non sai il perché) caricandoci 2 bytes a 00H.
bulletDopo l'esecuzione di MOV AX,0102 (punto *2*), la coppia di registri CS:IP contiene 0DE0:0103: il processore si accinge ad eseguire CALL 0DE0:010C il puntatore di Stack non è stato influenzato dall'istruzione MOV: il suo valore è ancora SP=FFFE.
bulletDopo l'esecuzione di CALL 0DE0:010C (punto *3*):
bulletil puntatore di codice CS:IP contiene 0DE0:010Cdato che la procedura chiamata è FAR il nuovo valore di CS può essere quello di un segmento qualunque; il fatto che CS è inalterato è casuale, dovuto alla nostra scelta di definire la procedura comunque nel medesimo segmento, pur dichiarandola lontana (FAR).
bulletil puntatore di codice CS:IP punta dunque prima istruzione della procedura, cioè si accinge ad eseguire ADD BX,AX.
bulletil puntatore di Stack punta la locazione SP=FFFA, a dimostrazione del fatto che sono state consumate altre 2 posizioni di Stack: il dettaglio a destra mostra che nello Stack sono finiti il segment e l'offset della locazione successiva a quella (nel programma principale) in cui è scritta la CALL 0DE0:010C (0DE0:0108) cioè i 4 bytes a 0DH, E0H, 01H e 08H, nell'ordine indicato, per rispettare la tecnica Lo-Hi.
bulletDopo l'esecuzione di ADD BX,AX , dentro la procedura (punto *4*), la coppia di registri CS:IP contiene 0DE0:010E: il processore si accinge ad eseguire RET il puntatore di Stack non è stato influenzato dall'istruzione ADD: il suo valore è ancora SP=FFFA.
bulletDopo l'esecuzione di RET, naturalmente di tipo FAR, dentro la procedura (punto *5*):
bulletil puntatore di codice CS:IP contiene 0DE0:0108: il processore è tornato nel programma principale e si accinge ad eseguire l'istruzione MOV AH,4C.
bulletil puntatore di Stack punta la locazione SP=FFFE, a dimostrazione del fatto che ha recuperato entrambe le posizioni di Stack indotte in precedenza dalla CALL 0DE0:010C.

      

bulletRiassumiamo la dinamica dello Stack, nella gestione di una chiamata di procedura extrasegmentale (FAR); quando il processore è finalmente rientrato nel programma principale (per l'azione della RET far della procedura, dopo esserne uscito per l'azione di CALL ProcFar):
bulletil puntatore di Stack ha il valore che aveva prima di iniziare il servizio di chiamata-procedure (nell'esempio SP=FFFE).
bulletsi può sottolineare che, in accordo con le definizioni, SP sta puntando la locazione successiva a quella che sarà caricata, in futuro, cioè sempre esterna all'area utile corrente dello Stack!
bulletle 4 locazioni precedenti quella puntata da SP mostrano ancora i 4 valori che il processore ha introdotto; la figura mette in evidenza che la scrittura è avvenuta con la tecnica Lo-Hi (cioè prima la parte bassa, Low,  e poi la parte alta, High, sia di CS che di IP).
bulletil fatto che la ram sia rimasta sporca dei 4 bytes precedentemente caricati è irrilevante: le prossime operazioni che coinvolgeranno lo Stack in scrittura si limiteranno semplicemente a sovrascrivere questi valori.
bulletin ogni caso le prime 2 locazioni dello Stack sono sempre precaricate con 2 bytes a 00H dal sistema operativo (per le note vicende).

      

SP:FFF8 ?? non ancora utilizzato
SP:FFF9 ?? non ancora utilizzato
SP:FFFA 08 Lo Offset
SP:FFFB 01 Hi Offset
SP:FFFC E0 Lo Segment
SP:FFFD 0D Hi Segment
SP:FFFE 00 <- SP=FFFE
SP:FFFF 00 

    

Pagina Precedente Scheda n° 06 Pagina Successiva Stack - Definizione e Gestione Torna al Menu delle Schede del "Tutorial" Lezioni - Vai al DownLoad dei files DOC Torna al Menu del "Tutorial"
Scheda n° 06 -  4
1 2 3 4 5 6 7

    

SCHEDE » 1.Header EXE 2.PseudoOp MASM 3.Differenza tra Macro e Procedure
4.
Tabella Vettori 5.PSP 6.Stack 7.Istruzioni 80x86
8.La misura dell'Informazione 9.Numeri e Logica Binaria
TUTORIAL » Indirizzi Base | Registri Interni | Area Comunicaz. BIOS | Funzioni BIOS | Funzioni DOS
Prefazione | CAP 1 | CAP 2 | Schede | Palestra
Libreria ASM | Libreria MAC | Progetti ASM | Download | Info | Indice
Home 
Pascal|Manuali|Tabelle|Schede
Tutorial Assembly|Palestra Assembler
Aggiungi Giobe®2000 ai preferiti  
Motore
Ricerca
  Rendi Giobe®2000 pagina di Default
© 2001-2010  -  Studio Tecnico ing. Giorgio OBER
Tutti i diritti sono riservati