Tutorials - PIC - Corso A&C

 

Esercitazioni PIC - Assembly


Le direttive di MPASM

Le direttive (directives) appaiono simili alle istruzioni, ma si tratta di "istruzioni" dirette al compilatore, in generale indipendenti dal modello di microcontroller, e che hanno come scopo il controllo della compilazione. Possiamo dividerle in vari tipi:

  • direttive di controllo che permettono di realizzare sezioni di codice assemblato secondo particolari condizioni
  • direttive relative ai dati, che gestiscono l' allocazione in memoria e provvedono ai riferimenti simbolici
  • direttive di listato, che condizionano il formato del file .lst (spazi, paginazione, titolo, ecc)
  • macro direttive, che controllano l' esecuzione e l' allocazione dei dati attraverso macro definizioni
  • direttive relative al file oggetto, che ne permettono la creazione
  In generale, le direttive:
  1. non possono iniziare in prima colonna, ad eccezione di #define
  2. supportano una label, ad eccezione di alcune, come glogal, extern, ecc
  3. sono "parole riservate" e non possono essere usate altro che per la loro funzione

Va notato che MPASM accetta i nomi delle direttive e degli opcodes sia in maiuscolo che in minuscolo, quindi
END o end  e bsf o BSF sono equivalenti.

L' uso del maiuscolo e del minuscolo fanno parte dello stile personale del programmatore, anche se l' attenersi ad una qualche linea guida è altrettanto utile dell' ordine formale del sorgente.

Per quanto riguarda il punto 1, va tenuto presente il limite della prima colonna di testo, che l' Assembler considera rigorosamente, dato che la posizione è determinante, ad esempio, per la dichiarazione di una label durante la compilazione.
Nella prima colonna del testo sorgente possono iniziare i commenti, le label che vengono in tal modo definite ed alcune direttive. Tutto il resto (opcodes, label di macro e la gran parte delle direttive) NON può iniziare in prima colonna, pena una segnalazione di errore del compilatore e l' impossibilità di generare il codice oggetto.

Questa necessità fa si che la "forma" con cui è scritto il sorgente sia meno che mai un mero fatto estetico. Si potranno usare uno spazio (space) o più oppure una o più tabulazioni (tab) per separare gli elementi in una riga o allontanarne l' inizio dalla prima colonna.

Per quanto riguarda il terzo punto, i nomi delle direttive e delle funzioni dell' Assembler e gli mnemonici degli opcodes non possono essere usati per altre funzioni. Così pure le label specificate nel file processore.inc  non possono essere usate se non per indicare quanto specificato. Questo è evidente, dato che la stessa label non può essere duplicata con riferimento a diversi valori.
Ricordiamo che la label è un simbolo che sottintende un valore esadecimale, sia esso un indirizzo, un numero, la posizione di un bit in un registro, ecc. Quindi ogni label deve essere univoca e se possono esistere label a cui è attribuito uno steso valore, non possono esistere label uguali a cui sono attribuiti valori diversi. Altrimenti come potrebbe il compilatore, che trasforma le label in valori binari, eseguire correttamente il suo lavoro?

Molte direttive hanno la possibilità di accettare diverse forme del nome, per mantenere  la compatibilità con vecchie versioni dell' Assembler.

Le direttive di MPASM sono circa 56. Il già citato MPASM User's Guide riporta queste direttive e le regole per il loro uso.

Tra le direttive di uso comune, esistono alcune funzioni logiche per condizionare la compilazione. Ad esempi0:

 #if LCDLINENUM == 1    ; 1 line module - N=0
     movlw
LCD_1L       ; low nibble b'0000' 1 line, 5x7
 
#else                  ; more lines module - N=1
     movlw
LCD_2L       ; low nibble b'1000' 2 lines, 5x7
 
#endif

oppure

 VARIABLE vCNT          ; local variable
vCNT = LCDNIBBLE        ; assign pre-defined constant
 
WHILE vCNT > 0x0      ; perform loop to insert shift
     rlncf
LCDbuf1, w   ; shift data to aligne w/ output pins
 
vCNT -= 1
 
ENDW

Ma è C? No, per nulla. Si tratta dell' uso delle direttive di controllo che condizionano la compilazione.

  Va compreso in modo molto chiaro che questi elementi logici riguardano la compilazione e NON l' esecuzione del programma

In questo senso i cicli if e while hanno la stessa funzione logica che avrebbero in un sorgente C, ma non agiscono creando funzioni che opereranno durante l' esecuzione del programma, bensì agiscono solo ed esclusivamente durante la compilazione, determinando le istruzioni che entreranno a far parte dell' oggetto.

Nel primo esempio, il senso è: se la variabile LCDLINENUM è uguale a 1, il compilatore considererà la linea  movlw LCD_1L , altrimenti la linea movlw LCD_2L.

Nel secondo caso, fino a che counter vCNT è maggiore di 0, il compilatore inserirà istruzioni rlncf LCDbuf1, w nell' eseguibile.

Un esempio più chiaro si potrà avere considerando questo impiego del ciclo if-else-endif:

  #ifdef ___18F13K22

     LIST p=18F13K22            ; Definizione del processore
     #include <p18F13K22.inc>

  #else
     LIST p=18F14K22            ; Definizione del processore

     #include <p18F14K22.inc>
  #endif
 

A seconda del processore definito, sarà compilato il relativo set di riferimento. 

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 17/09/14.