
L'Assembly è il linguaggio più difficile che esista e, a ragione, i programmatori hanno un po' di timore nell'impararlo. Per la codifica di semplici azioni occorre scrivere una notevole quantità di codice. Ma la velocità è il suo punto di forza, in quanto la filosofia operativa è vicinissima a quella del linguaggio macchina. Vediamo come Jasmin ci aiuta a comprendere tale linguaggio di programmazione.
Introduzione
Iniziamo con una distinzione di termini: per Assembly si intende propriamente il linguaggio di programmazione, mentre Assembler è un programma che traduce tale linguaggio in una forma comprensibile al calcolatore.
La funzione di Jasmin è quella di essere un semplice assembler e la sua sintassi è estremamente chiara e pulita. Al seguente link un approfondimento sull'assembler dal titolo "Come ottimizzare il codice assembler dei PICmicro". L'ideale per imparare "facilmente" tale linguaggio di programmazione. Il suo scopo è anche quello di creare funzionalità per la Java Virtual Machine, convertendo il sorgente testuale in una classe di Java sottoforma di file binario, ma l'articolo si focalizza esclusivamente sui primi rudimenti dell'Assembly. Può essere scaricato all'indirizzo http://wwwi10.lrr.in.tum.de/~jasmin/
Consiste in un unico file con estensione "jar" che può essere eseguito se si ha installato Java sulla propria macchina. Al momento della scrittura del presente articolo, il nome di tale file eseguibile è jasmin-1.5.11.jar. E' sufficiente cliccarlo due volte per poter lanciare immediatamente l'ambiente operativo, come visibile in figura 1.
Come si nota, si tratta di un interprete, quindi niente compilazioni ne' generazione di eseguibili. Tutto il lavoro si sviluppa in modo estremamente leggero e pratico.
Il nostro primo programma
Ovviamente chi si cimenta a scrivere un listato in Assembly deve cominciare a familiarizzare un po' con le sue istruzioni e, soprattutto, con i registri a disposizione, ossia particolari celle di memoria che possono contenere determinati valori (proprio come le variabili). Un approfondimento sui registri lo si trova al seguente articolo dal titolo "Come scambiare un registro con W in assembler".
Scegliendo la voce "New" del menù "File" si accede all'editor vero e proprio, raffigurato in figura 2. Esso è composto dal visualizzatore dei registri, dei flags, della memoria e, ovviamente, dall'editor testuale.
Nell'architettura a 32 bit, la memoria utilizza particolari registri di tale dimensione (vedi figura 3). Si tratta di speciali (e velocissime) celle (EAX, EBX, ECX e EDX) che possono contenere valori compresi tra 0 e 2^32-1 (ossia 4.294.967.295). Ogni registro può essere anche utilizzato come registri a 16 bit (AX, BX, CX e DX) e, ulteriormente, a 8 bit (AH, AL, BH, BL, CH, CL, DH, DL). In altre parole, è inutile utilizzare un recipiente di mille litri se dobbiamo versare solamente 10 litri d'acqua.
Scriviamo sull'editor il seguente sorgente in Assembly.
MOV AX,100 ADD AX,33 ADD AX,22 ADD AX,10
Il listato è semplicissimo. Esso inizializza il registro AX al valore di 100, poi gli aggiunge 33, quindi aggiunge 22 e infine aggiunge 10. Il valore finale è, dunque, 165. Per l'esecuzione del programma è sufficiente premere il tasto con la freccia verde, posto sulla barra degli strumenti, in alto.
Come facciamo a verificare la correttezza dei risultati? E' sufficiente dare un'occhiata alla finestra dei registri, posta sulla sinistra della videata, come mostrato in figura 4. Si possono visualizzare i valori in formato binario, decimale ed esadecimale.
E' possibile anche eseguire il sorgente linea per linea (step by step) premendo il tasto con la freccia verde e la stanghetta gialla, posto a sinistra del tasto con la sola freccia verde (Run). Si possono osservare, in tal modo, le evoluzioni dei registri, a ogni istruzione eseguita.
La metodologia utilizzata nell'esempio è definita indirizzamento immediato, nella quale l'operando è una costante.
Swap di due registri
Il prossimo semplice esempio propone il classico problema dello scambio del contenuto di due registri o di due variabili. Esistono, a riguardo, diversi metodi. Il più semplice prevede l'appoggio provvisorio del valore su un terzo registro di comodo, secondo il seguente listato. Dopo l'esecuzione si può verificare che il contenuto dei due registri è stato effettivamente scambiato.
;----Inizializza i due registri EAX a 234 e EBX a 155--- MOV EAX,234 MOV EBX,155 ;------Effettua lo scambio con il terzo registro di comodo--- MOV ECX,EAX MOV EAX,EBX MOV EBX,ECX MOV ECX,0
Un altro modo per poter "swappare" due registri è quello di usare l'istruzione XCHG. Essa permette di rendere molto veloci i programmi, dal momento che utilizza pochi cicli macchina per la sua esecuzione e non è richiesto l'utilizzo del terzo registro di comodo.
;----Inizializza i due registri EAX a 234 e EBX a 155--- MOV EAX,234 MOV EBX,155 ;------Effettua lo scambio con l'istruzione XCHG--- XCHG EAX,EBX
Ancora un ulteriore metodo permette di scambiare i due valori, utilizzando l'istruzione logica XOR. Il listato è il seguente.
;----Inizializza i due registri EAX a 234 e EBX a 155--- MOV EAX,234 MOV EBX,155 ;------Effettua lo scambio con l'istruzione XOR--- XOR EAX,EBX XOR EBX,EAX XOR EAX,EBX
E' possibile osservare l'effetto degli scambi in figura 5.
Display a 7 segmenti
Jasmin è dotato di un comodo display, completamente personalizzabile, con cui visualizzare le cifre numeriche. La figura 6 mostra il display in questione. Il seguente listato provvede all'indirizzamento delle singole cifre.
mov EBX,0 mov [EBX],7 mov EBX,1 mov [EBX],6 mov EBX,2 mov [EBX],63 mov EBX,3 mov [EBX],91
Altri tools
Jasmin mette a disposizione altri tools molto utili. Come si evince dalla figura 7, essi sono uno StripLight, una finestra di console e un display grafico, tutti con caratteristiche impostabili dall'utente. Al seguente link un approndimento sul controllo dei display OLED dal titolo "Colleghiamo un display OLED ad ESPertino".
Conclusioni
Lo spazio è tiranno, ci sarebbero tante cose da aggiungere, ma siamo sicuri che gli appassionati programmatori sapranno ottenere tanto aiuto e beneficio da questo ottimo programma. E Voi avete avuto esperienza con questo linguaggio? Vi sembra interessante?

Scrivere un programma in Assembly, anche semplice, è un’operazione molto pesante e faticosa, ma a me personalmente crea un po’ di dipendenza….
semplicemente fantastico!un ricordo lontano ai tempi della scuola a fare codice assembly per Z80.
grazie per la dritta,purtroppo il tempo libero è tiranno, ma spero di riuscire a provarlo!
E’ anche relativamente semplice trasportare un programma da Assembly a linguaggio macchina. Una volta ho pure realizzato un semplice assemblatore per la CPU 68000.
Ogni istruzione assembly, infatti, corrisponde a un preciso opcode, ovviamente reperito sul datasheet della stessa CPU.
Ad esempio, il seguente programma Assembly:
mov ax,5
mov bx,10
add cx,ax
add cx,bx
diventerebbe, in linguaggio macchina:
66 b8 05 00
66 bb 0a 00
66 01 c1
66 01 d9
e in RAW:
66B8050066BB0A006601C16601D9
Non è tanto difficile, dai……
Grande Giovanni, anche a me riporta indietro di 20 (e piu’) anni quando scrivevo il primo codice assembly per il mio MSX buonanima, ormai. Oppure a scuola, a scrivere un programma per il calcolo di numeri primi sul nanocomputer con lo Z80.
Ho lavorato 1 po’ per divertimento sul codice macchina per la PS3, con il set PowerPC.
Sicuramente ci sono esigenze anche professionali a volte per usare l’Assembly, vedi routine di interrupt molto spinte e ritagliate al bit su quello che devono fare. Ricordo anche una volta di aver scritto codice assembly per una routine un po’ particolare di un watch dog.
CIao Riccardo. Grazie.
E poi, l’assembly aiuta anche per la programmazione dei microcontrollori. Non dimentichiamo che qualsiasi programma, in qualsiasi linguaggio, alla fine è sempre convertito in codice binario per la CPU/MCU. Inoltre, solitamente, mentre lo spazio occupato da un EXE generato con i compilatori occupa centinaia o migliaya di bytes, un eseguibile in Assembly occupa poch decine di bytes.
Hai ragione, infatti conosco colleghi che, in certi casi, preferiscono ritoccare il codice generato o bypassare direttamente il compilatore in certe zone del codice dove vogliono che sia piu’ performante. Ad esempio, molte funzioni possono essere dichiarate con attributo naked, in modo che lo stack non gestica la solita push e pop dei parametri (con diverse calling conventions), ma lasciando allo sviluppatore la possibilita’ di passare i parametri in modo performante, senza usare lo stack. E’ un uso chiaramente estremo, e che puo’ far impazzire in fase di compilazione.
Spesso chi sviluppa per desktop, dimentica le dimensioni risicate di chi svulippa su embedded. Stack ridotto e quant’altro. Quasi mai la presenza di runtime per fare anche solo la piu’ semplice delle printf. Ecco perche’ mi piace lavorare sia per desktop, sia per embedded: per il secondo mi aiuta a tener sempre a mente che le risorse non sono illimitate. Spesso tenendo i trucchi che usano nell’embedded e portarndoli nel mondo desktop, si ottengono codici molto piu’ performanti e rispettosi delle risorse (e quindi intriscamente scalabili).
Anche a me riporta indietro nel tempo a quando scrivevo codice per Z80 (con la famosa valigetta FOX, se la ricorda qualcuno?) ma mi fa pensare anche ai primi due anni di lavoro in cui ho sviluppato esclusivamente codice assembly per microcontrollori PIC.
Forse per iniziare a programmare in assembly è più agevole adottare un’architettura RISC come quella dei PIC della Mcirochip: il set di istruzioni è limitato e quindi è più facile ricordarsele tutte, anche se poi forse lo sforzo mentale per la costruzione del software è maggiore.
Sara’ per un effetto amarcord, ma per me lo Z80 e’ ancora il re dei micro, sicuramente almeno dal punto di vista didattico. Ricordo ancora la gestione del daisy chain, il PIO, il SIO e compagnia bella.
Ho programmato in Assebler nel lontano 1983. Belle soddisfazioni le ebbi con un programmino per la gestine degli input da tastiera. Controllava la lunghezza, la tipologia della stringa, visuallizzava con dei caratteri asci lo spazio, gestiva l’editing della stringa. Preistoria… 🙂
… e allora fomentiamo un po’ di “guerra di religione”, viva il 6502, viva l’atari 8bit… 😀 😀 Vado a riesumare l’800XL….
vedo che ero in buona compagnia in casa Zilog 🙂
peccato che io ci ho “smanettato” un pò soltanto a scuola…poi per cause lavorative ho preso altre strade e “disperso” il mio bagaglio scolastico elettronico…:-(
anche se, grazie a arduino e compagnia bella un pò sto cercando di rispolverare la “mia elettronica”…almeno per hobby…
Concordo con Gabriele, lo Z80 e il 6502 divide il mondo in 2, un po’ come
gli Stones e i Fab4 o i Deep e i Led (per me lo Z80 e’ come gli Stones e i Deep 🙂 ).
Per tutti gli Z80 addict segnalo questo bel libro, che illustra come ricostruirsi
il Nano computer Z80-based che molti di noi usarono a scuola:
http://www.sanditlibri.it/z80-microcomputer-didattico.html
Enjoy it.
Giovanni, mi rivolgo a te per la tua grande esperienza di divulgatore e di didatta.
Ci sono moltissimi progetti homebrew con su l’Z80, alcuni anche col CP/M:
http://searle.hostei.com/grant/cpm/index.html
Mi stavo chiedendo quanto potrebbe essere attuale e interessante creare delle nuove schede Z80-based che supportino l’architettura Arduino…questo unirebbe l’utile col dilettevole e inserirebbe una nuova dose di retro e vintage che non guasta mai.
Chiaramente le schede risultanti non sarebbero piccole come la Uno, ma magari si potrebbe trovare una nicchia per gli smanettoni amanti del vintage.
Ditemi le vostre opinioni su questo, grazie
Ciao. Grazie.
Ci sono processori che saranno sempre immortali, come quelli da te citati. Si pensi anche che nelle discariche tecnologiche si trovano tantissime macchine obsolete, ancora funzionanti, che gli hobbisti possono prendere, cannibalizzare, pulire e usare.
Molti progetti possono essere benissimo realizzati con essi, in quanto la documentazione e i datasheet sono reperibilissimi in rete.
Magari non vedremo nel nuovo mercato delle schede Z80-based & C, ma sicuramente vedremo progetti e circuiti con tali processori.
Grazie Giovanni. Certamente lo Z80 e’ molto limitato rispetto al 328.
Sgrufolando in rete si vede cmq che l’abbinata Arduino – Z80 e’ gia’ venuta in mente a qualcun altro.
Qui un hacker matto ha usato l’arduino come debugger esterno di uno Z80. Con esso lo Z80 vede l’arduino come la sua RAM, e’ l’arduino puo’ dumpare la RAM passo passo, piu’ altre interessantissime funzionalità’:
http://baltazarstudios.com/arduino-zilog-z80/
Qui invece, altri hanno avuto la mia stessa tentazione, e alla fine anch’essi usano l’arduino per far girare uno Z80, ottenendo una simbiosi veramente interessante:
https://forum.arduino.cc/index.php?topic=60739.0
Qui ce n’e’ un altro simile:
http://bedroomcoders.co.uk/using-an-arduino-to-run-a-z80/
e ce ne sono molti altri, semplicemente gongolando Z80 + Arduino.
Questa cosa e’ sicuramente interessante. chissà’ che non ci mi metta dietro e ne venga fuori un articolo.
Ottimo. Grazie per gli interessanti contributi.!!!
“Magari non vedremo nel nuovo mercato delle schede Z80-based & C”. Sembrerebbe che gia’ ci siano schede Z80 based invece. Una delle piu’ interessanti e’ un emulazione della Raspberry:
https://sites.google.com/site/zberrysbc/
https://hackaday.com/2017/06/03/z80-based-raspberry-pi-look-alike/