Salta la barra di navigazione [1] - Vai alla barra di navigazione [3] - Scrivimi una mail [4]

PIC18: subroutines in assembly

Assembly PIC18 - PIC18 in C - Sommario - Novità - Tutorial - Progetti - Risorse - Non solo elettronica

Scheda con PIC18

In fase di sviluppo Stesura preliminare In fase di sviluppo

Una subroutine è una sequenza di istruzioni Assembly che realizza un determinato compito. Questa sequenza viene chiamata (call) all'interno di un generico codice e, al termine, ritorna (return) ad eseguire l'istruzione seguente la call.

Un esempio semplice

Questo primo esempio (a fondo pagina il codice completo) realizza un ciclo di ritardo, cioè una sequenza di istruzione il cui unico scopo è quello di far trascorrere un po' di tempo. Con l'esperienza si scoprirà che questo non è un buon esempio in quanto viene usata energia e potenza di calcolo al solo scopo di non fare nulla! Ma è una delle cose che all'inizio della carriera del programmatore sembra essere tra le più utili...

Il codice è piuttosto semplice: inizia con una label qualunque (ritardo_breve) e termina con l'istruzione return

ritardo_breve   ; introduce un ritardo di circa 3 ms (@ 1 MHz)
    clrf WREG   ; azzera il registro W
ripeti
    decfsz WREG ; decrementa il registro W e salta l'istruzione seguente
                ; quanto W=0
    bra ripeti  ; ripeti
    return      ; torna all'istruzione dopo la "call"

Il funzionamento del codice è intuitivo:

Il tempo impiegato dipende ovviamente dalla frequenza di clock del processore. Se questa è pari ad 1 MHz il ritardo introdotto è di poco più di 3 ms (esercizio 1). Tale tempo è, su scala umana, molto piccolo ed insufficiente per vedere il LED lampeggiare.

Per richiamare la subroutine, anche più volte, è sufficiente scrivere:

    call ritardo_breve

Alcune osservazioni:

Un secondo esempio

Una subroutine, per essere davvero utilizzabile, non deve come effetto collaterale modificare i registri che descrivono lo stato del processore, cioè i registri WREG, STATUS e BSR.

Una possibile soluzione è quella di creare alcuni registri temporanei che permettono di salvare i valori di tali registri all'inizio del codice della subroutine e di recuperarli al termine.

Questa tecnica è mostrata nella seconda versione della routine di ritardo. Questo codice contiene due subroutines:

Il salvataggio nei registri temporanei di WREG e STATUS è reso necessario dal fatto che entrambe le subroutines usano gli stessi registri: non salvarli avrebbe causato un'interferenza tra le due subroutines e, in definitiva, il loro mancato funzionamento.

Si noti che per quanto riguarda ritardo_lungo non è stato implementato alcun meccanismo di registri temporanei; sarebbe stata necessaria la creazione di ulteriori registri temporanei, con spreco di spazio e potenziali rischi difficili da controllare nel caso di omonimie. (nota 2)

L'ultimo esempio

L'ultimo esempio mostra l'utilizzo dello stack software per il salvataggio dei registri, attraverso alcune macro che ne rendono più intuitivo l'uso.

Questa può essere considerata la soluzione definitiva, utilizzabile anche in altri contesti, come quello delle interruzioni.

Codice

Esercizi

  1. Calcolare il tempo impiegato dalla subroutine ritardo_breve per completare la sua esecuzione. Occorre sommare il tempo di esecuzione di ciascuna istruzione e moltiplicare per il numero di volte per cui una sezione del codice è ripetuta

Note

  1. L'esempio mostra, per generalità, anche il salvataggio del Bank Select Register, sebbene in questo caso non viene modificato all'interno della subroutine
  2. In teoria PIC18 implementa un metodo automatico per il salvataggio dei registri (fast register stack), ma, essendo ad un solo livello è assolutamente sconsigliato il suo uso per subroutines generiche. In genere viene riservato alle interrupt ad alta priorità
  3. In realtà alcuni livelli dello stack sono usati dal debugger

Ultima modifica di questa pagina: 7 maggio 2016


Assembly PIC18

Licenza Creative Commons Attribuzione 4.0 Internazionale


EN - Pagina principale - Sommario - Accessibilità - Note legali e privacy policy - Posta elettronica

XHTML 1.0 Strict - CSS 3