Introduzione al linguaggio assemby del microprocessore 8086 1a parte Assemblatori Introduzione al linguaggio assemby del microprocessore 8086 1a parte
…ripartiamo da qui c := a 1 : n istruzioni c := c + 1 1 : 1 mov ax,bx LINGUAGGIO AD ALTO LIVELLO c := a 1 : n c := c + 1 istruzioni LINGUAGGIO ASSEMBLY 1 : 1 mov ax,bx add ax,1 ... LINGUAGGIO MACCHINA 0101011100 0111110100
Definizione di assemblatore Un assemblatore è un programma che legge un file di testo che si compone di codici mnemonici, cioè di comandi espressi come parole abbreviate in lingua inglese e li traduce in sequenze binarie di 0 e 1, generando il codice macchina del microprocessore. MOV …. ADD….. JMP….. DIV….. MOV CX,DX L’insieme dei codici mnemonici e delle convenzioni sintattiche di un assembler costituisce un vero e proprio linguaggio di programmazione, il linguaggio assembly.
Una istruzione assembly una istruzione macchina La rappresentazione delle istruzioni nella codifica mnemonica permette al programmatore di scrivere un codice sorgente sufficientemente leggibile, mentre la corrispondenza biunivoca esistente tra i codici mnemonici e il codice macchina permette all’assembler di realizzare una traduzione efficiente, accurata e particolarmente rapida. mov ax,bx 0101011100 Anche i compilatori partono da codice sorgente e restituiscono codice macchina però differiscono dagli assembler perché si basano su una corrispondenza non più biunivoca. 0101111100 a:=a+b 0111111101 1101000100
Linguaggi ad alto e basso livello Un linguaggio ad alto livello garantisce al programmatore una indipendenza quasi completa dall’architettura interna della macchina, a differenza del linguaggio assembly, le cui istruzioni contengono quasi sempre riferimenti espliciti ai registri, alle locazioni di memoria, alle porte di ingresso e uscita del calcolatore. In definitiva, mentre un linguaggio ad alto livello può avere caratteristiche di ‘portabilità’ da una macchina ad un'altra diversa che usa lo stesso linguaggio, il linguaggio assembly è ‘specializzato’ per un tipo o una famiglia di tipi di macchina perché ne usa direttamente le risorse specifiche.
Utilizzo dei linguaggi a basso livello Un particolare campo di applicazioni da sviluppare in assembly è quello relativo allo sviluppo di routine per la gestione o il colloquio con le periferiche (drivers). Tale compito è molto delicato e richiede attenzione a tutti i dettagli, poiché una periferica di per sè impone dei tempi di azione lunghi rispetto ai tempi di calcolo e il relativo software di gestione è piuttosto specifico rispetto alla periferica stessa.
Il linguaggio assembly per il processore 8086 In virtù della specializzazione che caratterizza l’assembler è necessario conoscere la macchina target per cui deve essere prodotto il codice macchina, in particolare il processore di cui si deve adottare il set di istruzioni. Si tratta di un processore con architettura a 16 bit ed è piuttosto datato, è nato infatti nel 1978. Da allora ad oggi ci sono state grandissime evoluzioni nello sviluppo dei microprocessori e nella stessa casa intel si è susseguita una famiglia di microprocessori che ha per capostipite proprio l’8086. Intel 8086
L’evoluzione dei processori i8086(16bit) i80286(16bit) i80386(32bit) i80486 Pentium, II, III e IV. Questi processori, nell’ordine, sono ciascuno l’evoluzione del precedente e la base per il successivo anche se quest’ultimo introduce degli stravolgimenti nell’architettura. L’intel ha adottato una politica di compatibilità all’indietro. Un programma funzionante su un dato processore doveva funzionare, in un modo o nell’altro, con i processori che sarebbero successivamente stati sviluppati. Ciò ha comportato delle notevoli complicazioni ma ha degli indubbi vantaggi, intanto il software (che ha un costo) era riciclabile con l’aggiornamento della macchina.
Qualche caratteristica .. L’8086 può indirizzare 220 byte, numerati in maniera sequenziale a partire da 0. Le istruzioni possono operare sia su byte(8bit) che su parole di 16bit. Con 220 byte di memoria l’8086 ha bisogno di 20 bit per indirizzare la memoria. Poiché sia i registri che tutti gli altri elementi usano parole di 16bit i numeri di 20 bit non sono convenienti. Per risolvere questo problema i progettisti hanno introdotto quattro registri di segmento da 16 bit che possono puntare esclusivamente ad indirizzi multipli di 16 byte, ciò equivale ad avere un indirizzo di 20 bit in cui i 4 bit meno significativi sono tenuti sempre a 0. Dunque ciascun registro contiene un indirizzo di memoria che punta alla base di un segmento (porzione continua di memoria) di 64K(216). Ciò significa che in ogni momento si può accedere al massimo a 64K di memoria senza cambiare il registro di segmento.
I segmenti segmento reg. di segmento utilizzo code CS contiene le istruzioni da eseguire data DS contiene le variabili del programma stack SS usato per tutte le operazioni di stack extra ES usato per immagazzinamento dati 64 K RAM
Modalità di indirizzamento L’8086 accede agli operandi delle istruzioni in diversi modi. Gli operandi possono essere contenuti nei registri, nelle istruzioni stesse, nella memoria oppure acquisiti dalle porte di I/O. Gli operandi indirizzi di memoria possono essere calcolati in diversi modi. INDIRIZZAMENTO IMMEDIATO INDIRIZZAMENTO A REGISTRO INDIRIZZAMENTO DIRETTO INDIRIZZAMENTO INDIRETTO CON REGISTRO INDIRIZZAMENTO CON REGISTRO DI BASE INDIRIZZAMENTO CON REGISTRO INDICE INDIRIZZAMENTO CON REGISTRI BASE E INDICE
INDIRIZZAMENTO IMMEDIATO Gli operandi immediati sono dati costanti contenuti in un istruzione. Possono essere lunghi 8 o 16 bit. Sono accessibili rapidamente perché disponibili direttamente dall’istruzione. MOV AH,00 MOV AL,04 MOV AX,0FFFFh MOV AX,302 MOV AX,23o MOV AL,-40 MOV DL,’w’ 302 AX
INDIRIZZAMENTO A REGISTRO Il valore dell’operando sorgente è contenuto in uno dei registri interni dell’8086. La sua dimensione può essere 8 o 16 bit. AL AB MOV DL,AL MOV DS,AX DL
INDIRIZZAMENTO INDIRETTO CON REGISTRO L’indirizzo dell’operando sorgente è contenuto in uno dei registri interni dell’8086. RAM BX 96000 MOV AX,[ BX ] 96000 AX FF