Architettura dei Calcolatori 08 Assembler
-
Upload
majong-devjfu -
Category
Technology
-
view
3.205 -
download
0
description
Transcript of Architettura dei Calcolatori 08 Assembler
Dispense del corso diArchitettura dei CalcolatoriArchitettura dei Calcolatori
Intel 8086/8 – ISA e Assembly
Architettura dei calcolatori a.a. 2007/2008
Intel 8086
AXBXCX
Bus indirizzi (20bit)
CXDXSPBP Bus dati
(16bit)DISI
CSDSESSS
(16bit)
BUScntr.
SSIP
Internal
Instruction queueEU
Temporary regs.
EUcntr.ALU
FLAGS
EU BIU
Architettura dei calcolatori a.a. 2007/2008
I registri della CPU 8086
• Il set di registri è la parte più importante di ciò che è visibile dal programmatore o al compilatore
• Registri sono divisi in:• Registri sono divisi in:– General Purpose Registers, – Segment Registers,
Miscellaneous Registers– Miscellaneous Registers.
• I General Purpose Registers hanno in realtà uno scopo ben preciso insito nel loro nome (non ortogonali) anche se molte istruzioni consentono di utilizzare iloro nome (non ortogonali) , anche se molte istruzioni consentono di utilizzare i registri generici indipendentemente dal loro scopo primario.
I registri sono AX BX CX DX SI DI BP SP• I registri sono AX, BX, CX, DX, SI, DI, BP, SP.
• Questi sono registri a 16 bit e per i primi 4 è possibile accedere direttamente agli 8 bit più significativi (parte alta/high) o agli 8 bit meno significativi (parte bassa/low) specificando H o L invece che X. Cioè, per esempio, CL è il registro a 8 bit corrispondente alla parte bassa di CX, mentre AH è la parte alta di AX.
Architettura dei calcolatori a.a. 2007/2008
I registri generici
• AX è l’accumulatore: serve per numerose operazioni matematiche, o di I/O o per speciali trasferimenti di dati.
• BX è il registro base: serve per contenere l’indirizzo di partenza durante gli indirizzamenti in memoria.
• CX è il registro di conteggio: serve per effettuare conteggi durante cicli o ripetizioni• CX è il registro di conteggio: serve per effettuare conteggi durante cicli o ripetizioni.
• DX è il registro dati: per contenere parte di dati eccedenti durate le operazioni aritmetiche(in coppia con AX) e per gli indirizzi delle istruzioni di I/O.) g
• SI e DI sono registri indice utilizzati principalmente durante le operazioni con stringhe di byte. Tipicamente SI punta alla sorgente, mentre DI punta alla destinazione.
• BP è il puntatore base e, in modo molto simile a BX, serve come indirizzo di partenza(principalmente entro lo stack), tipicamente durante l’accesso a parametri e variabili di funzioni.
• SP è il puntatore allo stack: l’8086 ha istruzioni per la gestione di questa struttura dati direttamente nella sua architettura e questo registro viene implicitamente referenziato da tutte queste istruzionitutte queste istruzioni.
Architettura dei calcolatori a.a. 2007/2008
I registri di segmento
• Senza entrare nel dettaglio del funzionamento dei segmenti, tali registri sono stati definiti perchè l’Intel si trovò di fronte al problema di indirizzare 1MB di memoria e che per motivi di progetto ed economici decise di non utilizzare registri a 20bit, ma di combinare opportunamente due registri a 16bitopportunamente due registri a 16bit.
• Esistono quindi 4 registri di segmento che hanno la funzione di suddividere la memoria in parti relative ai dati in esse contenuti:
– CS è l’indirizzo del segmento codice, cioè l’area di memoria da cui vengono lette le istruzioni da eseguire.
– DS è l’indirizzo del segmento dati, cioè l’area di memoria che contiene le variabili o le costanti necessarie al programma.
– ES è l’indirizzo del segmento ausiliario che consente di disporre rapidamente di ulteriore spazio per i dati senza dovere continuamente modificare DS.
– SS è l’indirizzo del segmento di stack.• L’utilizzo dei segmenti consente una notevole flessibilità, ma complica
notevolmente la progettazione del software in particolare per le strutture dati dinotevolmente la progettazione del software, in particolare per le strutture dati di dimensioni superiori ai 64KB.
Architettura dei calcolatori a.a. 2007/2008
Registri speciali
• Esistono due ulteriori registri speciali che non vengono modificati direttamente dal programmatore, ma sono fondamentali per l’esecuzione del software:
– IP è l’instruction pointer, cioè l’indirizzo, all’interno del code segmentdal quale prelevare la prossima istruzione.Specifica l’offset della successiva istruzione da eseguire in riferimento al segmento codice g gcorrente.
FLAG è un registro a 16 bit nel quale ogni bit (9 utilizzati nel 8086) ha– FLAG è un registro a 16 bit nel quale ogni bit (9 utilizzati nel 8086) ha un significato speciale che indica la modalità di funzionamento del software, lo stato del sistema o il risultato dell’istruzione precedente.
• Le istruzioni possono fare riferimento a tutti i registri generali e di segmento per leggerne o scriverne il valore, con l’eccezione di CS che può solo essere letto.
• Non è possibile fare riferimento a IP o a FLAG, perché questi sono implicitamente o esplicitamente modificati da istruzioni apposite.
• CS:IP e’ il corrispondente del Program Counter nella micro architettura
Architettura dei calcolatori a.a. 2007/2008
Il registro FLAG
• Ecco una breve descrizione del significato dei singoli bit:
Flag di Stato:
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00OF DF IF TF SF ZF AF PF CF
Flag di Stato:– Overflow(OF): Indica che operazione ha riportato un risultato troppo grande– Sign(SF): Viene posto a 1 se il risultato di una operazione è negativo
Z (ZF) Vi 1 il i lt t di i è 0– Zero(ZF): Viene messo a 1 se il risultato di una operazione è 0– Auxiliary Carry(AF): Indica un riporto o un prestito tra la parte bassa e quella alta di un
numero. Viene usato dalle istruzioni aritmetico decimale.Parity Flag(PF): Posto a 1 quando c’è un numero pari di bit a 1 nel risultato– Parity Flag(PF): Posto a 1 quando c è un numero pari di bit a 1 nel risultato dell’operazione. Utilizzato dai programmi di comunicazione.
– Carry Flag(CF): Indica un riporto o un prestito nella parte alta dell’ultimo risultato. Serve per realizzare istruzioni multi word.Serve per realizzare istruzioni multi word.
Flag di Controllo:– Direction(DF): Indica se decrementare o incrementare per le istruzioni con le stringhe.
Indica se la stringa viene letta/scritta a partire dall’elemento con indirizzo piu’g p palto/basso
– Interrupt Enable(IF): Indica se le interruzioni mascherabili sono abilitate– Trap(TF): Questo flag è usato dai debugger per eseguire i programmi un passo alla p( ) g gg p g p g p
volta. Genera un INT 3 dopo ogni istruzione
Architettura dei calcolatori a.a. 2007/2008
Assemblatore Intel
• Il codice macchina è una sequenza numerica che codifica le istruzioni e gli operandi. Ad esempio, il codice operativo 8A 49 E4 indica di copiare il byte contenuto all’indirizzo di memoria dato da BX+DI-28 nel registro CL.N è lt d l l d il di hi t ti i• Non è molto comodo programmare calcolando il codice macchina, per questo motivo si utilizza un programma che traduce le istruzioni da una forma testuale più comprensibile al programmatore nel codice macchina.
• L’istruzione precedente può allora essere scritta come:p pmov cl,[bx+di-28]
• Non esiste purtroppo un accordo ufficiale sulla sintassi che deve essere rispettata da un assemblatore ed esistono diverse varianti per lo stesso codice operativo.– Ad esempio l’istruzione precedente, con il Microsoft Macro
Assembler (MASM), può essere scritta come mov cl,[bx+di]-28o mov cl,[bx][di][-28] o mov cl,[di][-28][bx], ecc...
• Un altro pacchetto disponibile e’ il “flat assembler” (FASM) un assemblatore che può essere utilizzato gratuitamente e del quale sono disponibili i sorgenti in rete.
• Per i dettagli sulla sintassi di questo assemblatore si rimanda alla documentazione Solo per chiarezza, per coloro che hanno utilizzato altri assemblatori, notiamo che la sintassi deglichiarezza, per coloro che hanno utilizzato altri assemblatori, notiamo che la sintassi degli indirizzi è molto più rigida: quando si specifica un operando in memoria questo deve essere compreso tra parentesi quadre e all’interno delle parentesi possono comparire registri, etichette e valori immediati separati da “più”. Inoltre nella dichiarazione di dati la direttiva dup viene sostituita da times che ha una sintassi leggermente diversa.dup viene sostituita da times che ha una sintassi leggermente diversa.
Architettura dei calcolatori a.a. 2007/2008
Linguaggio macchina ed assembler
• Linguaggio macchina è binario • Linguaggio assembler è in forma simbolica; • Il formato di una istruzione in assembler è il seguente:
Etichetta: Mnemonico Operando1, Operando2; Commento
• Etichetta– è un identificatore (stringa) cui è assegnato l’indirizzo del primo byte
dell’istruzione alla quale si riferisce– Può servire come nome simbolico cui riferirsi nei salti condizionati e
incondizionati• Mnemonico
– indica l’operazione vera e propriai di > ADD• es: operazione di somma => ADD
• Operando– la presenza dipende dall’istruzione– possiamo avere istruzioni con 1 2 o nessun operandopossiamo avere istruzioni con 1, 2 o nessun operando
• Commento– Se non presente il punto e virgola può essere omesso
Architettura dei calcolatori a.a. 2007/2008
Regole di Sintassi - Costanti numeriche
• Un numero con suffisso che indica la base:
– B o b (binario), – D o d (decimale)– D o d (decimale), – O o o (ottale), – H o h (esadecimale).
P d f lt l b è d i l• Per default la base è decimale
• In caso di base esadecimale la prima cifra a sx deve essere compreso tra 0 e 9 es: BC2H deve essere scritto 0BC2H altrimenti verrebbe confusa con una stringa.g
• Esempi corretti:
– 0FFh– 0h– 777O
11001B– 11001B
• Esempi errati:
FFh t !– FFh errata !– 778O errata
Architettura dei calcolatori a.a. 2007/2008
Dichiarazione dei dati
• Sintassi:
– <nome var> <mnemonico> op1, op2,… ;commento• Lo mnemonico determina la dimensione in byte• Lo mnemonico determina la dimensione in byte
– DB (define byte) ogni operando occupa 1 byte– DW (define word) ogni operando occupa 1 word = 2bytes( ) g p p y– DD (define double word) occupa 2 word = 4bytes
• Gli operandi possono essere dei valori o espressioni costanti• Per riservare lo spazio di memoria si usa “?”• Per riservare lo spazio di memoria si usa ?• Esempio:
DATA_SEG SEGMENT
DATA BYTE DB 10 4 10HDATA_BYTE DB 10,4,10HDATA_WORD DW 100,?,-5DATA_DW DD 3*20,0FFFDH
DATA_SEGMENT ENDS
• Individuano 3 aree di memoria contigue lunghe ciascuna: 3 bytes, 6 bytes e 8 bytes• Come definire un “array”
– <nome var> DB | DW| DD <dim> DUP (<elementi>)| | ( )• duplica gli <elementi> specificati il numero di volte specificato da dim
Architettura dei calcolatori a.a. 2007/2008
Modalità di Indirizzamento
• Esistono molti modi per indicare nell’istruzione dove trovare l’operando
• REGISTRO: l’operando si trova in un registro
• IMMEDIATO: l’operando è nella istruzione
MEMORIA è i i i di i di di l l• MEMORIA: se è in memoria, ci sono diversi modi di calcolare l’indirizzo; alcune CPU prevedono molte modalità, maggiore flessibilità e diminuzione del numero delle istruzioni; ma questo implica reti logiche più complesse nella gestione ed un codice operativo con più bit
Architettura dei calcolatori a.a. 2007/2008
Metodi di indirizzamento in Memoria Intel• Oltre che ai registri è possibile accedere alla memoria e questo può essere fatto in 17 modi di
indirizzamento (8086) per specificare un indirizzo di memoria. Questi possono essere raggruppati in 3 categorie:– Indirizzamento diretto: si specifica l’indirizzo di memoria tramite un valore p
numerico detto displacement, cioè spostamento.– Indirizzamento indiretto tramite registro base: si specifica l’indirizzo di
memoria tramite il valore contenuto in uno tra i registri base BX o BP.– Indirizzamento indiretto tramite registro indice: si specifica l’indirizzo di
memoria tramite il valore contenuto in uno tra i registri indice SI o DI.• È possibile combinare queste tre modalità ottenendo tutte le possibili combinazioni. Per ricordare le
combinazioni valide è sufficiente memorizzare la tabella seguente (ognuno dei tre elementi può noncombinazioni valide è sufficiente memorizzare la tabella seguente (ognuno dei tre elementi può non essere presente):
BX SIBX SIBP DI
+ +Disp
• Le modalità di indirizzamento viste si riferiscono sempre e solo al calcolo dell’offset, ovvero di un valore a 16 bit dato dalla somma dei tre possibili campi. A queste si deve sommare, scalato l’indirizzo di segmento (modello di memoria segmentato)
Architettura dei calcolatori a.a. 2007/2008
Modi di indirizzamento di I/O Intel
L’architettura INTEL ha uno spazio di indirizzamento specifico per l’I/O ed istruzioni specifiche per accedervi.
Indirizzamento DIRETTOL’indirizzo può essere solo a 8 bit nell’istruzione (fino a 256 indirizzi diversi).L indirizzo può essere solo a 8 bit nell istruzione (fino a 256 indirizzi diversi). AL serve per contenere il dato (a 8 bit)
in AL,PORTA1 ; AL I/O[PORTA1]out PORTA2,AL ; I/O[PORTA2] AL
Indirizzamento INDIRETTO con registro DXL’indirizzo è a 16 bit ed è nel registro DXg
in AL,DX ; AL I/O[DX]out DX,AL ; I/O[DX] AL
Architettura dei calcolatori a.a. 2007/2008
Insieme delle istruzioni 8086
• Possiamo suddividere le istruzioni 8086 in gruppi funzionali:
– Trasferimento di dati– Trasferimento di controllo– Aritmetica binaria– Logica binaria– Shift e Rotate– Operazioni su stringhe di dati– Istruzioni per il controllo dei flagg– Aritmetica decimale (Binary Coded Decimal)– Varie
• Di seguito esamineremo ogni gruppo di istruzioni, rimandando per i dettagli sulla sintassi alle guide elettroniche fornite sul sito.
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di dati
• Fanno parte di questo gruppo:
– MOV dest,sorg Sposta il contenuto del secondo operando nel primoprimo
– XCHG dest,sorg Scambia il contenuto dei due operandi– PUSH word Inserisce una word nello stack– POP word Estrae una word dallo stack– IN accum,porta Legge un dato dalla porta specificata– OUT porta,accum Scrive un dato sulla porta specificata
• L’istruzione MOV è certamente la più usata e semplice da comprendere. XCHG consente diL istruzione MOV è certamente la più usata e semplice da comprendere. XCHG consente di scambiare due registri senza passare per una variabile temporanea.
• È importante notare che non è possibile muovere o scambiare dati tra memoria e memoria, ma solo tra memoria e registri/valori.
• Le istruzioni di IN e OUT consentono di accedere ai registri delle periferiche collegate al bus di sistema.
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di dati (2)
• Le istruzioni PUSH e POP lavorano con lo stack. Per la precisione, l’istruzione PUSH AX è equivalente a:SP = SP - 2[SS:SP] = AXMentre POP AX equivale a:AX = [SS:SP] = AX[ ]SP = SP + 2
• Quello che può sembrare strano è il fatto che il puntatore allo stack venga decrementato adQuello che può sembrare strano è il fatto che il puntatore allo stack venga decrementato ad ogni inserimento. In realtà questo consente una modalità di programmazione molto compatta (nota anche come Modello di memoria Tiny) in cui tutti i segmenti hanno lo stesso valore, i dati seguono immediatamente il codice e lo stack parte dalla fine del segmento:
0 FFFFCodice Dati … Stack
• Questo modello di memoria ha un chiaro svantaggio, cioè limita il programma e tutti i suoi dati ad un massimo di 64KB, ma elimina la necessità di occuparsi della segmentazione.
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di controllo
• Fanno parte di questo gruppo:
– CALL ind Esegue la procedura all’indirizzo ind– RET Ritorna da una procedura– RET Ritorna da una procedura
– INT num Esegue l’interruzione software num– IRET Ritorna da una interruzione software
– JMP ind Salta all’indirizzo ind– Jxx ind Salta all’indirizzo ind se è verificata la condizione xx
LOOP ind Decrementa CX e se non è zero salta a ind– LOOP ind Decrementa CX e se non è zero salta a ind– LOOPxx ind Come LOOP, ma salta solo se è verificata xx
L’i t i iù hi è t t JMP h ò id t tit t “MOV IP i d”• L’istruzione più chiara è certamente JMP, che può essere considerato un sostituto per “MOV IP,ind” e che chiarisce il concetto indicando che si “salta” in un’altra zona del programma.
• CALL è la versione di JMP che consente di tornare da dove si era venuti. Per fare questo prima del salto viene eseguito un PUSH IP. Se si salta in un altro segmento viene prima salvato CS, poi IP ed infine si salta. RET ritorna alla posizione precedente.
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di controllo (2)
• Le istruzioni di salto condizionato sono:
JA (JNBE) JAE (JNB) JB (JNAE) JBE (JNA) JEJA (JNBE), JAE (JNB), JB (JNAE), JBE (JNA), JE, JG (JNLE), JGE (JNL), JL (JNGE), JLE (JNG), JNEA=above (superiore), B=below (inferiore), E=equal (uguale), G=greater(maggiore), L=less (minore), N=not
• Questi salti fanno riferimento al risultato dell’operazione aritmetica CMP (compare) che esegue una sottrazione ed aggiorna i FLAG in modo opportuno. Quindi queste interpretazioni logiche non sono altro che una combinazione dello stato dei FLAG.
• Esistono salti che fanno esplicito riferimento ai FLAG:
• JC, JNC, JNO, JNP (JPO), JNS, JNZ, JO, JP (JPE), JS, JZC=carry (riporto), O=overflow, S=sign (segno), Z=zero, P=parity
• Esiste inoltre JCXZ che salta se CX è uguale a 0.
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di controllo (3)
JNE Jump if Not Equal ZF = 0
JNG Jump if Not Greater ZF = 1 o SF ≠ OF
JNGE Jump if Not Greater nor Equal SF ≠ OF
Istruzione Descrizione Salta se ...
JA Jump if Above CF = 0 e ZF = 0
JAE Jump if Above or Equal CF = 0
JNL Jump if Not Less SF = OF
JNLE Jump if Not Less nor Equal ZF = 0 e SF = OF
JNO Jump if No Overflow OF= 0
JNP Jump if No Parity (odd) PF = 0
JB Jump if Below CF = 1
JBE Jump if Below or Equal CF = 1 o ZF = 1
JC Jump if Carry CF = 1
JE Jump if Equal ZF = 1 JNP Jump if No Parity (odd) PF = 0
JNS Jump if No Sign SF = 0
JNZ Jump if Not Zero ZF = 0
JO Jump on Overflow OF =1
JE Jump if Equal ZF = 1
JG Jump if Greater ZF = 0 e SF = OF
JGE Jump if Greater or Equal SF = OF
JL Jump if Less SF ≠ OF
JP Jump on Parity (even) PF = 1
JPE Jump if Parity Even PF = 1
JPO Jump if Parity Odd PF = 0
JS Jump on Sign SF = 1
JLE Jump if Less or Equal ZF = 1 o SF ≠ OF
JNA Jump if Not Above CF = 1 o ZF = 1
JNAE Jump if Not Above nor Equal CF = 1
JNB Jump if Not Below CF = 0 JS Jump on Sign SF = 1
JZ Jump if Zero ZF = 1
JNB Jump if Not Below CF = 0
JNBE Jump if Not Below nor Equal CF = 0 e ZF = 0
JNC Jump if No Carry CF = 0
Architettura dei calcolatori a.a. 2007/2008
Trasferimento di controllo (4)
• L’istruzione LOOP consente di eseguire i tipici cicli di una programmazione strutturata. La variabile di controllo è CX e LOOP è equivalente a un decremento di CX seguito da un salto se CX è diversoequivalente a un decremento di CX, seguito da un salto se CX è diverso da 0.
• Esistono inoltre LOOPE (LOOPZ) e LOOPNE (LOOPNZ) che combinano il test CX diverso da 0 con il risultato di una operazione di compare precedente.
• Infine l’istruzione INT consente di invocare le interruzioni software, che per ora possiamo considerare come chiamate a funzione tramite un indice numerato. Successivamente nel corso ne capiremo il reale significato. Per ora basti sapere che INT è una CALL far (cioè inter-g p (segmento) che salva sullo stack anche il registro FLAG.
• Per questo motivo esiste un ritorno speciale IRET che prima estrae dallo stack IP e CS e poi anche FLAGstack IP e CS e poi anche FLAG.
Architettura dei calcolatori a.a. 2007/2008
Implementare un If o un While
char c;
;if (c==‘5')cmp c,‘5'jne elsechar c;
...if (c==‘5')
SeVero();
j;then-partcall SeVerojmp endif;else partelse
SeFalso();
;else-partelse:call SeFalsoendif:
;while (n>0)
int n;...while (n>0)
while:cmp n,0jle end_while;loop-bodywhile (n>0)
n-=2;;loop bodysub n,2jmp whileend_while:
Architettura dei calcolatori a.a. 2007/2008
Aritmetica binaria
• Fanno parte di questo gruppo:
– ADC dest,sorg Add with CarryADD d t Additi– ADD dest,sorg Addition
– CMP dest,sorg Compare– DEC dest DecrementDEC dest Decrement– DIV sorg Divide, Unsigned– IDIV sorg Integer Divide, Signed– IMUL sorg Integer Multiply, Signed– INC dest Increment
MUL M lti l U i d– MUL sorg Multiply, Unsigned– NEG dest Negate– SBB dest,sorg Subtract with BorrowSBB dest,sorg Subtract with Borrow– SUB dest,sorg Subtract
• Le operazioni più semplici sono certamente INC e DEC che aumentano o diminuiscono di uno il valore di un registro o di una variabile in memoriauno il valore di un registro o di una variabile in memoria.
Architettura dei calcolatori a.a. 2007/2008
Aritmetica binaria
• Esistono poi ADD e SUB che effettuano somma e sottrazione del secondo operando rispetto al primo e salvano il risultato nel primo.
• CMP è identico a SUB però non salva il risultato dato che serve unicamente per• CMP è identico a SUB, però non salva il risultato, dato che serve unicamente per confrontare il contenuto di due registri e quindi effettua una differenza per impostare i flag, ma non usa il risultato per nessuno scopo.
• ADC e SBB sono le versioni di somma e sottrazione che tengono conto di riporto• ADC e SBB sono le versioni di somma e sottrazione che tengono conto di riporto o prestito dell’operazione precedente, utili per effettuare elaborazioni con numeri più grandi di 16 bit.
• MUL effettua la moltiplicazione di AL o AX con il byte o word passato come• MUL effettua la moltiplicazione di AL o AX con il byte o word passato come parametro e mette il prodotto rispettivamente in AX o in DX:AX (cioè la parte alta in DX e la parte bassa in AX). IMUL è l’equivalente per numeri con segno.DIV di ide AX o DX AX per il b te o ord passate come parametro e mette il• DIV divide AX o DX:AX per il byte o word passate come parametro e mette il quoziente e il resto in AL e AH o in AX e DX. IDIV è l’equivalente per numeri con segno.
• Nel caso che il risultato della DIV sia troppo grande per il registro destinazione o che il divisore sia 0, viene generato un INT 0h (Divisione per zero).
• La NEG produce il negato del registro passato come parametro.
Architettura dei calcolatori a.a. 2007/2008
Esempio
Voglio realizzare la seguente operazione:
W = X+Y+24 ZW = X+Y+24-Z
Devo svolgere il calcolo in vari passaggi:
mov AX,X ; metto X in AXadd AX,Y ; aggiungo Y al contenuto di AXadd AX,Y ; aggiungo Y al contenuto di AXadd AX,24 ; gli sommo 24sub AX,Z ; gli sottraggo Zmov W,AX ; memorizzo in W il contenuto di AX…X DW 34Y DW 16Z DW 20W DW ?W DW ?
Architettura dei calcolatori a.a. 2007/2008
Esempio: Somma di valori a 32 bit
• Voglio sommare i due valori a 32 bit 0123 BC62 e 0012 553A• Visto che nell’8086 i dati sono al massimo a 16 bit, posso svolgere il
l l i d t i i N l d tcalcolo in due step successivi. Nel secondo step posso usare direttamente l’istruzione ADC.
mov ax,W10 ; si somma la word meno significativaadd ax,W20mov W30,axmov ax,W11 ; si somma la word più significativaadc ax,W21 ; e si somma con carrymov W31,ax ; in W31 si mette il risultato
; dati
W11 dw 0123hW10 dw bc62hW21 dw 0012hW20 dw 553ahW31 dw ?W30 dw ? ; non inizializzato
Architettura dei calcolatori a.a. 2007/2008
Esempio 1
• Vediamo il primo esempio completo di programma assembly:
_TEXT segmentassume cs:_TEXT, ds:_TEXT, ss:_TEXTorg 100h
Leggi: mov ah,07h ; Questa è la funzione di letturaint 21h ; di un carattere senza mostrarlo a video
cmp al,1Bh ; Il codice ASCII è 1B (ESC)?je Fine ; Se sì, vai alla fine
mov ah,02h ; Funzione di scrittura a videomov dl,al ; In DL ci va il carattere da visualizzareint 21h
jmp Leggi ; Leggi un altro carattere
Fine: ret
_TEXT endsend Leggi
Architettura dei calcolatori a.a. 2007/2008
Esempio 1
• Tutto il programma è incluso in un unico segmento che abbiamo chiamato _TEXT (come fa il C, ma è solo un nome si poteva scegliere anche qualcos’altro). La direttiva per dichiarare segmenti è SEGMENT e viene chiusa da ENDS.
• Alla fine del programma si deve sempre includere END, seguito dall’etichetta da cui deve cominciare il programma.
• La seconda riga informa l’assemblatore che CS conterrà l’indirizzo del segmento TEXTLa seconda riga informa l assemblatore che CS conterrà l indirizzo del segmento _TEXT, come anche DS ed SS.
• La terza riga contiene una direttiva per l’assemblatore che specifica che la prima istruzione sarà all’indirizzo 100h nel segmento. Questo è lo standard per i file .COM del vecchio MS-DOS ed è anche quello che utilizzeremo. Nei primi 100h byte c’erano dati del sistema operativo, come la linea di comando e le istruzioni per terminare il programma.
• Dalla quarta riga vediamo una delle principali caratteristiche dell’assemblatore, cioè quella di consentire la dichiarazione di etichette per indicare la posizione di una istruzione senza conoscere l’indirizzo.
• Che valore verrà sostituito all’etichetta Leggi?
Architettura dei calcolatori a.a. 2007/2008
Esempio 1
• L’etichetta Leggi indica l’indirizzo di una MOV che carica 07h nel registro AH. Poi viene chiamato l’INT 21h. Questa è l’interruzione che consente di accedere alle funzioni del DOS. La funzione richiesta viene passata in AH e la funzione 07h attende la pressione di un tasto. Il risultato (il codice ASCII del tasto premuto) viene ritornato in AL.
• Il programma prosegue con una CMP, per verificare se l’utente ha premuto il carattere ESC C ià i t CMP tt i t AL 1Bh i t il flESC. Come già spiegato, CMP esegue una sottrazione tra AL e 1Bh e imposta il flag zero (ZF). Possiamo allora verificare se sono uguali, con un JE. JE è infatti un sinonimo per JZ,che però mette in evidenza (solo a livello concettuale) che la differenza è stata eseguita con lo scopo di verificare una uguaglianza. Nel caso si sia premuto ESC, si saltacon lo scopo di verificare una uguaglianza. Nel caso si sia premuto ESC, si salta all’etichetta Fine.
• Il carattere letto viene poi visualizzato tramite la funzione 02h del DOS, che vuole il p ,carattere da visualizzare in DL. Infine si salta nuovamente all’etichetta Leggi.
• Nel caso si arrivi a Fine, viene eseguita una RET. Il DOS si è infatti preoccupato di fare una PUSH dell’indirizzo di ritorno, o meglio ha eseguito il nostro programma facendo una CALL all’Entry Point, ovvero l’etichetta che abbiamo messo a fianco della direttiva END.
Architettura dei calcolatori a.a. 2007/2008
Esempio 2
_TEXT segmentassume cs: TEXT, ds: TEXT, ss: TEXTorg 100h
Leggi: mov ah,07h ; Questa è la funzione di letturaint 21h ; di un carattere senza mostrarlo a video
cmp al,1Bh ; Il codice ASCII è 1B (ESC)?je Fine ; Se sì, vai alla fine
mov Numero,alcall ScriviNumero
mov ah,02h ; Funzione di scrittura a videomov dl,' ' ; In DL ci va il carattere da visualizzareint 21h
jmp Leggi ; Leggi un altro carattere
Fine: ret
Architettura dei calcolatori a.a. 2007/2008
Esempio 2 (segue)ScriviNumero:
mov ah,0mov al,Numeromov bl,16div bl
In questo esempio vediamo come si definiscono i dati tramite la direttiva define byte ovvero DB. Dopo la direttiva DB è possibile inserire uno odiv bl
mov ah,0mov si,axmov dl,CaratteriEsa[si]mov ah,02hint 21h
direttiva DB è possibile inserire uno o più valori numerici separati da virgole, stringhe tra apici (ogni carattere è un byte) oppure un ? che indica dati non
int 21h
mov ah,0mov al,Numeromov bl,16
inizializzati (in realtà vale solo se posizionato alla fine di un segmento, altrimenti è come scrivere 0).
div blxchg ah,almov ah,0mov si,axmov dl,CaratteriEsa[si]
Inoltre è possibile notare come CaratteriEsa[si] sia un indirizzamento indiretto tramite registro indice, equivalente al meno chiaroo d ,Ca atte sa[s ]
mov ah,02hint 21h
ret
equivalente al meno chiaro [CaratteriEsa+si].
CaratteriEsa db '0123456789ABCDEF'Numero db ?
_TEXT endsend Leggi
Architettura dei calcolatori a.a. 2007/2008
Esempio 2 (segue)proc ScriviNumero near
mov ah,0mov al,Numeromov bl,16div bl
La seconda parte potrebbe essere scritta anche così. Cioè invece che dichiarare una etichetta “normale”, si utilizza la direttiva PROC chiusa dadiv bl
mov ah,0mov si,axmov dl,CaratteriEsa[si]mov ah,02hint 21h
utilizza la direttiva PROC chiusa da ENDP. Non cambia nulla, a parte il fatto che si può esplicitare l’indicazione NEAR che indica una
int 21h
mov ah,0mov al,Numeromov bl,16
funzione all’interno dello stesso segmento.
div blxchg ah,almov ah,0mov si,axmov dl,CaratteriEsa[si]o d ,Ca atte sa[s ]mov ah,02hint 21h
retCaratteriEsa db '0123456789ABCDEF'CaratteriEsa db '0123456789ABCDEF'endp ; ScriviNumero
Numero db ?
TEXT endsend Leggi
Architettura dei calcolatori a.a. 2007/2008
Logica binaria
• Fanno parte di questo gruppo:
– AND dest,sorg AND bit a bitNOT d t NOT bit bit– NOT dest NOT bit a bit
– OR dest,sorg OR bit a bit– TEST dest,sorg TestTEST dest,sorg Test– XOR dest,sorg OR esclusivo bit a bit
• AND, NOT, OR e XOR eseguono l’operazione logica indicata sui bit dei registri forniti come parametri. TEST è invece un AND che però non salva il risultato, un po’ come CMP, ma modifica i FLAG. Questa istruzione serve per verificare se un certo bit di un byte o word è a 11.
Architettura dei calcolatori a.a. 2007/2008
Shift e Rotate
• Fanno parte di questo gruppo:
– SHL dest,count Spostamento logico a sinistraSHR d t t S t t l i d t– SHR dest,count Spostamento logico a destra
– SAL dest,count Spostamento aritmetico a sinistra– SAR dest,count Spostamento aritmetico a destraSAR dest,count Spostamento aritmetico a destra– ROL dest,count Rotazione verso sinistra– ROR dest,count Rotazione verso destra– RCL dest,count Rotazione attraverso il carry verso sinistra– RCR dest,count Rotazione attraverso il carry verso destra
• Gli shift logici spostano tutti i bit in una certa direzione, espellendo gli estremi nel carry e inserendo degli zeri come nuovi bit.SAL è id ti SHL t SAR i i bit li l bit di i i l d• SAL è identico a SHL, mentre SAR inserisce bit uguali al bit di segno originale, preservando quindi il segno del numero.
• I rotate sono equivalenti agli shift, ma reinseriscono il bit “espulso” dalla parte opposta come nuovo bit Le rotazioni attraverso il carry invece inseriscono il carrycome nuovo bit. Le rotazioni attraverso il carry invece inseriscono il carry.
Architettura dei calcolatori a.a. 2007/2008
Schemi operativi
Architettura dei calcolatori a.a. 2007/2008
Esempio 3proc ScriviNumero near
xor bh,bhmov ah,02hmov ch,2
In questo esempio è stata riscritta la procedura ScriviNumero, utilizzando anche le istruzioni logiche e la rotate.
mov dh,NumeroRipeti:
mov cl,4ror dh,cl
Nella prima riga, XOR viene utilizzato per azzerare BH.Il parametro count per gli shift e i rotate può
lt t 1 CL Att imov bl,dhand bl,0fhmov dl,CaratteriEsa[bx]int 21h
essere soltanto 1 oppure CL. Attenzione perché alcuni assemblatori consente anche altri valori, ma questi funzionano soltanto dal 80386 in avanti.
dec chjnz Ripetiret
80386 in avanti.Notare anche la mancanza di una CMP prima di JNZ.
CaratteriEsa db '0123456789ABCDEF'
endp ; ScriviNumero
Architettura dei calcolatori a.a. 2007/2008
Operazioni su stringhe di dati
• Fanno parte di questo gruppo:
– CMPS (CMPSB/CMPSW) Confronta stringhe di byte o wordMOVS (MOVSB/MOVSW) C i t i h di b t d– MOVS (MOVSB/MOVSW) Copia stringhe di byte o word
– LODS (LODSB/LODSW) Carica una stringa in AL o AX– STOS (STOSB/STOSW) Scrive AL o AX in una stringaSTOS (STOSB/STOSW) Scrive AL o AX in una stringa– SCAS (SCASB/SCASW) Confronta AL o AX con una stringa
• Prefissi relativi a questo gruppo
– REP/REPE/REPZ Ripetono l’operazione se CX≠0 e se ZF=0, poi CX=CX-1
– REPNE/REPNZ Ripetono l’operazione se CX≠0 e se ZF=1, poiREPNE/REPNZ Ripetono l operazione se CX≠0 e se ZF 1, poi CX=CX-1
• Queste operazioni sono istruzioni complesse che consentono di lavorare con stringhe di dati in modo semplice. L’indirizzo della stringa sorgente è sempre DS:SI e quello dati in modo semplice. L indirizzo della stringa sorgente è sempre DS:SI e quello destinazione è ES:DI.
• Ognuna di queste operazioni ha una forma con operandi a dimensione variabile e due senza operandi (B per byte e W per word), ma in realtà la prima è solo un modo per consentire più chiarezza nel codice e coincide esattamente con le altre due.
Architettura dei calcolatori a.a. 2007/2008
Operazioni su stringhe di dati (2)
• Tutte le istruzioni stringa incrementano di uno in caso di byte o di due in caso di word SI e DI. Se però il DF (flag direzione) è a 1 la direzione viene invertita e quindi SI e DI vengono decrementati.quindi SI e DI vengono decrementati.
– MOVS(B/W) copia un dato da DS:SI a ES:DI– LODS(B/W) carica un dato da DS:SI in AL o AXLODS(B/W) carica un dato da DS:SI in AL o AX– STOS(B/W) scrive il dato da AL o AX a ES:DI
• Solitamente per MOVS e STOS si utilizza il prefisso REP che consente di ripetere la copia o la scrittura CX volte. LODS si può ripetere, ma è totalmente inutile, dato che AL/AX viene continuamente sovrascritto.
– CMPS(B/W) confronta il dato in DS:SI con quello in ES:DICMPS(B/W) confronta il dato in DS:SI con quello in ES:DI– SCAS(B/W) confronta il dato in DS:SI con AL o AX
• CMPS e SCAS vengono tipicamente ripetuti con REPE/Z o REPNE/Z a seconda g p pche si voglia continuare fino a che il dato è uguale o diverso.
Architettura dei calcolatori a.a. 2007/2008
Istruzioni per il controllo dei flag
• Fanno parte di questo gruppo:
– CLC/STC Clear/Set Carry Flag (Pone CF a zero o a uno)uno)
– CLD/STD Clear/Set Direction Flag (Pone DF a zero o a uno)
– CLI/STI Clear/Set Interrupt-Enable Flag (Pone IF a zero o a uno)CMC Complement Carry Flag (Inverte lo stato di CF)– CMC Complement Carry Flag (Inverte lo stato di CF)
– LAHF Copia FLAG in AH– SAHF Copia AH nei FLAGp– POPF Estrae i FLAG dallo stack– PUSHF Memorizza i FLAG sullo stack
Q t i t i i ti i t t CLD STD i d ll i t i i t i CLC• Queste istruzioni tipicamente vengono usate CLD e STD prima delle istruzioni stringa, CLC, STC e CMC prima di alcune operazioni aritmetiche su numeri grandi, CLI e STI prima e dopo l’esecuzione di sezioni che lavorano con l’hardware o con le tabelle degli interrupt.
• Le altre servono tipicamente nelle routine di risposta agli interrupt• Le altre servono tipicamente nelle routine di risposta agli interrupt.
Architettura dei calcolatori a.a. 2007/2008
Aritmetica decimale (Binary Coded Decimal)
• Fanno parte di questo gruppo:
– AAA ASCII Adjust after AdditionAAD ASCII Adj t b f Di i i– AAD ASCII Adjust before Division
– AAM ASCII Adjust after Multiply– AAS ASCII Adjust after SubtractionAAS ASCII Adjust after Subtraction– DAA Decimal Adjust after Addition– DAS Decimal Adjust after Subtraction
• Non vedremo i dettagli di queste istruzioni, che servono per utilizzare il formato numerico Binary Coded Decimal (BCD). Questo formato prevede che i numeri compaiano in forma decimale, con una cifra per byte (formato unpacked-BCD) o due cifre per byte (formato packed-BCD).
Architettura dei calcolatori a.a. 2007/2008
Varie
• Fanno parte di questo gruppo:– LEA dest,source Carica l’indirizzo di source in dest– LDS dest,source Carica il puntatore all’indirizzo source in DS:dest, p– LES dest,source Carica il puntatore all’indirizzo source in ES:dest– NOP Non fa niente (no operation)– XLAT Estrae un dato da una tabella in memoriaXLAT Estrae un dato da una tabella in memoria
• LEA carica l’indirizzo di variabili in memoria in un registro, risolvendo eventuali indici o scostamenti.• LDS e LES servono per caricare una variabile puntatore far con una sola istruzione.• XLAT è equivalente ad una MOV AL,[BX+AL] (istruzione sintatticamente errata). Se ad esempio abbiamo
una serie di dati (byte) in memoria e vogliamo estrarre il 3° possiamo caricare in BX l’indirizzo dei dati euna serie di dati (byte) in memoria e vogliamo estrarre il 3 , possiamo caricare in BX l indirizzo dei dati e in AL 3.
• Operatore OFFSET– Formato: OFFSET <variabile o label>– L’operatore OFFSET restituisce il valore dell’offset di una variabile o della
labelP ò i l i ll’i i LEA l i i iù li i– Può essere usato in alternativa all’istruzione LEA solo nei casi più semplici
– – Esempio:MOV AX, OFFSET VARLEA AX, VAR,(se Var è una variabile => Sono equivalenti)
Architettura dei calcolatori a.a. 2007/2008
Esempio 4proc ScriviNumero near
mov dh,Numeromov cl,2
Ripeti:
Questa ennesima versione di ScriviNumero, mostra l’uso che si può fare di XLAT.N t h è t t i tit ilrol dh,1
rol dh,1rol dh,1rol dh,1
Notare che è stato invertito il verso della rotazione e che è stata usata l’istruzione LOOP per la ripetizione.Il parametro della XLAT è sempre [BX]
mov al,dhand al,0fhmov bx,offset CaratteriEsaxlat
Il parametro della XLAT è sempre [BX] che va infatti caricato opportunamente. Anche se non viene indicato [BX], il comportamento di XLAT non cambia.
mov ah,02hmov dl,alint 21hloop Ripeti
Notare anche che se vogliamo l’indirizzo di una variabile dobbiamo usare la direttiva offset.
ret
CaratteriEsa db '0123456789ABCDEF'
endp ; ScriviNumero
Architettura dei calcolatori a.a. 2007/2008
Esempio 5 – Le stringhe
_TEXT segmentassume cs:_TEXT, ds:_TEXT, ss:_TEXTorg 100h
; Visualizzo Stringa2mov cl,Stringa2mov si,offset Stringa2 + 1mov ah,02h
Inizio: ; Copio Stringa2 in Stringa1xor ch,chmov cl,Stringa2mov Stringa1,clmov si,offset Stringa2 + 1
Stampa2:lodsbmov dl,alint 21hloop Stampa2g
mov di,offset Stringa1 + 1rep movsb
; Visualizzo Stringa1mov cl Stringa1
p p
; Termino il programmaFine: ret
; Dati del programmamov cl,Stringa1mov si,offset Stringa1 + 1mov ah,02h
Stampa: lodsbmov dl,ali t 21h
; Dati del programmaStringa1 db ?
db 255 dup (?)Stringa2 db 16,'Prova di stringa'
db 255-16 dup (?)int 21hloop Stampa
; Riempio Stringa2 di ‘*’mov al,'*'
_TEXT ends
end Inizio
mov cl,100mov Stringa2,clmov di,offset Stringa2 + 1
rep stosb
Architettura dei calcolatori a.a. 2007/2008
Esempio 5
• In questo esempio vengono utilizzate le istruzioni per le stringhe. • Per comodità si sono definite le stringhe al modo del PASCAL, ovvero
b t i i i l h ti l l h d ll t i icon un byte iniziale che contiene la lunghezza della stringa e uno spazio di 255 byte. Notare che è stata usata la direttiva dup per allocare lo spazio necessario. La sintassi è:[numero di ripetizioni] dup ( dato da ripetere )
• Quindi Stringa1 è l’indirizzo di una struttura di 256 byte, in cui il primo indica il numero di caratteri effettivamente presenti nel buffer di 255indica il numero di caratteri effettivamente presenti nel buffer di 255 caratteri successivo.
• Stringa2 è analoga, ma viene inizializzata con un testo.• Il programma copia Stringa2 in Stringa1, ne visualizza il contenuto,
riempie Stringa2 di asterischi e mostra il risultato.• Provate a modificare il programma in modo che la parte che esegue la• Provate a modificare il programma in modo che la parte che esegue la
visualizzazione sia una procedura da invocare con una CALL.
Architettura dei calcolatori a.a. 2007/2008
Esempio 6 – Uso di più segmenti
_TEXT segment para public 'CODE'assume cs:_TEXT, ds:_DATA, ss:_STACK
; inizializiamo DS in modo che punti al
; Visualizza stringamov ah,09hmov dx,offset str_ACapoint 21h
; segmento datiInizio: mov ax,_DATA
mov ds,ax; Visualizza stringa
mov ah,09h
; Chiamo la funzione DOS per terminare; i programmi
mov ah,4chmov al,00h,
mov dx,offset str_Messaggio1int 21h
; Input di un carattere (viene ritornato ; in al)
mov ah 01h
,int 21h
_TEXT ends
_DATA segment para public 'DATA'str Messaggio1 db 'Digita un carattere:mov ah,01h
int 21h; Memorizzo il carattere
mov Carattere,al; Visualizza stringhe
str Messaggio1 db Digita un carattere: ','$'
str_ACapo db 0dh,0ah,'$'str_Messaggio2 db 'Hai premuto il
carattere: ','$'mov ah,09hmov dx,offset str_ACapoint 21hmov ah,09hmov dx,offset str Messaggio2
Carattere db ?_DATA ends
STACK segment para stack 'STACK'ggint 21h
; Output del carattere premutomov ah,02hmov dl,Carattereint 21h
_ g p; Dimensione dello stack
dw 32 dup (?)_STACK ends
end Inizioint 21h end Inizio
Architettura dei calcolatori a.a. 2007/2008
Esempio 6
• In questo esempio vediamo un programma con più segmenti (che quindi diventerà un EXE e non un COM. N ’è ll di ti l t t l h i li it• Non c’è nulla di particolarmente strano nel programma che si limita a visualizzare stringhe e caratteri con le funzioni del DOS. Attenzione che la funzione per stampare stringhe in DOS vuole un carattere ‘$’ alla fine della stringa.
• Per dichiarare un segmento di stack è necessario riservare un po’ di spazio a differenza di prima e quindi si sono riservate 32 word.spazio a differenza di prima e quindi si sono riservate 32 word.