Lezione 2

Step 3/4

Passo precedenteInizio lezionePasso successivo

Il Program Counter e lo Stack

 

In questo passo analizzeremo il funzionamento del Program Counter e dello Stack due componenti importanti per la comprensione delle istruzioni di salto e chiamata a subroutine.

Come visto nei passi precedenti, il PIC16F84 inizia l'esecuzione del programma a partire dal Reset Vector ovvero dalla locazione di memoria 0000H. Dopo aver eseguito questa istruzione passa all'istruzione successiva memorizzata nella locazione 0001H e così via. Se non ci fossero istruzioni in grado di influenzare l'esecuzione progressiva del programma, il PIC arriverebbe presto ad eseguire l'istruzione memorizzata nell'ultima locazione e non saprebbe più come continuare.

Sappiamo ovviamente che non è così e che qualsiasi sistema a microprocessore o linguaggio di programmazione dispone di istruzioni di salto, ovvero istruzioni in grado di modificare il flusso di esecuzione del programma.

Una di queste istruzioni è il goto (dall'inglese go to, vai a). Quando il PIC incontra una goto non esegue più l'istruzione immediatamente successiva ma salta direttamente alla locazione di memoria specificata nell'istruzione.

Facciamo un esempio:

	ORG	00H

Point1
	movlw	10
	goto	Point1

Al reset il PIC eseguirà l'istruzione movlw 10 memorizzata alla locazione 0000H che inserirà nell'accumulatore il valore decimale 10. Quindi passerà all'istruzione successiva goto Point1. Questa istruzione determinerà un salto incondizionato alla locazione di memoria puntata dalla label Point1 ovvero di nuovo alla locazione 0000H.

Il programma non farà altro che eseguire un ciclo infinito eseguendo continuamente le due istruzioni elencate.

Durante questo ciclo, per determinare quale è la successiva istruzione da eseguire, il PIC utilizza uno speciale registro denominato Program Counter ovvero contatore di programma. Questo viene sempre aggiornato con l'indirizzo della prossima istruzione da eseguire. Al reset esso viene azzerato, determinando l'inizio dell'esecuzione dall'indirizzo 0000H, ad ogni istruzione viene invece incrementato di uno per consentire il passaggio all'istruzione successiva.

L'istruzione goto consente l'inserimento di un nuovo valore nel Program Counter ed il di conseguente salto ad una locazione qualsiasi dell'area programma del PIC.

Un'altra istruzione molto interessante è la call ovvero la chiamata a subroutine.

Questa istruzione funziona in maniera molto simile alla goto con l'unica differenza che prima di eseguire il salto memorizza, in una locazione di memoria particolare denominata Stack, l'indirizzo di quella che sarebbe dovuta essere la prossima istruzione da eseguire se non ci fosse stata la call.

Vediamo meglio con un esempio:

	ORG	00H

Point1
	movlw	10
	call	Point2
	goto	Point1

Point2
	movlw	11
	return

In questo caso il PIC, dopo aver eseguito la movlw 10 passa ad eseguire la call Point2. Prima di saltare memorizza nello Stack l'indirizzo 0002H, ovvero l'indirizzo della locazione successiva alla call. Passa quindi ad eseguire l'istruzione movlw 11, memorizzata in corrispondenza della label Point2. A questo punto incontra una nuova istruzione la return che, come di deduce dal suo nome, consente di "ritornare", ovvero di tornare ad eseguire l'istruzione successiva alla call.

L'operazione appena effettuata viene denominata: "chiamata a subroutine", ovvero interruzione momentanea del normale flusso del programma per "chiamare" in esecuzione una serie di istruzioni, per poi tornare al normale flusso di esecuzione.

Per poter riprendere da dove aveva interrotto, il PIC utilizza l'ultimo valore inserito nello Stack e lo inserisce di nuovo nel Program Counter.

La parola stack in inglese significa "catasta" ed infatti su di esso è possibile accatastare l'uno sull'altro gli indirizzi per recuperarli quando servono. Questo tipo di memorizzazione viene anche denominata LIFO dall'inglese Last In First Out, in cui l'ultimo elemento inserito (last in) deve necessariamente essere il primo ad uscire (last out).

Grazie allo stack è possibile effettuare più call, l'una dentro l'altra e mantenere sempre traccia del punto in cui riprendere il flusso al momento che si incontra una istruzione return.

Vediamo un altro esempio:

	ORG	00H

Point1
	movlw	10
	call	Point2
	goto	Point1

Point2
	movlw	11
	call	Point3
	return

Point3
	movlw	12
	return

In questo caso nella subroutine Point2 viene effettuata un'ulteriore call alla subroutine Point3. Al ritorno da quest'ultima il programma dovrà rientrare nella subroutine Point2 eseguire la return e quindi tornare nel flusso principale.

Gli indirizzi da memorizzare nello stack sono due in quanto viene incontrata una seconda call prima ancora di incontrare la return corrispondente alla prima. Si dice quindi che le call sono "nidificate" ovvero l'una dentro l'altra.

Il PIC16F84 dispone di uno stack a 8 livelli, ovvero uno stack che consente fino ad 8 chiamate nidificate.

E' importante assicurasi, durante la stesura di un programma, che ci sia sempre una istruzione return in corrispondenza ad una call per evitare pericolosi disallineamenti dello stack che in esecuzione possono dar adito a errori difficilmente rilevabili.

Nel passo successivo modificheremo il nostro source LED.ASM per fissare meglio quanto finora appreso.

 
Home page

PICPOINT, SXPOINT and ELETTROSHOP (C) 1997/98 by Andrea Galizia
For comments on this web site, write to webmaster@picpoint.com
Web design by Tiziano Galizia

Pic by example (c) 1997/98 by Sergio Tanzilli & Tiziano Galizia