Calcolatori elettronici/Le procedure

Wikibooks, manuali e libri di testo liberi.
Jump to navigation Jump to search
CopertinaCalcolatori elettronici/Copertina
  1. L'evoluzione dei sistemi di elaborazioneCalcolatori elettronici/L'evoluzione dei sistemi di elaborazione
  2. Il progetto di circuiti logiciCalcolatori elettronici/Il progetto di circuiti logici
  3. I processoriCalcolatori elettronici/I processori
  4. Architettura 8086Calcolatori elettronici/Architettura 8086
  5. Unità di controlloCalcolatori elettronici/Unità di controllo
  6. Introduzione alle memorieCalcolatori elettronici/Introduzione alle memorie
  7. Le memorie ad accesso casualeCalcolatori elettronici/Le memorie ad accesso casuale
  8. Le memorie cacheCalcolatori elettronici/Le memorie cache
  9. Le memorie ad accesso serialeCalcolatori elettronici/Le memorie ad accesso seriale
  10. La memoria virtualeCalcolatori elettronici/La memoria virtuale
  11. La gestione dei dispositivi input/outputCalcolatori elettronici/La gestione dei dispositivi input/output
  12. Intel 8255Calcolatori elettronici/Intel 8255
  13. Intel 8259Calcolatori elettronici/Intel 8259
  14. I busCalcolatori elettronici/I bus
  15. Le architetture a pipelineCalcolatori elettronici/Le architetture a pipeline
  16. Assembler 8086
IntroduzioneCalcolatori elettronici/Introduzione
  1. Informazioni generaliCalcolatori elettronici/Informazioni generali
  2. Istruzioni di trasferimento datiCalcolatori elettronici/Istruzioni di trasferimento dati
  3. Istruzioni aritmeticheCalcolatori elettronici/Istruzioni aritmetiche
  4. Istruzioni per il controllo del flussoCalcolatori elettronici/Istruzioni per il controllo del flusso
  5. Istruzioni per la manipolazione dei bitCalcolatori elettronici/Istruzioni per la manipolazione dei bit
  6. Le procedureCalcolatori elettronici/Le procedure
  7. Istruzioni per il controllo del processoreCalcolatori elettronici/Istruzioni per il controllo del processore
  8. Formato delle istruzioni macchina, tempi di esecuzioneCalcolatori elettronici/Formato delle istruzioni macchina, tempi di esecuzione

Una procedura è una porzione di codice richiamabile tramite il suo nome in qualsiasi punto del programma. Il salto alla procedura supporta il ritorno al chiamante. Migliora la leggibilità del codice e risparmia memoria.

Struttura[modifica]

Una procedura si definisce in questo modo:

<etichetta> PROC <tipo>
...
<etichetta> ENDP

La procedura può essere richiamata con l'istruzione CALL <etichetta>. In realtà nell'istruzione CALL l'assemblatore converte il simbolo <etichetta> nell'indirizzo della prima istruzione della procedura. Alla chiamata, l'indirizzo del chiamante viene salvato dall'IP allo stack.

L'istruzione RET, priva di parametri, permette di ritornare alla procedura chiamante.

Località[modifica]

Una procedura di tipo NEAR (predefinito) può essere richiamata solo all'interno dello stesso segmento di codice, e viene richiamata da una CALL su 3 byte tramite l'offset della sua prima istruzione. Una procedura di tipo FAR può essere chiamata da procedure appartenenti a segmenti di codice diversi; la CALL su 5 byte prima di caricare l'offset della procedura deve modificare il registro CS, effettuando il push nello stack del vecchio valore di CS.

Anche l'istruzione RET si distingue per i tipi NEAR e FAR, effettuando la pop dallo stack di uno o due word.

Stack[modifica]

Memorizzazione di variabili locali[modifica]

La procedura può memorizzare temporaneamente nello stack le variabili dichiarate in modo locale al suo interno.

Backup del contenuto dei registri[modifica]

Le procedure vengono richiamate tramite l'istruzione CALL, che salta alla prima istruzione della procedura. Al termine della procedura, l'istruzione RET deve poter ritornare al chiamante → l'istruzione CALL, prima di sovrascrivere il PC con il nuovo indirizzo, deve quindi temporaneamente salvare (push) nello stack il PC del chiamante, che verrà letto (pop) dall'istruzione RET. La struttura LIFO garantisce che l'ordine dei PC letti da una serie di istruzioni RET appartenenti a procedure annidate sia corretto, cioè dall'ultima procedura chiamata fino al primo chiamante.

I valori dei registri possono essere salvati prima della prima istruzione e ripristinati dopo l'ultima istruzione, in modo che la procedura non "sporchi" i registri.

Passaggio di parametri[modifica]

I linguaggi assembler non hanno alcun meccanismo apposito per il passaggio dei parametri.

Prima della chiamata della procedura il chiamante può salvare nello stack i parametri, che verranno letti durante l'esecuzione della procedura. Il problema è che l'istruzione CALL li coprirebbe con il valore dell'IP. Il registro BP serve per salvare temporaneamente il valore del­l'SP subito dopo la chiamata come prima istruzione della procedura (lo stack si riempe a partire dal fondo), in modo che il primo parametro sia accessibile all'indirizzo [BP+2]. Un semplice ripristino dell'SP al valore originario segue il ritorno al chiamante. I parametri di ritorno possono essere salvati dalla procedura e letti dal chiamante in una posizione destinata appositamente nello stack tramite una istruzione SUB dell'SP che precede le push dei parametri. Non c'è limite al numero di parametri, e i parametri rimangono in memoria solo per il tempo di esecuzione della procedura. Questa soluzione non può essere applicata a procedure annidate, perché il registro BP può contenere un solo valore di SP; per ovviare a questo problema, si può salvare il contenuto di BP a sua volta nello stack subito prima di sovrascriverlo con il valore di SP, e quindi ripristinarlo con una pop subito prima della istruzione RET, avendo l'accortezza di accedere al primo parametro all'indirizzo [BP+4].

Altri modi[modifica]

Variabili globali[modifica]

La procedura può usare direttamente delle variabili globali, che sono visibili a tutte le procedure compresa quella chiamante.

Svantaggio
non è una soluzione flessibile
Registri[modifica]

Lo scambio di informazioni tra la procedura e il chiamante avviene tramite i registri.

I registri che non sono restituiti al programma chiamante possono essere usati internamente alla procedura, salvando temporaneamente nello stack i loro vecchi valori.

Svantaggio
il numero di registri è limitato