Le variabili

Le variabili

L'uso della memoria fatto scrivendo manualmente gli indirizzi con codifica esadecimale è spesso complicata da leggere e grande fonte di errori. Per questo si preferisce assegnare un nome a ciascuna variabile, lasciando all'assemblatore l'onere di individuare lo spazio effettivo in RAM da utilizzare.

Variabili create nell'Access Bank

Questa è la modalità più semplice per creare e usare variabili.

Le variabili da memorizzare all'interno dell'Access Bank devono essere dichiarate dopo la parola chiave  UDATA_ACS, specificando una label, la parola chiave res e la dimensione in byte.

Esempio 1 - le righe 1-4 del codice seguente chiedono all'assemblatore di riservare lo spazio necessario per memorizzare tre variabili  di dimensioni pari ad un byte; queste celle saranno identificate dalle tre label a, b e pippo)

Variabili a, b e pippo

Qualche osservazione:

Di seguito il codice generato in corrispondenza del codice appena mostrato, in cui è effettivamente stato inserito dall'assemblatore, in modo automatico ,ACCESS:

0000 0E05 MOVLW 0x5          7: movlw 0x05
0002 6E00 MOVWF 0x0, ACCESS  8: movwf a
0004 6E01 MOVWF 0x1, ACCESS  9: movwf b
0004 6E02 MOVWF 0x2, ACCESS 10: movwf pippo

Esercizio 1 - Esaminare sui fogli tecnici il comportamento dell'istruzione movf

Esercizio 1a - Eseguire passo passo l'esempio 1 osservando il contenuto delle variabile nella finestra di Watch e all'interno della finestra dei File Registers.

Variabili create in un generico banco

Per utilizzare tutta la RAM disponibile, è necessario utilizzare i banchi (nota 1). Per una descrizione dei banchi: La memoria RAM

Per riservare spazio per una variabile all'interno di un generico banco è necessario utilizzare la parola chiava UDATA, associata ad una label.

Esempio 2 - Il codice esemplificativo seguente riserva:

primo   UDATA
a       res 1
b       res 1

secondo UDATA
a1      res 1
a2      res 1
b1      res 1

acs     UDATA_ACS
a_acs   res 1

Qualche osservazione, in aggiunta a quelle già fatte a proposito dell'Access Bank:

L'uso di una variabile posta in un banco richiede obbligatoriamente la selezione preventiva del banco in cui si trova; è consigliabile, invece dell'uso diretto dello Special Register BSR, l'utilizzo della direttiva assembler banksel, tradotta nell'opportuna istruzione assembly movlb (MOVe Literal to low nibble in Bsr), ricavando automaticamente l'indirizzo del banco in cui la variabile si trova.

Esempio 2a - Dopo aver definito le variabili come nell'esempio 2, è possibile utilizzare il seguente codice:

  movlw 0x05  

  banksel a
  movwf a

  banksel a2
  movwf a2
  movwf a1

  movwf a_acs

Alcune osservazioni utili per comprendere questo esempio:

Esercizio 2 - Eseguire passo passo l'esempio 2/2a osservando il contenuto delle variabile nella finestra di Watch e all'interno della finestra dei File Registers.

Di seguito il listato generato in corrispondenza del codice appena mostrato, in cui è effettivamente stato inserito dall'assemblatore, in modo automatico, lo switch BANCKED per tutte le variabili che lo richiedono:

0000 0E05 MOVLW 0x5         28: movlw 0x05
                            29:
0002 0101 MOVLB 0x1         30: banksel a
0004 6F00 MOVWF 0x0, BANKED 31: movwf a
                            32:
0006 010E MOVLB 0xE         33: banksel a2
0008 6F01 MOVWF 0x1, BANKED 34: movwf a2
000A 6F00 MOVWF 0x0, BANKED 35: movwf a1
                            36:
000C 6E00 MOVWF 0x0, ACCESS 37: movwf a_acs

Scorrendo il codice possiamo osservare, per esempio, che la variabile "a" ha indirizzo 0x100 (banco 0x1, indirizzo 0x00) e che la variabile "a2" ha indirizzo 0xE01 (banco 0xE, indirizzo 0x01). Queste assegnazioni potrebbero comunque cambiare senza alcun preavviso (nota 2).

Variabili di più byte

A volte una variabile di un byte è troppo piccola per contenere una certa informazione. Per esempio un numero maggiore di 255 oppure una stringa non possono essere contenuti in un solo byte. Per questo è necessario specificare che una variabile occupa più di un byte, scrivendolo dopo la parola chiave res.

Per esempio, la quarta riga del codice seguente specifica che la variabile pippo richiede 2 byte consecutivi. L'esempio fa riferimento all'Access Bank, ma è estensibile a tutti i banchi.

Variabili di più byte

Nell'esempio riportato, l'assemblatore ha assegnato autonomamente alla variabile pippo le due celle con indirizzo 0x002 e 0x003: per visualizzare due o più celle come un'unica variabile è possibile cliccare con il tasto destro sul pulsante evidenziato in giallo nella precedente figura e selezionare la quantità voluta di celle da raggruppare; analogamente è possibile selezionare la base numerica o altre rappresentazioni. La modalità con cui le variabili numeriche multi-byte sono mostrate è la little endian, come riconoscibile confrontando i contenuto della finestra Variables e della finestra File Register.

I singoli byte di una variabile di più byte sono accessibili aggiungendo al nome della variabile il simbolo + seguito da un numero, come fossero gli elementi di un array. Di seguito alcuni esempi.

Esempio 3 - Per azzerate la variabile pippo definita nell'immagine precedente i due byte che la costituiscono devono essere azzerati individualmente con le seguenti due righe di codice:

 clrf pippo
 clrf pippo + 1

Esempio 4 - Creiamo una variabile numerica di 4 byte (numero intero senza segno a 32 bit) e memorizzare in essa, byte per byte, il numero 0x12345678 (pari in base dieci a 305 419 896).

Numero a 32 bit

Si noti (codice e finestra FIle Register) l'ordine con cui 4 byte sono memorizzati in memoria e come tale numero è interpretato (finestra Variables). La modalità utilizzata è little endian

Si noti inoltre come l'uso diretto della base 10 per numeri maggiori di 255 sarebbe stato troppo complesso.

Esercizi 3 e 4 - Eseguire passo passo gli esempi 3 e osservando il contenuto delle variabile nella finestra di Watch e all'interno della finestra dei File Registers.

Indirizzamento indiretto

Questo tipo di indirizzamento permette al PIC18 di accedere a tutta la RAM senza usare il concetto di banco, ma sfruttando il registro speciale a 12 bit FSR (File Select Registers, nota 3) ed il registro speciale INDF (INDirect File operand):

Il PCI18 possiede tre di tali insiemi di registri: FSR0, FSR1, FSR2 e corrispondenti INDF0, INDF1, INDF2

Esempio 5 - Questo codice mostra la scrittura del numero 0x55 in una variabile var qualunque, usando la coppia di registri FSR0 e INDF0:

primo   UDATA
var     res 1

        lfsr FSR0, var
        movlw 0x55
        movwf INDF0

Si noti che nel codice non è presente alcun riferimento al banco in cui var si trova.

Oltre a INDFx sono disponibili anche altri registri virtuali:

Un esempio d'uso in questa pagina.

Note

  1. L'istruzione movff (MOVe File register to File register)  ignora questa modalità e permette lo spostamento diretto tra due registri qualunque
  2. In realtà è possibile forzare il compilatore all'uso di determinati banchi, ma questo passaggio è spesso inutile e, quindi, dannoso. Comunque, volendosi fare del male forzando l'uso del banco 3:
    terzo UDATA 0x300
  3. In realtà sono due registri a 8 bit, uno usato solo parzialmente

 

Data di creazione di questa pagina: febbraio 2017
Ultima modifica: 27 ottobre 2017


Licenza Creative Commons Attribuzione 4.0 Internazionale


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima