Sei sulla pagina 1di 6

TRASFERIMENTO DATI

L’operatore MOV copia un dato da una posizione all’altra.


FORMA: MOV destinazione, sorgente
NOTE:
• l’operando sorgente non viene modificato.
• l’operando sorgente può essere un registro, una locazione in memoria o una costante.
• l’operando di destinazione può essere un registro o una locazione in memoria.

COMBINAZIONI NON PERMESSE e RESTRIZIONI:


• gli operandi devono avere lo stesso numero di bit;
• IP non deve mai comparire;
• CS non può essere destinazione;
• i due operandi non possono essere due valori in memoria (bisogna obbligatoriamente
passare da un registro).

MODI DI INDIRIZZAMENTO

1. REGISTER (mediante registro)


L’operando1 è un registro specificato nell’istruzione.
Es. MOV BX, AX (sposta in BX il contenuto di AX)

2. IMMEDIATE (mediante immediato)


L’operando è una costante espressamente indicata.
Es. MOV BH, 07H (2) (sposta 07H in BH)

3. DIRECT (indirizzamento diretto)


L’operando si trova in una locazione di memoria.
Es(1). MOV AX, [0100]
Spostiamo in AX il contenuto di DX+0100, DX è il segmento di default
Es(2). MOV AX, TABLE
TABLE è una variabile che indica tale locazione di memoria.
Es(3). MOV AX, TABLE+1
Il processore prende TABLE, ricava l’offset in cui quest’ultima variabile si trova in memoria e gli
somma 1. Il risultato è l’offset di ciò che si vuole spostare in AX.
Es(4). MOV AX, TABLE[2]
Il processore prende TABLE, ricava l’offset in cui quest’ultima variabile si trova in memoria e gli
somma 2. Il risultato è l’offset di ciò che si vuole spostare in AX.

4. SEGMENT OVERRIDE
Il registro di default è sempre DS, ma utilizzando l’operando “ : ” possiamo utilizzare un
segmento diverso come riferimento per il calcolo degli indirizzi.
Es. MOV AX, ES:VAR2 (prendi ciò che c’è all’indirizzo di base ES e offset VAR2 e metti in AX)
VAR2 si trova in un segmento il cui inizio è memorizzato nel registro AS (non più DS).

1 L’operando può generalmente essere un registro, oppure una costante presente nell’espressione, una quantità in memoria o infine

un valore di I/O.
2 BH e 07H sono quantità a 8 bit.
5. REGISTER INDIRECT (indirizzamento indiretto mediante registro base o registro indice)
L’offset è contenuto in un registro base (ad es. BX, BP) oppure in un registro indice (ad es. DI, SI).
Es. MOV AX, [BX]
L’operando viene preso nella cella di memoria il cui offset si trova in BX.
NOTA: se non indicato diversamente, i registri base ai quali va aggiunto l’offset sono DS (per BX,
SI, DI) e SS (per BP).

6. BASE RELATIVE (indirizzamento indiretto mediante registro base, con tanto di


displacement)
L’offset dell’operando è ottenuto sommando il contenuto di BX (o BP) a un displacement
(nell’esempio è 4); per le regole sui registri base vedi il punto 5.
Es. MOV AX, [BX+4]

7. DIRECT INDEXED
L’operando è in memoria, ma l’offset è la somma di un offset in una variabile più un displacement.
Es. MOV AX, TABLE[DI]
Su usa come offset quello di TABLE sommato al contenuto di DI.

8. BASE INDEXED (indirizzamento indiretto mediante registro base e registro indice)


L’offset è costituito dalla somma di:
• contenuto di BX o BP (registro base);
• contenuto di SI o DI (registro indice);
• un campo opzionale.
ES. MOV AX, TAB[BX][DI]
Offset: offset di TAB + contenuto di BX + contenuto di DI.

DEFINIZIONE DI COSTANTI

In fase di assemblaggio del programma, EQU permette di definire simboli che rappresentano
valori specifici.
FORMATO: nome EQU espressione
Es. X EQU 1024

ISTRUZIONI ARITMETICHE E OPERAZIONI ELEMENTARI

Operano su numeri interi binari senza (o con segno) a 8 bit o a 16 bit. Il processore 8086 supporta
anche il formato BCD.

ADD formato: ADD dest, sorg


SUB formato: SUB dest, sorg
Quel che accade è che si effettua dest + (o -) sorg e il risultato viene messo in dest (mentre sorg
rimane immutato).
RESTRIZIONI:
• non è lecito specificare come operandi due locazioni di memoria (al massimo uno): perciò,
se proprio dobbiamo sommare due valori in memoria, dobbiamo obbligatoriamente
passare attraverso un registro;
•gli operandi devono essere dello stesso tipo e della stessa dimensione (o entrambi byte o
entrambi word).
NOTA:
• il flag CF assume il significato di bit di riporto.

ADC e SBB effettuano la somma (e la sottrazione) a 32 bit riconducendo il tutto a due somme
(sottrazioni) su 16 bit (bisogna però tenere conto del riporto o del prestito).

INC e DEC permettono di incrementare o decrementare un operando. Queste due istruzioni


possono essere integrate con l’istruzione NEG (che cambia il segno dell’operando agendo a
complemento a 2).

MUL (interi senza segno) e IMUL (interi con segno) sono due comandi che prevedono un unico
operando esplicito. L’altro operando è implicito nell’istruzione stessa, perché si utilizza
automaticamente un registro AX come secondo operando.
L’operando può essere un registro o una locazione di memoria (non una costante!), mentre il tipo
può essere byte o word:
• se l’operando è di tipo byte allora l’istruzione intercorre tra operando e AL e il risultato
viene copiato in AX.
• se l’operando è di 16 bit l’istruzione moltiplica operando e AX e il risultato lo si mette in AX
(per i bit più significativi, MSB) e DX (per i bit meno significativi, LSB)

In Assembler la divisione è implementata con le parole di comando DIV (senza segno) e IDIV
(con segno), le quali sono analoghe a MUL e IMUL per quanto riguarda il formato (un unico
operando esplicito e un operando implicito; l’operando può essere un registro o una locazione di
memoria ma non può essere un immediato).
Operando byte: processore divide AX per l’operando. Quoziente in AL e resto in AH.
Operando word: processore divide DX:AX e l’operando. Quoziente in AX e il resto in DX.
NOTA: l’operando sorgente non può essere una costante.

ISTRUZIONI LOGICHE E DI SCORRIMENTO

Esse sono utilizzate, in particolare, per forzare il valore di uno o più bit all’interno della parola.
Es. forziamo a 1 il quarto bit di AX
OR AX, 1000b
In alcuni casi (laddove si vogliano programmare i dispositivi periferici che vivono attorno al
processore) può essere necessario dover modificare i registri specifici un bit alla volta. Operandi:
AND
OR formato: dest, sorg
XOR

Ogni operazione logica viene effettuata fra dest e sorg e il risultato viene posto in dest.

Istruzione NOT (ha un solo operando)  effettua il complemento bit a bit. Non è equivalente a
NEG: NEG cambia aritmeticamente il segno, NOT inverte i bit logicamente.

SHL e SHR hanno il formato:


SH¶ operando, contatore ¶ = L (sinistra), R (destra)
Il contatore specifica di quante posizioni dev’essere effettuato lo scorrimento. Lo scorrimento
lascia dietro di sé degli zeri. L’ultimo bit uscita viene inserito nel CF.
NOTA: per le proprietà dei numeri binari l’istruzione SHL BX, 1 moltiplica BX per 2.

SAL e SAR hanno lo stesso formato di SHL e SHR, solo che i vuoti creati dallo spostamento sono
riempiti di bit pari al valore del bit più significativo. Ancora una volta l’ultimo bit in uscita viene
inserito nel CF.
Es. operando (CF = --) (0 shift)
ooperand (CF = o) (1 shift)
oooperan (CF = d) (2 shift)
oooopera (CF = n) (3 shift)

ROR e ROL hanno la stessa forma e scopo delle ultime istruzioni viste (SHL, SHR, SAL, SAR) ma
hanno caratteristica di ricorsività. L’ultimo bit in uscita viene copiato in CF e rientra dalla parte
opposta.

CONTROLLO DEL FLUSSO

Le istruzioni di un programma sono normalmente eseguite sequenzialmente, ma può esserci


bisogno di salti e cicli.

Salti incondizionati
Un salto incondizionato è un salto eseguito a prescindere, senza nessuna condizione.

L’istruzione JMP (jump) ha un formato relativamente scontato, ovvero:


JMP destinazione
Esistono due tipi di salti: diretti e indiretti. Nel primo caso (salto diretto) all’interno dell’operando
può esserci l’indirizzo stesso dell’istruzione cui saltare (o le informazioni necessarie per
calcolarlo); spesso come operando usiamo un’etichetta. Nel salto indiretto l’operando contiene
l’indicazione di quale sia un puntatore che contiene a sua volta l’indirizzo dell’istruzione cui
saltare: c’è, insomma, un passaggio in più rispetto al salto diretto.
es. diretto JMP AX (salta all’indirizzo indicato dal registro AX)
indiretto  JMP [AX] (salta all’indirizzo contenuto nella cella di memoria che si trova
all’indirizzo indicato dal registro AX) .
I salti indiretti possono essere utilizzati per implementare costrutti di tipo CASE.
ad es. JMP TAB[BX], al variare di BX saltiamo in punti diversi.

Salti condizionati
Prima verificano se è
verificata una certa
condizione e poi fanno il
salto.
Formato:
JXXX label

(dove XXX è un suffisso che specifica la condizione, v. tabella)


L’istruzione JXXX dev’essere sempre preceduta dall’istruzione CMP (compare)  formato:
CMP destinazione, sorgente
Questa compara i due valori (sottraendoli) e sulla base del risultato della sottrazione setta i flag
che saranno necessari per effettuare i confronti.
NOTA: CMP funziona tra
• due registri,
• una locazione di memoria e un registro,
• un registro e un valore immediato (non il viceversa),
• fra una locazione di memoria e un immediato (non il viceversa).
Gli operandi del confronto devono inoltre avere la stessa lunghezza e non è ammesso il confronto
fra due locazioni di memoria.

I flag impostati da CMP vengono testati per effettuare il salto condizionato.

CICLI

LOOP ha un formato del tipo


LOOP label
e quindi viene esclusivamente esplicitata l’etichetta (cioè il nome simbolico, la label) dell’istruzione
cui si vuole saltare.
Quando il processore incontra LOOP:
• decrementa CX di una unità,
• controlla e se è diverso da 0
 se sì  salta all’istruzione con etichetta label;
 se no  va avanti.
In questo modo CX può essere utilizzato come contatore, laddove si voglia fare un ciclo che
dev’essere ripetuto un numero noto a priori di volte.

PROCEDURE

Attraverso le procedure è possibile scrivere una volta quelle parti di codice che vengono eseguite
ripetutamente all’interno di un programma.
Come definiamo una procedura? Come isoliamo una procedura nel codice?

Usiamo due direttive: PROC e ENDP. Formato:


nome PROC tipo3
corpo della procedura
nome ENDP

Chiamata di una procedura


L’istruzione CALL trasferisce il controllo del flusso di esecuzione del programma ad una
procedura specificata. Formato:
CALL target
Alla fine della procedura bisogna tornare indietro, al programma chiamante: per questo viene
salvato nello stack l’indirizzo di ritorno.

3 Opzionale: NEAR = all’interno dello stesso segmento di codice, FAR = tra segmenti diversi, per cui bisogna salvare CS e offset di

ritorno
Ritorno da una procedura
L’istruzione RET permette di restituire il controllo alla procedura chiamante, una volta che la
procedura chiama ha terminato l’esecuzione. Si estrae perciò dallo stack l’indirizzo di ritorno e si
ripassa il controllo al chiamante.
Formato: RET.