Tutorials - PIC - Corso A&C

 

Esercitazioni PIC - Assembly


Una breve introduzione all' Assembly

All' interno della memoria programma di un microcontroller o microprocessore viene posizionata una sequenza di numeri binari che costituiscono il "programma". Questi numeri binari corrispondono ai codici delle istruzioni che l' unità centrale andrà ad eseguire. 

Ad esempio, i bytes di un semplice programma  appariranno in questo modo:

00 00 08 28 00 00 09 00 83 01 8B 01 8C 01 86 01 83 16 BF 30 81 00 00 30 

Si tratta del "linguaggio macchina", composto dai bit utilizzati per controllare il processore, che di solito sono rappresentati come numeri esadecimali, tipicamente raccolti in byte dove 1 byte = 8 bits o in word dove 1 word = 16 bits. 

Esso fornisce il modo diretto per introdurre istruzioni in un computer al livello più basso possibile; nel passato era utilizzato per inserire i programmi, istruzione dopo istruzione, attraverso interruttori, come nel modello a lato oppure nastri o schede perforate.

E' evidente, però, che risulta ben poco pratico utilizzare direttamente questi valori binari che hanno ben poco a che fare con il nostro modo di creare i legami logici che permettono di realizzare un programma.

La soluzione è quella di utilizzare un mezzo che faccia da intermediario tra i codici binari della macchina e la logica della comunicazione umana, che ci permetta di lavorare con una forma espressiva più vicina al nostro pensare.

Quanto scritto in questo "linguaggio" è un testo denominato "sorgente"; esso verrà "tradotto" da un successivo programma, il "compilatore", che provvederà a trasformare il sorgente nel crudo linguaggio macchina di 1 e 0.

Tra le varie possibilità per trattare le operazioni che il computer deve eseguire in un modo facilmente comprensibile al pensare normale, il linguaggio Assembly è il sistema più vicino al linguaggio macchina vero e proprio.  E' costituito da segni alfabetici e parole, oltre che da numeri, non solo binari, e la concatenazione logica delle varie operazioni da eseguire è resa più evidente.  Un programma scritto in Assembly è qualcosa di ben più facilmente "leggibile" rispetto al linguaggio macchina, sopratutto per l' utilizzo di "label", etichette o parole tipicamente abbreviate o mnemonici, per rappresentare istruzioni, comandi, registri.

Il passaggio dall' Assembly ai codici binari è compito del compilatore che si chiama Assembler.

  Formalmente, quindi, esiste una differenza tra Assembly e Assembler:
  • Assembly è il linguaggio, ovvero un insieme di regole usate per la scrittura di un programma
  • Assembler è il compilatore, ovvero il programma "assemblatore" che trasforma il testo scritto in Assembly nella lista dei codici macchina che saranno scritti nella memoria del processore

L' Assembly si basa essenzialmente sull' uso degli opcodes, ovvero le sigle mnemoniche delle istruzioni del processore, permettendo di introdurre indicazioni simboliche al posto dei valori assoluti. 
A queste si aggiungono le direttive che l' Assembler può fornire, che contribuiscono alla creazione del sorgente.

Trattandosi del linguaggio più vicino a quello della macchina ed essendo limitato dall' uso degli opcodes, Assembly non dispone di strutture logiche pre definite, come quelle usate da altri linguaggi, come C o BASIC per realizare loop, condizionamenti od operazioni matematiche. Tutte queste cose, però, sono possibili anche qui, potendo creare strutture anche di notevole complessità, ma vanno realizzate a partire dagli elementi del linguaggio, anche attraverso l' uso di opzioni particolari, come un macro-Assembler, che consente di realizare macro istruzioni e procedure pre confezionate e la presenza di un Linker, che consente di scrivere, sviluppare ed utilizzare librerie. 

Gli elementi che compongono una scrittura Assembly sono di due tipi:

  • gli mnemonici relativi alle istruzioni del processore, ovvero le istruzioni del set del processore
  • le funzioni di supporto fornite dall' Assembler (direttive)

Il sorgente risulta, quindi, una miscela delle due componenti, che tendono a confondersi; quindi, nell' uso comune, Assembler e Assembly sono definizioni usate in modo equivalente.

In pratica, Assembly è quanto mai semplice da apprendere, in quanto consiste essenzialmente nel set di istruzioni native del processore e in poche regole piuttosto semplici, a cui si aggiungono le direttive citate.
Per contro, essendo privo di librerie e funzioni logiche complesse pre confezionate, richiede una maggiore energia nella scrittura del sorgente, assieme alla conoscenza dell' hardware su cui si sta lavorando, in quanto praticamente non esiste un abstraction layer tra hardware e software.

Per quanto detto, dovrebbe essere evidente che, basandosi l' Assembly sul set di istruzioni del processore, esisteranno Assembly diversi per ogni famiglia di processori e, anche se le regole generali sono le stese o strettamente analoghe, il sorgente scritto per un processore non potrà essere usato per uno differente.
Quindi non è possibile portare, salvo un lavoro che può essere anche molto complesso, il sorgente scritto, ad esempio, per un 8051 su un ARM o per un ARM su un PIC, in quanto essi hanno set di istruzioni assai diversi.

Va detto che, all' interno di una stessa famiglia di un determinato costruttore, la filosofia di progetto è unica e i set di istruzioni è scalabile: i processori più piccoli hanno poche istruzioni, quelli maggiori hanno un set più ampio, ma del tutto analogo. Quindi un programma scritto per un chip è spesso facilmente "spostabile" su un' altro chip della stessa famiglia, adeguandolo alle risorse locali, con pochissime modifiche.

In ogni caso, e come è per tutti i compilatori (sono compilatori C, BASIC, ecc), i passi necessari per "programmare" il componente sono essenzialmente tre:

  1. stesura del testo del file sorgente
  2. compilazione attraverso il compilatore Assembler per ottenere il file eseguibile binario
  3. trasferimento di questo file nella memoria programma del chip

Il file sorgente, scritto come un semplice testo ASCII (normalmente identificato come file .asm), viene passato all' Assembler per la compilazione e il file eseguibile (spesso identificato come file .hex) che si è ottenuto sarà utilizzato per la programmazione del chip, attraverso un dispositivo adeguato (programmatore).

Nel caso dei PIC di Microchip, il costruttore offre un Assembler gratuito chiamato MPASM, a sua volta integrato in un ambiente di sviluppo MPLAB. Lo scopo di quest'ultimo è fornire un ambiente uniforme integrato che consenta nel modo più efficace possibile di trattare tutte le azioni necessarie all' interno di una sola finestra generale di lavoro. MPLAB IDE o il più recente MPLAB-X, integra il Macro Assembler MPASM e permette di collegarsi con altri linguaggi, ad esempio vari compilatori C e con le funzioni di debug integrato in circuit (ICD) e con le operazioni di simulazione e programmazione del componente.


 

 

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