Breve guida AL LINGUAGGIO ASSEMBLY (emulatore
Transcript
Breve guida AL LINGUAGGIO ASSEMBLY (emulatore
LABORATORIO DI SISTEMI – ASSEMBLY 8086 PROF. CARMELO CALARCO Breve guida AL LINGUAGGIO ASSEMBLY (emulatore EMU8086) 1 LABORATORIO DI SISTEMI – ASSEMBLY 8086 IL LINGUAGGIO ASSEMBLY Il linguaggio assembly è un linguaggio di programmazione a basso livello. Per linguaggi di basso livello si intendono il sottogruppo linguaggi di programmazione orientanti alla macchina, al contrario del linguaggio di programmazione ad alto livello che è orientato all'utente. Un esempio di linguaggio a basso livello è l'assembly. Per programmare in assembly è necessario conoscere la struttura di base di un PC. La struttura più semplice di un computer può essere così schematizzata: Il SYSTEM BUS (parte colorata in giallo) connette le varie componenti del computer. La CPU è il cuore di un computer, esegue tutte le operazioni di calcolo e rappresenta quindi il parametro principale per valutare le prestazioni di un computer. È composta da un’unità con funzioni aritmetiche e logiche chiamata ALU (Arithmetic/Logic Unit), da un’unità di controllo e temporizzazione chiamata CTU (Control/Timing Unit) e dai registri, piccole memorie che contengono i dati 2 LABORATORIO DI SISTEMI – ASSEMBLY 8086 da utilizzare nelle operazioni matematico/logiche o di controllo. La RAM è l’area di memoria in cui i programmi sono caricati per poi essere mandati in esecuzione. 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. Registri indice, contengono l’indirizzo per raggiungere le locazioni di memoria all’interno del segmento dati, sono due: SI - registro indice sorgente. DI – registro indice destinazione. 3 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Registri puntatore, (o Index o Offset) sono generalmente utilizzati come puntatori a dati in memoria (contengono cioè gli indirizzi di memoria). Si possono dividere 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) 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. 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. 15 14 13 12 11 OF 10 DF 09 IF 08 TF 07 SF 06 ZF 05 04 AF 03 02 PF 01 00 CF 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. 4 LABORATORIO DI SISTEMI – ASSEMBLY 8086 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. Vediamo alcuni esempi possibili: MOV ax,bx MOV bx,ax MOV variabile,ax ed alcuni esempi errati: ADD al,bx (dimensioni diverse) ADD var1,var2 (due variabili) ADD 5,ax (la dest. non può essere una costante) 5 LABORATORIO DI SISTEMI – ASSEMBLY 8086 INDIRIZZAMENTO DEI DATI DEL PROCESSORE 8086 Gli indirizzamenti possibili sono: 1) indirizzamento immediato, il sorgente è una costante: MOV AL,8 (cifra decimale) MOV AL,0FH (cifra esadecimale, seguita dal suffisso H e prec. dallo 0 se inizia con una lettera)[B:binario/O:ottale] 2) indirizzamento con registro, gli operandi sono dei registri: MOV AX,BX ADD DL,AL CMP AX,DX MOV CX,BH (non valida - dimensioni diverse) 3) indirizzamento diretto, uno dei due operandi è una variabile: MOV AX,PIPPO MOV PLUTO,AL MOV TIZIO,5 MOV 5,TIZIO (non valida – costante come destinazione) MOV CAIO,TIZIO (non valida – due variabili) 6 LABORATORIO DI SISTEMI – ASSEMBLY 8086 MODELLO DI UN PROGRAMMA IN ASSEMBLY CON L’EMULATORE EMU8086 LABORATORIO DI SISTEMI – ASSEMBLY 8086 alcuni modelli di memoria processore 8086: TYNY: unico seg per i dati e per il codice; SMALL: un seg per il codice ed uno per i dati; COMPACT: un seg per il codice e più seg per i dati; MEDIUM: un seg per i dati e più seg per il codice; LARGE: più segmenti per i dati e per la memoria; Definizione di Costanti • Le costanti sono nomi dati a valori • non compaiono nel codice oggetto ed eseguibile – Il valore di una costante non può essere modificato • Durante la traduzione, l’assemblatore sostituisce ogni occorrenza del nome di una costante con il valore corrispondente – Esempi: MAX EQU 10h VAT EQU ‘@’ MOV AH,MAX ;diventa MOV AH,10h MOV AL,VAT ;diventa MOV AL,40h (cod. ASCII di @) *** Definizione di variabili • Sintassi: <nome> <tipo> <val_iniziale> dove: <nome> è un identificatore <tipo> indica la dimensione e può essere – DB: Byte (8 bit) – DW: Word (16 bit) – DD: Double Word (32 bit) (non usato nell’8086) <val_iniziale> è il valore di inizializzazione e può essere – un valore numerico (es.: VAR1 DB 10) – una stringa di caratteri (es.: VAR1 DB ”casa: $”) – il carattere ? (indica nessun valore, es.: VAR1 DB ?) 8 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Dichiarazione di una stringa di caratteri: .data MESSAGGIO1 DB "Inserisci un carattere $" Codice per l’output di una stringa di caratteri: MOV DX,OFFSET MESSAGGIO1 MOV AH,09H INT 21H Codice che sposta a capo il cursore: .data CAPORIGA DB 13,10,"$" Input di un carattere inserito dalla tastiera: (il carattere digitato viene inserito nel registro AL) .data CARAT DB ? … MOV AH, 01H INT 21H => viene caricato in AL MOV CARAT, AL Output di un carattere inserito dalla tastiera: MOV DL, CARAT MOV AH, 02H INT 21H 9 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Dichiarazione di una variabile stringa: .data STRINGA DB N,?,N DUP (?) i cicli: MOV CX,VALORE OBIETTIVO: … … LOOP OBIETTIVO Salto incondizionato: etichetta: … … JMP etichetta JMP etichetta1 … … etichetta1: Confronto: CMP DEST, SORG Esempi di confronto: cmp registro,variabile cmp registro,registro cmp variabile,costante cmp registro,costante es.: – cmp ax,var1 – cmp ax,bx – cmp var,5 – cmp al,0dh cmp var1,0dh (13) je etichetta 10 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Salti condizionati senza segno: (in funzione del risultato della CMP) JE/JNE: salta se DEST=/≠SORG (sintassi JE/JNE <etichetta>) JB/JBE: salta se DEST</<=SORG (sintassi JB/JBE <etichetta>) JA/JAE: salta se DEST>/>=SORG (sintassi JA/JAE <etichetta>) Salti condizionati con segno: (in funzione del risultato della CMP) JE/JNE: salta se DEST=/≠SORG (sintassi JE/JNE <etichetta>) JL/JLE: salta se DEST</<=SORG (sintassi JL/JLE <etichetta>) JG/JGE: salta se DEST>/>=SORG (sintassi JG/JGE <etichetta>) 11 LABORATORIO DI SISTEMI – ASSEMBLY 8086 incremento: INC VAR1 INC BX decremento: DEC VAR1 DEC BX sottrazione: (sintassi SUB DEST, SORG) esempi: SUB AX,10 SUB AX,AX SUB VAR1,10 SUB AX,BX SUB BX,VAR1 addizione: (sintassi ADD DEST,SORG) esempi: ADD AX,10 ADD VAR1,10 ADD AX,BX ADD BX,VAR1 12 LABORATORIO DI SISTEMI – ASSEMBLY 8086 divisione: • Senza segno: DIV (DIVision, unsigned) Sintassi: DIV <source> SUB AX,AX ; azzeramento del registro • Divisione di un byte per un altro byte MOV AL,VAR1 ; dividendo a 8 bit DIV VAR2 ; quoziente in AL e resto in AH • Divisione di una word per un byte MOV AX,VAR1 ; dividendo a 16 bit DIV VAR2 ; quoziente in AL e resto in AH • Con segno: IDIV (Integer DIVision) – Stessa sintassi di DIV moltiplicazione: • Senza segno: MUL (MULtiply, unsigned) Sintassi: MUL <source> MOV AL,NUMERO1 ; operando a 8 bit MUL NUMERO2 ; risultato in AL (8 bit) MOVE AX,NUMERO1 ; operando a 16 bit MUL NUMERO2 ; risultato in AX (16 bit) • Con segno: IMUL (Integer MULtiply) – Stessa sintassi di MUL 13 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Le variabili (array) • Gli array sono sequenze di dati di tipo omogeneo – Es.: vettori numerici (1,2,5,3) – Es.: stringhe di caratteri (“prova”) • Le variabili array si dichiarano come segue: a DB 1, 4, 6, 16, 3, 0 ; array di 6 byte b DB ‘H’,’e’,’l’,’l’,’o’ ; array di caratteri c DB 5 DUP(9) ; come c DB 9,9,9,9,9 d 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 14 LABORATORIO DI SISTEMI – ASSEMBLY 8086 vettori di caratteri non definito: dimensionamento: DIM EQU 10 (inizio del progr.) dichiarazione: VET DB DIM DUP (?) definizione nel programma: VET[SI] >SI indice del vettore 15 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Esempi di codice: Trasformazione di un carattere in un numero SUB NUM, 30h (sottrae al valore corrispondente del codice ASCII del carattere il valore 30h[48d], il risultato è un valore che va da 0 a 9 [per es. se il carattere inserito da tastiera num = 2, il corrispondente codice ASCII è 50, sottraendo 48, avremo 2 come valore numerico] ) Trasformazione di un numero ad una cifra in un carattere ADD NUM, 30h (somma al valore corrispondente del codice ASCII del carattere il valore 30h[48d], il risultato è un valore che va da 48 a 57 [per es. se il valore di num = 2, il corrispondente codice ASCII è 50, sommando 48, avremo 50] ) 16 LABORATORIO DI SISTEMI – ASSEMBLY 8086 Input numero a due cifre: LABORATORIO DI SISTEMI – ASSEMBLY 8086 Visualizzazione numero a due cifre: LABORATORIO DI SISTEMI – ASSEMBLY 8086 Input/output vettore di un carattere: LABORATORIO DI SISTEMI – ASSEMBLY 8086 Input di un vettore numerico con elementi a 2 cifre: n EQU 10 ……. LABORATORIO DI SISTEMI – ASSEMBLY 8086 Output di un vettore numerico con elementi a 2 cifre: