Introduzione al linguaggio assembly
del microprocessore 8086
Il linguaggio macchina
Il linguaggio naturale di un microprocessore
è il linguaggio macchina.
Nel linguaggio macchina non esistono
riferimenti astratti o simbolici e tutte le
operazioni sono eseguite direttamente sui
registri o in locazioni assolute di memoria.
Il linguaggio macchina non è altro che
l’insieme delle istruzioni definite per un
particolare processore.
Ogni istruzione è identificata dal suo
codice, di solito riportato in binario
o in esadecimale.
Il linguaggio macchina
Il linguaggio macchina si compone di istruzioni alle quali fanno
immediatamente seguito i relativi operandi.
Un esempio di linguaggio macchina per il processore Intel 8086 è il
seguente codice per il confronto del contenuto dell’accumulatore
AX con la costante 812h:
0011 1101 0001 0010 0000 1000
Per facilitare la descrizione delle istruzioni e degli operandi, si fa uso della
notazione esadecimale in alternativa a quella binaria.
L’esempio precedente assume in esadecimale questo aspetto:
3D1208
Con debug
Con l’uso della calcolatrice scientifica potremo verificare
che il valore binario corrispondente è proprio:
001111010001001000001000
Difficile?
Resta però difficile lavorare anche con questa notazione.
Il codice rimane indistinguibile dagli operandi e solo a fatica,
con l’aiuto di una tabella di conversione si riconosce in 3D
l’istruzione di confronto.
Un certo impegno è anche necessario per la traduzione di 08
12 in 12 08.
Infatti viene memorizzato prima il byte della parte bassa e
poi il byte della parte alta del numero considerato a 16 bit.
Molto !!!
Il codice binario (o la sua
rappresentazione
equivalente esadecimale)
usato nel linguaggio
macchina è molto
scomodo; per l’uomo è
molto più facile
raffigurare e lavorare con
simboli e messaggi
piuttosto che con cifre.
Una soluzione:
I linguaggi assembly in ambienti assembler sono stati introdotti proprio per
eliminare i problemi di uso del linguaggio macchina.
Le caratteristiche principali dei linguaggi assembly sono le seguenti:
•
In assembly le istruzioni non sono identificate da codici astratti ma da
simboli letterali con significato mnemonico.
ADD significa ad esempio addizione
•
•
Alle variabili viene fatto riferimento per valore e non per locazione
assoluta di memoria (indirizzo)
E’ possibile definire istruzioni macro assembler, composte a loro volta da
altre istruzioni, e richiamarle nel programma.
ebp punta alla base dello STACK
Esempio: alternativa
In Linguaggio
Assembly
In Linguaggio
C like
(commenti in
IDE jasmin)
Esempio: scrittura a video
….. main(….) {
System.out.print(“ciao \n”);
}
In Linguaggio
JAVA
….. main(….) {
printf(“ciao \n”);
}
In Linguaggio
C
In Linguaggio
Assembly
DSEG SEGMENT
;segmento dati
Outstr db “ciao”,13,10,”$”
DSEG ENDS
SSEG SEGMENT stack
;segmento catasta
dw
32 dup (?)
SSEG ENDS
CSEG SEGMENT
;segmento codice
assume cs:cseg, ds:dseg, ss:sseg
start:
mov bx,dseg
mov ds,bx
;DS=DSEG via bx
mov dx,offset outstr ;puntatore a “ciao”
mov ah,09h
;uscita su schermo
int 21h
;richiamo MS-DOS
mov ah,4Ch
;termine programma
int 21h
;richiamo MS-DOS
CSEG ENDS
END start
; termine programma
; inizio a start
Complicato?
Il primo programma è molto più compatto
del secondo, oltre che più facile da leggere
e capire.
Il programma in assembly è a prima vista
certamente molto più complicato ed è
necessario un certo tempo per analizzarne e
comprenderne le funzioni, che in questo
caso sono comunque molto semplici.
Entrambi i programmi funzionano secondo lo stesso
principio, chiedendo al sistema operativo di
presentare una stringa sullo schermo.
Dettagli nascosti o espliciti
Nel programma in linguaggio
JAVA i dettagli di questa
chiamata sono nascosti al
programmatore al quale è
sufficiente scrivere l’istruzione
Systm.out.print
Spetta al compilatore generare
la chiamata al sistema
operativo, aggiungere alla
stringa i codici di controllo “a
capo” e “ritorno carrello”, ecc.
Nel programma in assembly è
necessario tenere esplicitamente
conto di tutti questi aspetti.
Le chiamate al sistema operativo
hanno luogo per mezzo
dell’istruzione INT 21h
La stringa di uscita è definita
nell’area dati; con essa devono
essere indicati esplicitamente i
codici di “a capo” (ASCII 10) ,
“ritorno carrello” (ASCII 13) e
termine stringa “$”.
La differenza di spazio occupato in memoria dai due programmi è
evidente quando si passa a compilarli ed eventualmente collegarli.
Facciamo qualche valutazione..
Le dimensioni in byte dei codici sorgente, oggetto (compilato) e
eseguibile (collegato) dei programmi sono qui confrontate:
Programma in JAVA
Programma in C
Programma in Assembly
Sorgente
1000 byte
57 byte
682 byte
Oggetto
1000 byte
578 byte
194 byte
Al volo
15 Kbyte
610 byte
Eseguibile
La differenza nelle dimensioni del programma sorgente assembly rispetto al C è dovuta al
maggior spazio richiesto per le istruzioni e per i commenti necessari. Il codice compilato è però
già più compatto per il programma assembly. La differenza più rilevante si nota dopo che i
programmi sono stati collegati alle rispettive biblioteche e routine di servizio: il programma in
assembly manca quasi completamente di overhead, che invece caratterizza il programma in C.
Il programma scritto in assembly è più rapido a caricarsi ed eseguirsi; tutti i programmi
producono lo stesso risultato e non sono distinguibili solo sulla base di quest’ultimo.
Confrontando ...
Non esistono criteri assoluti per optare per un linguaggio ad alto livello
oppure assembly. Se con l’assembly è possibile scrivere programmi più
efficienti, è anche vero che la loro stesura prende molto più tempo rispetto
allo scrivere programmi in un linguaggio avanzato. Anche la documentazione
e la manutenzione di programmi assembly sono più difficili e dispendiose.
La programmazione in assembly resta comunque di attualità in tutti i casi
dove con la programmazione ad alto livello si raggiungono i limiti di capacità
di memoria o velocità di esecuzione di una macchina.
Alcune funzioni, in particolare quelle che agiscono direttamente sulle
risorse del sistema, non sono realizzabili se non in assembly.
Aspetto non trascurabile della programmazione assembly è il suo
carattere didattico. Indipendentemente dal numero e tipo di prodotti
software installati in un sistema, il processore, almeno con le architetture
attuali, opera su istruzioni di macchina assimilabili a quelle di un
programma assembly. L’assembly aiuta quindi a comprendere meglio i
meccanismi di funzionamento della macchina.
… concludendo
… nell'evoluzione vs linguaggi di scripting