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.
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)
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.
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).
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.
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).
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.
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.
Data di creazione di questa pagina: febbraio 2017
Ultima modifica: 27 ottobre 2017
Assembly PIC18 - Versione 0.5 - aprile 2018
Copyright 2016-2018, Vincenzo Villa (https://www.vincenzov.net)
Assembly PIC18 di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale