Introduzione al linguaggio assembly
del microprocessore 8086
2a parte
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.
La programmazione in linguaggio macchina è stata a lungo l’unica
possibile, all’inizio dell’epoca del calcolo elettronico, prima
dell’introduzione degli assemblatori e dei compilatori.
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 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:
001111010001001000001000
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 assembler o assembly sono stati introdotti proprio per eliminare i
problemi di uso del linguaggio macchina. Le caratteristiche principali dei
linguaggi assembler sono le seguenti:
•
In assembler 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 nome 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.
Un esempio
#include <stdio.h>
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 assembler è 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, richiamando un modulo del sistema operativo
per la presentazione di una stringa sullo schermo.
Nel programma in linguaggio C
i dettagli di questa chiamata
sono nascosti al
programmatore al quale è
sufficiente scrivere l’istruzione
printf .
Spetta al compilatore generare
la chiamata al sistema
operativo, aggiungere alla
stringa i codici di controllo “a
capo” e “ritorno carrello”, ecc.
Nel programma assembler è
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 “$”.
Facciamo qualche valutazione..
La differenza nello spazio occupato in memoria dai due programmi è
evidente quando si passa a compilarli e collegarli.
Le dimensioni in byte dei codici sorgente, oggetto (compilato) e
eseguibile (collegato) dei due programmi sono qui confrontate:
Programma C
Programma Assembler
Sorgente
57 byte
682 byte
Oggetto
578 byte
194 byte
Eseguibile
15 Kbyte
610 byte
La differenza nelle dimensioni del programma sorgente assembler è dovuta al maggior spazio
richiesto per le istruzioni e per i commenti necessari. Il codice compilato è però già più compatto
per il programma assembler. La differenza più rilevante si nota dopo che i programmi sono stati
collegati alle rispettive biblioteche e routine di servizio: il programma in assembler manca quasi
completamente di overhead, che invece caratterizza il programma in C. Il programma scritto in
assembler è più rapido a caricarsi e eseguirsi; entrambi i programmi producono lo stesso
risultato e non sono distinguibili solo sulla base di quest’ultimo.
Concludendo..
Non esistono criteri assoluti per optare per un linguaggio ad alto livello
oppure assembler. Se con l’assembler è 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 assembler sono più difficili e dispendiosi.
La programmazione in assembler 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 assembler.
Aspetto non trascurabile della programmazione assembler è 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 assembler. L’assembler aiuta quindi a comprendere meglio i
meccanismi di funzionamento della macchina.
Scarica

assembler 2 - contiriccardo