Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
1
IL LINGUAGGIO ASSEMBLY
8086
2
Perché il Linguaggio Assembly 8086
Programmare un processore, quando questi nacquero, consisteva nel riempire direttamente la memoria con le istruzioni in linguaggio macchina (codici operativi) e con i dati. Con l’aumento della complessità dei problemi lo sforzo diventava proibitivo. Un primo passo verso la semplificazione del compito di un programmatore è la nascita del linguaggio Assembly. L’idea alla base è quella di sollevare il programmatore dal dover lavorare direttamente con sequenze di bit dandogli la possibilità di: identificare ciascun comando in linguaggio macchina (codice operativo) con una parola chiave più facile da ricordare (codice mnemonico). indirizzare le locazioni di memoria ed i registri attraverso degli identificatori testuali, anziché attraverso i loro indirizzi binari.
3
Il linguaggio assembly
Assembly: è un linguaggio di programmazione a basso livello è più vicino al linguaggio macchina vero e proprio. Infatti, esiste una corrispondenza pressoché biunivoca tra gli mnemonici del linguaggio assembly ed i corrispondenti codici macchina corrispondenti ai bitfields (campi di bit) che compongono le istruzioni direttamente eseguibili dal dispositivo elettronico (in genere una CPU) che si sta programmando. Assembler: è un programma compilatore che si occupa di tradurre in linguaggio macchina (ossia in una serie di bit 0 e 1, che costituiscono l'unico modo per comunicare con dispositivi elettronici), una serie di comandi scritti in linguaggio Assembly. Oltre a questo compito base, un Assembler si occupa spesso di ausiliare il programmatore, ad esempio consentendo l'utilizzo nel codice sorgente del programma di nomi mnemonici al posto di indirizzi esadecimali che costituiscono l'esatta collocazione di una variabile o di una porzione di programma nella memoria centrale del computer.
4
Conoscenze basi per programmare in assembly
La struttura più semplice di un computer può essere così schematizzata: La CPU, è il principale elemento per valutare le prestazioni di un computer. È composta da l’ALU (Arithmetic/Logic Unit), dall’UC (Unit Control) e dai registri, piccole memorie che contengono i dati da utilizzare nelle operazioni matematico/logiche o di controllo. La memoria in cui i programmi sono caricati per poi essere mandati in esecuzione. Il SYSTEM BUS connette le varie componenti del computer.
5
L’interno della CPU Il processore 8086 ha una serie di registri (14) a 16 bit, è possibile distinguere tra: registri accumulatori, utilizzabili indifferentemente come registri a 16 bit (word) o 8 bit: AX – registro accumulatore (diviso in AH / AL). BX – registro base, contiene l’indirizzo di base di una tabella o di un vettore (diviso in BH / BL). CX – registro contatore usato nelle operazioni fra stringhe e nelle iterazioni come registro contatore a sedici bit (diviso in CH / CL). DX – registro dati (diviso in DH / DL). Questi registri sono usati normalmente per i seguenti scopi: operazioni aritmetiche ad otto e a sedici bit; operazioni logiche; trasferimento dei dati.
6
L’interno della CPU Registri indice, contengono l’indirizzo per raggiungere le locazioni di memoria all’interno del segmento dati: SI - registro indice sorgente. DI – registro indice destinazione. Registri puntatore, (o Index o Offset) sono generalmente utilizzati come puntatori a dati in memoria (contengono cioè gli indirizzi di memoria). Si dividono in: BP – registro puntatore alla base dello stack (Base Pointer). SP – registro puntatore alla fine dello stack (Stack Pointer). IP – registro puntatore delle istruzioni: lavora in parallelo al segmento CS e punta all’istruzione che è in esecuzione. Lo stack è un’area di memoria della CPU in cui i dati vengono estratti col metodo FIFO (First In First Out)
7
L’interno della CPU Registri di segmento
La memoria della CPU è suddivisa in paragrafi, costituiti da 16 byte contigui e da segmenti costituiti ciascuno da 64k byte. Ogni segmento inizia in corrispondenza di un paragrafo, ossia ad un indirizzo multiplo di 16. CS – segmento del codice: punta all’indirizzo di testa del segmento contenente il codice del programma. DS – segmento dei dati: punta all’indirizzo di testa del segmento contenente i dati usati dal programma. ES – segmento extra, ovvero segmento dati aggiuntivo. SS – segmento dello stack: punta al segmento contenente lo stack.
8
L’interno della CPU Registro dei flag o di stato
Si tratta di un registro a 16 bit, chiamato anche registro di stato, contenente 9 bit utilizzati per indicare differenti condizioni durante l’esecuzione del programma. I bit 0,2,4,6,7,11, contengono flag di stato, che indicano risultati di operazioni di programma. I bit 8,9,10, contengono flag di controllo. Gli altri non vengono utilizzati.
9
Sintassi Linguaggio Assembly
Il processore 8086 è un processore a due indirizzi, la sintassi generale è la seguente: ISTRUZIONE DESTINAZIONE, SORGENTE dove: Istruzione è un codice operativo; Destinazione è l’operando che riceve il risultato; Sorgente è l’operando che fornisce un valore al microprocessore. La destinazione può essere un registro o una variabile. La sorgente può essere un registro, una variabile, una costante. Alcuni esempi: MOV ax,bx ADD bx,ax MOV variabile,ax Alcuni esempi errati: MOV al,bx (dimensioni diverse) SUB var1,var2 (due variabili) ADD 5,ax (la dest. non può essere una costante)
10
Indirizzamento dei Dati del Processore 8086
Gli indirizzamenti possibili sono: Indirizzamento immediato, il sorgente è una costante: ADD AL,8 (cifra decimale). MOV AL,0FH (cifra esadecimale)[B: binario/O: ottale]. Indirizzamento con registro, gli operandi sono dei registri: SUB AX,BX ADD DL,AL CMP AX,DX Indirizzamento diretto, uno dei due operandi è una variabile: ADD AX,variabile MOV variabile,AL MOV numero,5
11
Le direttive fondamentali di Assembly
TITLE nomeprogramma - direttiva per dare il nome al programma. .MODEL tipo - direttiva modelli di memoria processore 8086: TYNY: unico segmento per i dati e per il codice. SMALL: un segmento per il codice ed uno per i dati. COMPACT: un segmento per il codice e più segmento per i dati. MEDIUM: un segmento per i dati e più segmento per il codice. LARGE: più segmenti per i dati e per la memoria. .STACK direttiva che dichiara il segmento STACK di 1024 byte.
12
Le direttive fondamentali di Assembly
.DATA - Direttiva per dichiarare i dati. Definizione di Costanti (EQU): La costante è un nome a cui viene assegnato un valore, Il valore di una costante non può essere modificato dal programma in esecuzione. Durante la traduzione, l’assemblatore sostituisce ogni occorrenza del nome di una costante con il valore corrispondente. Esempio: NUM EQU 10h - VAL EQU 42 Definizione di variabili: Una variabile è un contenitore di dati, destinata a contenere valori, suscettibili di modifica nel corso dell'esecuzione di un programma. Una variabile è caratterizzata da un nome, il tipo e un valore iniziale. Sintassi: <nome> <tipo> <val_iniziale> <nome> è un identificatore <tipo> indica la dimensione e può essere: DB: Byte (8 bit) DW: Word (16 bit) <val_iniziale> è il valore di inizializzazione e può essere numerico, un carattere o una stringa. Esempio: NUM DB 05h - DATO DW ?
13
Le direttive fondamentali di Assembly
.DATA - Direttiva per dichiarare i dati. Dichiarazione di una stringa. - Sintassi: <nome> <tipo> <" stringa da visualizzare $"> <nome> è un identificatore <tipo> indica la dimensione: DB: Byte (8 bit) <"messaggio da visualizzare $"> stringa da visualizzare a video racchiusa tra i doppi apici (") e chiusa con il simbolo dollaro ($) Esempio: MESSAGGIO1 DB "Inserisci un carattere $" FRASE_1 DB " Buongiorno e benvenuto $"
14
Le direttive fondamentali di Assembly
.DATA - Direttiva per dichiarare i dati. Le variabili (array) sono sequenze di dati di tipo omogeneo: vettori numerici (1,2,5,3). stringhe di caratteri (“prova”). Dichiarazione di un array Sintassi: <nome> <tipo> <sequenza valori o caratteri> Es: VET DB 1, 4, 6, 16, 3, 0 - array di 6 byte; – VET1 DB ‘H’,’e’,’l’,’l’,’o’ - array di caratteri; A DB 5 DUP(9) - come c DB 9,9,9,9,9; B DW 10 DUP(?) - array di 10 word non inizializzate. Uso delle variabili array Per leggere/scrivere il contenuto di un elemento: MOV <Registro>, <Variabile>[indice] - MOV <Variabile>[indice], <Registro> Esempio: MOV AL, a[3] ;copia in AL l’elemento dell’array a di indice 3. E’ possibile usare i registri BX, SI, DI, BP per contenere l’indice: MOV SI, 3 MOV AL, a[SI] - copia in AL l’elemento dell’array a di indice 3.
15
Le direttive fondamentali di Assembly
.CODE - direttiva che dichiara l’inizio del segmento Codice. .STARTUP - direttiva che segnala il punto di partenza della funzione principale. .EXIT - direttiva che segnala il punto di conclusione della funzione principale. END - direttiva che segnala il punto di conclusione di un modulo di programma.
16
Set istruzione 8086
17
Vediamo alcune istruzioni fondamentali
Istruzione di trasferimento: MOV Sintassi: MOV destinazione, sorgente es.: MOV AL , AH o MOV AL , variabile o MOV variabile , AL L’istruzione MOV sposta/copia il contenuto di sorgente in destinazione. Istruzione INC Sintassi: INC operando es.: INC VAR1 INC BX L’istruzione INC incrementa di 1 il valore del suo operando. Istruzione DEC Sintassi: DEC operando es.: DEC NUM DEC AH L’istruzione DEC decrementa di 1 il valore del suo operando. Istruzione NEG Sintassi: NEG operando es.: NEG BX NEG AL L’istruzione NEG cambia segno al suo operando (eseguendo il complemento a 2).
18
Le operazioni aritmetiche
ADDIZIONE: l’istruzione da utilizzare è: ADD Sintassi: ADD destinazione , sorgente es.: ADD AL , AH o ADD AL , variabile o ADD variabile , AL L’istruzione esegue l’addizione, tra la destinazione (il contenuto all’indirizzo o alla variabile) e la sorgente (il contenuto dell’indirizzo o la variabile), il risultato va nella destinazione. SOTTRAZIONE: l’istruzione da utilizzare è: SUB Sintassi: SUB destinazione , sorgente es.: SUB AL , AH o SUB AL , variabile o SUB variabile , AL L’istruzione esegue la sottrazione, tra la destinazione (il contenuto all’indirizzo o alla variabile) e la sorgente (il contenuto dell’indirizzo o la variabile), il risultato va nella destinazione.
19
Le operazioni aritmetiche
MOLTIPLICAZIONE: l’istruzione da utilizzare è: MUL Sintassi: MUL sorgente es.: MUL AH o MUL variabile (8bit) - MUL AX o MUL variabile(16bit). Per eseguire l’istruzione della moltiplicazione bisogna che un valore sia precedentemente caricato o sia già presente nel registro AL (se a 8bit) oppure in AX (se a 16bit). Il risultato va ad occupare il registro AX (se si tratta di valori a 8 bit). AX = AL * sorgente (il risultato è a 16bit). Mentre va ad occupare i registri DX:AX (se si tratta si valori a 16bit) DX:AX = AX * sorgente (il risultato è 32 bit, ovviamente e su 2 registri DX e AX) (in DX ci va la parte alta mentre in AX la parte bassa)
20
Le operazioni aritmetiche
DIVISIONE: l’istruzione da utilizzare è: DIV Sintassi: DIV divisore es.: DIV BH o DIV variabile(8bit) - DIV BX o DIV variabile(16bit) Per eseguire l’istruzione della divisione bisogna che il dividendo sia precedentemente caricato o sia già presente nel registro AX (se a 8bit), quindi azzerando AH e inserendo in AL il valore del dividendo, oppure in DX:AX (se a 16bit), quindi azzerando DX e inserendo il valore del dividendo in AX. L’operazione di divisione genera il quoziente e il resto: (se divisore è a 8bit) AL = quoziente ( AX / divisore) AH = resto ( AX / divisore ) (se divisore è a 16bit) AX = quoziente ( DX:AX / divisore ) DX = resto ( DX:AX / divisore)
21
Le funzioni di INT21 erogati dal DOS
Un interrupt software, consiste in un tipo particolare di istruzione della CPU, che consente l'interruzione di un processo, qualora lo stesso debba effettuare una richiesta al sistema operativo o al BIOS del sistema. L’interruzione sincrona (trap) INT 21H, serve per chiedere, da parte dell’utente, i servizi e le funzioni erogati dal DOS. In tutte le chiamate il valore contenuto nel registro AH, è il numero della funzione che deve essere eseguita. Altri parametri possono essere richiesti in altri registri. In tutti i casi la sintassi di programmazione, da realizzare, è questa: Impostare AH con il numero della funzione desiderata. Impostare il contenuto dei registri eventualmente coinvolti nella chiamata. Fare la chiamata, alla funzione impostata, con l’istruzione INT 21h.
22
Alcune funzioni di INT21 Sintassi: MOV AH , codice_funzione INT 21h
Input di un carattere inserito dalla tastiera con eco (il carattere inserito viene visualizzato): MOV AH, 01H - il carattere viene caricato in AL INT 21H Input di un carattere inserito dalla tastiera senza eco (il carattere inserito non viene visualizzato): MOV AH, 07H - il carattere viene caricato in AL Per entrambi le funzioni il carattere caricato in AL è il codice ASCII corrispondente rappresentato in codice binario.
23
Alcune funzioni di INT21 Output di un carattere:
MOV DL, 42h - nel registro DL va inserito il codice ASCII del carattere da stampare MOV AH,02h il valore può essere espresso in esadecimale(h) o decimale(d) INT 21H Output di una stringa di caratteri: MOV MOV DS, AX MOV DX,OFFSET Messaggio MOV AH,09H Funzione ritorno al sistema operativo: MOV AH,4C serve alla fine di ogni programma per restituire il INT 21h controllo al Sistema Operativo Questo blocco d’istruzione serve per stampare a video il messaggio precedentemente dichiarato nella direttiva .DATA
24
Istruzioni di salto Le istruzioni di salto permettono di specificare l’indirizzo dell’istruzione successiva da eseguire, in modo da modificare la normale sequenza di esecuzione. L’istruzione di destinazione può essere successiva (selezione) o precedente (iterazione) rispetto all’istruzione di salto. Le istruzioni di salto possono essere incondizionate (vengono sempre eseguite) o condizionate (vengono eseguite o meno in base al valore di determinati flag). Le istruzioni a cui si può arrivare mediante un salto possono essere individuate o mediante il loro indirizzo, o mediante un’etichetta. Un’etichetta in un programma rappresenta l’indirizzo di un’istruzione (l’assemblatore calcola l’indirizzo corrispondente all’etichetta). Le etichette sono specificate come segue: nome_etichetta: istruzioni… N.B. in un programma non può essere assegnato a due etichette lo stesso nome.
25
L'istruzione di salto incondizionato
Viene eseguito con l’istruzione JMP Sintassi: JMP nome_etichetta L’istruzione JMP permette di fare un salto a qualsiasi altro indirizzo, anche in un segmento diverso, ma è buona regola eseguire solo salti all’interno dello stesso modulo (del programma principale o della procedura). Esempi: inizio: JMP fine … … JMP inizio fine:
26
L’istruzione CMP per i salto condizionati
L'istruzione CMP, precede sempre le istruzioni di salti condizionati. L’istruzione CMP ha il formato Sintassi: CMP operando1, operando2 es.: CMP AL , AH o CMP AL , variabile o CMP variabile , AL L’istruzione CMP si comporta come una sottrazione; sottrae il secondo operando dal primo, ma non modifica nessun operando, cioè trascura il risultato e l’unico effetto è quello di impostare i flag di stato in base al risultato calcolato, in modo che possano essere utilizzati correttamente da una successiva istruzione di salto condizionato. Infatti i salti condizionati si basano sul valore dei flag impostati dalle operazioni aritmetico-logiche generate dall’istruzione CMP. Se la condizione è falsa l’esecuzione continua in modo sequenziale, se la condizione è vera viene eseguito il salto.
27
Le istruzioni di salto condizionato
SALTI CONDIZIONATI: Il formato generale di una istruzione di salto condizionato è: Sintassi: Jxx etichetta (dove le xx sono possibili combinazioni di flag e/o risultato) Ad ogni flag di stato (ZF, SF, OF, CF, PF) sono associate due istruzioni di salto condizionato: Quelli che saltano se il flag è a JZ, JS, JO, JC, JP. Quelli che saltano se il flag è a JNZ, JNS, JNO, JNC, JNP. Es. JZ salta se il flag Z è a 1, JNZ salta se il flag Z è a 0. Ci sono poi altre istruzioni basate sugli stessi flag, ma più facili da ricordare: JE salta se op1 = op2 (equivalente a JZ) JNE salta se op1 ≠ op2 (equivalente a JNZ)
28
Le istruzioni di salto condizionato
Per il confronto tra numeri con segno: JL o JNGE salta se op1 < op2 (salta se il flag di segno è a 1) JG o JNLE salta se op1 > op2 (salta se entrambi i flag di zero e di segno sono uguali 0) JLE o JNG salta se op1 <= op2 (salta se il flag di zero è a 1 o il flag di segno è a 1) JGE o JNL salta se op1 >= op2 (salta se il flag di segno è a 0) Per il confronto tra numeri senza segno o tra caratteri (B below, A above): JB o JNAE salta se op1 < op2 (salta se il flag di carry è a 1) JA o JNBE salta se op1 > op2 (salta se entrambi i flag di carry e di zero sono 0) JBE o JNA salta se op1 <= op2 (salta se il flag di carry è a 1 o il flag di zero è a 1) JAE o JNB salta se op1 >= op2 (salta se il flag di carry è a 0)
29
Le istruzioni di salto condizionato LOOP
L’istruzione LOOP è un'operazione che usa il registro CX come contatore. Ogni volta che viene eseguita l'istruzione LOOP, il registro CX viene decrementato di una unità, e viene controllato se è 0(zero). Se CX è 0, il ciclo termina e l'esecuzione del programma e continua con l'istruzione che segue l'istruzione LOOP, altrimenti viene eseguito un salto all’etichetta. Esistono alcune varianti dell'istruzione LOOP in cui viene controllato anche il flag ZF come condizione per terminare il ciclo, ovviamente l’istruzione LOOP non influisce sullo stato dello stesso, ma esso viene modificato da altre istruzioni nel ciclo. LOOP: decrementa CX e salta all’etichetta, se CX è diverso da 0(zero). LOOPE – LOOPZ: decrementa CX e salta all’etichetta, se CX è diverso da 0(zero) e ZF uguale a 1(uno). LOOPNE – LOOPNZ: decrementa CX e salta all’etichetta, se CX è diverso da 0(zero) e ZF uguale a 0(zero).
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.