Sistemi e Reti - Assembly 8086: Modi di Indirizzamento | Lezione 06
Sistemi e Reti · Anno 3 · Modulo 2 · Lezione 06
✍ Autore: profgiagnotti · Materia: Sistemi e Reti

Assembly 8086: Struttura Istruzione e Modi di Indirizzamento

Dal codice macchina ai mnemonici: come la CPU trova i dati — immediato, diretto e tutte le varianti indirette fino a base+indice+displacement. La formula EA che devi saper calcolare.

⏱ 60 min 📚 Anno 3 🧠 Assembly x86 💻 Indirizzamento
// OBIETTIVI DI APPRENDIMENTO
✓Comprendere la struttura di un'istruzione Assembly x86: label, opcode, operandi e corrispondenza 1:1 con il codice macchina
✓Distinguere i tre tipi fondamentali di indirizzamento: immediato, diretto e indiretto, con numero di passi esecutivi
✓Analizzare le varianti dell'indirizzamento indiretto: tramite registro, con displacement, con base e indice
✓Calcolare l'indirizzo effettivo EA con la formula DS×10h + base + index + displacement e applicarla a SI, DI, BX, BP
✓Scegliere il metodo di indirizzamento appropriato per array, strutture e matrici — base+indice+displacement per array di struct

1. Assembly — il linguaggio mnemonico del processore

📌 Definizione da ricordare

Assembly è la rappresentazione simbolica 1:1 del codice macchina: ogni mnemonico leggibile corrisponde esattamente a un opcode binario che la CPU esegue direttamente, senza livelli di astrazione.

Il codice macchina — le sequenze di bit che la CPU esegue direttamente — è incomprensibile all'uomo. L'Assembly è la sua rappresentazione simbolica: ogni istruzione binaria corrisponde esattamente a un mnemonico leggibile. Non c'è astrazione: Assembly e codice macchina sono equivalenti uno a uno.

01 · SOLO CPU

Codice macchina

1011 0000 0100 1101
1000 1001 1100 0011
1010 0001 0110 1010
Sequenze binarie dirette.

02 · UMANO

Assembly

MOV AL, 4Dh
MOV BX, AX
MOV AX, [6Ah]
Mnemonici leggibili, stesso controllo.

CODICE MACCHINA 1011 0000 0100... opcode + dati assembler ASSEMBLY MOV AL, 4Dh mnemonico leggibile CPU 8086 Esecuzione diretta Controllo hardware totale

Ogni riga Assembly viene tradotta dall'assemblatore (assembler) nel corrispondente opcode binario. Il vantaggio è fondamentale: si scrive in simboli mnemonici e si ottiene il controllo assoluto sull'hardware — senza rinunciare alla leggibilità.

💬 Tip del docente

Quando vedi MOV pensa sempre "copia, non sposta": la sorgente resta invariata. È la domanda trabocchetto classica in verifica. Se ti chiedono cosa succede a BX dopo MOV AX,BX, rispondi: BX resta uguale, AX diventa uguale a BX.

2. Struttura di un'istruzione Assembly x86

Un'istruzione Assembly x86 segue una sintassi precisa e può contenere fino a quattro elementi:

loop_start:LABEL (opzionale) MOVOPCODE (obbl.) AX,DESTINAZIONE BXSORGENTE Sintassi Intel: destinazione prima, sorgente dopo — AX ← BX — ordine fisso!
  • LABEL (opzionale): nome simbolico dell'indirizzo di questa istruzione in memoria. Usata per salti (JMP loop_start) e chiamate.
  • OPCODE (obbligatorio): il mnemonico dell'operazione — MOV, ADD, SUB, JMP, CALL... corrisponde direttamente al byte opcode binario.
  • Operando destinazione: dove va il risultato.
  • Operando sorgente: da dove viene il dato.
🎯 Esempio in classe

In loop_start: MOV AX, BX — loop_start è la label per saltarci, MOV è l'opcode obbligatorio, AX è la destinazione, BX la sorgente. Se inverti AX e BX inverti il flusso dei dati!

⚠️ Errore comune

Confondere la sintassi Intel con AT&T: in Intel (8086) è MOV dest, sorg. In AT&T (usata da GAS/Linux) è invertita mov sorg, dest. In EMU8086 e in questa materia usiamo SEMPRE Intel.

3. Indirizzamento immediato

📌 Definizione da ricordare

Indirizzamento immediato: il dato è scritto direttamente nell'istruzione stessa — nessun accesso a memoria o registro sorgente. 1 passo, massima velocità.

Nell'indirizzamento immediato il dato è parte dell'istruzione — subito dopo l'opcode. La CPU non deve cercarlo altrove.

ASM 8086 · IMMEDIATO
MOV AL, 4Dh ; carica il valore immediato 4Dh (77 decimale) in AL MOV BX, 1234h ; costante esadecimale a 16 bit MOV CX, 10 ; costante decimale
// ISTRUZIONE: B0 4D -> MOV AL, 4Dh [2 byte] B0 OPCODE 4D DATO IMM. Passo 1: opcode B0 = MOV AL, imm8Passo 2: byte successivo 4D → scritto in ALPrima: AL=?? → Dopo: AL=4Dh · Nessun accesso RAM
✅ Quando usarlo

Ideale per inizializzare registri con valori costanti noti a tempo di compilazione: contatori, maschere di bit, valori di configurazione. È la modalità più veloce perché la CPU non deve accedere alla RAM.

4. Indirizzamento diretto

Entrambi gli operandi sono registri oppure un operando è una locazione di memoria specificata direttamente dall'offset nell'istruzione, indicato tra parentesi quadre.

Da registro a registro

ASM · DIRETTO REG → REG
MOV AX, BX ; copia il contenuto di BX in AX (AX ← BX) MOV CX, DX ; copia DX in CX MOV AL, BH ; copia il byte alto di BX nel byte basso di AX
💬 Tip del docente

Diretto reg→reg è tutto interno alla CPU: nessuna attesa di RAM, 1 solo passo. Per la verifica ricorda: dopo MOV AX,BX — AX = valore vecchio di BX, BX resta identico.

Da registro a memoria e viceversa

ASM · DIRETTO REG ↔ MEM
MOV AX, [6Ah] ; legge dalla memoria all'offset 6Ah → AX MOV [6Ah], AX ; scrive AX in memoria all'offset 6Ah MOV [0200h], BX ; scrive BX in memoria all'offset 0200h
MOV AX, [6Ah] — 2 passi — EA = DS × 10h + offset Passo 1: DS=1000h · offset=6Ah → EA = 1000h×10h+6Ah = 1006Ah (20 bit fisico) Passo 2: AX ← Mem[1006Ah] — accesso RAM tramite bus indirizzi/dati 8086 Segmentazione20 bit = Seg×16+Off
⚠️ Da ricordare — segmentazione 8086

Nell'8086 l'indirizzo fisico a 20 bit si calcola sempre come segmento × 16 + offset. Per gli accessi ai dati il registro di segmento è DS (Data Segment). Formula: EA = DS × 10h + offset. DS×10h significa DS shiftato di 4 bit a sinistra (×16 decimale).

5. Indirizzamento indiretto

📌 Definizione da ricordare

Indirizzamento indiretto: l'istruzione non contiene il dato né il suo indirizzo diretto — contiene dove trovare l'indirizzo (un registro). Il dato finale è sempre in memoria.

Il meccanismo permette di cambiare dinamicamente a runtime l'indirizzo puntato, semplicemente modificando il registro indice — base di array, stringhe e strutture dati dinamiche.

Tramite registro (register indirect)

ASM · INDIRETTO VIA REGISTRO
MOV AX, [SI] ; legge dalla memoria all'indirizzo contenuto in SI → AX MOV AX, [DI] ; legge dalla memoria all'indirizzo contenuto in DI → AX MOV [BX], CX ; scrive CX in memoria all'indirizzo contenuto in BX
SI = 0050hregistro indice + DS = 1000hsegmento dati = EA = 10050h10000h+0050h Mem[10050h]→ AX INC SI → scorri array senza toccare il codice: MOV AX,[SI] resta uguale, cambia solo SI!
🎯 Potenza dell'indirizzamento indiretto

Modificando SI a runtime (INC SI), puoi scorrere un array in memoria senza modificare l'istruzione stessa — è la base di cicli e strutture dati dinamiche in Assembly. In C equivale a *ptr dove incrementi il puntatore.

Tramite registro e displacement

Al contenuto del registro indice si aggiunge un ulteriore displacement (spiazzamento fisso scritto nell'istruzione) per raggiungere una locazione specifica rispetto all'indirizzo base puntato dal registro.

ASM · INDIRETTO + DISPLACEMENT
MOV AX, 03h[SI] ; legge da Mem[DS + SI + 3] → AX MOV BX, 10h[DI] ; legge da Mem[DS + DI + 16] → BX MOV [02h][BX], AL ; scrive AL in Mem[DS + BX + 2] ; Esempio struct: offset del campo ; Se struct inizia a BX e campo "età" a +2: MOV AL, 02h[BX] ; AL = età
EA = DS×10h + SI + displacement Es. SI=0050h DS=1000h disp=03h → EA=10000h+0050h+03h=10053h → AX←Mem[10053h] Uso tipico: accesso a campi di struct — BX base struct, disp offset campo → struct->field in C

6. Base + Indice e Base + Indice + Displacement

📌 Definizione da ricordare

Base + Indice: EA = DS×10h + BX/BP + SI/DI. Base+Indice+Displacement aggiunge un offset fisso: massima flessibilità per array di strutture — base = inizio array, indice = elemento, displacement = campo.

L'indirizzo effettivo si calcola sommando il contenuto di un registro base (BX o BP) e di un registro indice (SI o DI). Permette di navigare strutture dati bidimensionali — il base punta alla struttura, l'indice al singolo elemento.

ASM · BASE + INDICE
MOV AX, [BX][SI] ; legge da Mem[DS + BX + SI] → AX MOV [BX][DI], AX ; scrive AX in Mem[DS + BX + DI] MOV CX, [BP][SI] ; legge da Mem[SS + BP + SI] → CX (BP usa SS per default!) ; Array di strutture - esempio didattico ; BX = base array studenti, SI = indice*dimensione, 06h = offset campo voto MOV BX, OFFSET studenti MOV SI, 0 MOV AL, 06h[BX][SI] ; legge il voto dello studente SI-esimo INC SI ; prossimo elemento
⚠️ Nota importante su BP

Quando usi BP come base, il segmento di default non è DS ma SS (Stack Segment): MOV AX, [BP][SI] usa SS:BP+SI. È pensato per accedere a parametri e variabili locali sullo stack — fondamentale per procedure e chiamate CALL.

MODALITÀ PIÙ POTENTE: BASE + INDICE + DISPLACEMENT — Array di struct BX=0200hBASE = inizio array SI=0014hINDICE = elem·dim DISP=06hoffset campo voto EA=DS+0200h+0014h+06h→ Mem[EA] → AL Memoria vista come array di record: [ ID 2B | nome 8B | voto 1B ] [ ID 2B | nome 8B | voto 1B ] [ ID 2B | nome 8B | voto ... ← BX punta qui ← SI sposta di record in record → +06h arriva al byte voto →
🎯 Esempio in classe — registro studenti

Hai un array di 30 studenti, ogni studente occupa 10 byte (2 byte ID + 8 byte nome + 1 byte voto? semplifichiamo 10). BX punta all'inizio array, SI scorre di 10 in 10 per elemento, 06h è l'offset del campo voto. MOV AL, 06h[BX][SI] legge il voto corrente — poi ADD SI,10 per studente successivo. È esattamente studenti[i].voto in C!

7. Quadro comparativo — tutti i metodi

Tabella riassuntiva che devi saper riprodurre in verifica — metodi, formula EA, passi e uso tipico.

MetodoSintassi esempioFormula EAPassiUso tipico
ImmediatoMOV AL, 4Dh— (dato nell'istruzione)1Costanti, inizializzazioni
Diretto reg→regMOV AX, BX— (solo registri)1Copia rapida tra registri
Diretto reg↔memMOV AX, [6Ah]DS×10h + offset2Variabili globali a indirizzo fisso
Indiretto via regMOV AX, [SI]DS×10h + SI2Puntatori, scorrimento array
Indiretto + dispMOV AX, 03h[SI]DS×10h + SI + disp3Accesso a campi di strutture
Base + indiceMOV AX, [BX][DI]DS×10h + BX + DI2Array bidimensionali, matrici
Base + ind + dispMOV AX, 02h[BX][SI]DS×10h + BX + SI + disp3Array di strutture — max flessibilità
💬 Tip del docente — come ricordarlo all'interrogazione

Conta le parentesi: immediato = nessun [] , diretto reg→reg = nessun [] , diretto mem = [numero fisso], indiretto = [registro]. Quando vedi due registri tra [] è base+indice, se c'è anche un numero è base+indice+displacement. EA sempre: segmento×16 + tutto quello che è dentro le quadre sommato.

✓Assembly = codice macchina simbolico: ogni mnemonico corrisponde 1:1 a un opcode binario, controllo hardware totale ma leggibile.
✓Struttura istruzione: label opzionale + opcode obbligatorio + destinazione + sorgente — ordine Intel fisso dest,sorg.
✓Immediato: dato nell'istruzione, 1 passo, massima velocità per costanti.
✓Diretto: reg→reg (1 passo) o reg↔mem con offset fisso [6Ah] → EA=DS×10h+offset (2 passi).
✓Indiretto: [SI]/[DI]/[BX]/[BP] — EA dinamico, INC SI scorri array senza modificare codice. +disp per campi struct.
✓Base+Indice+Displacement: la più potente — BX base array, SI/DI indice elemento, disp offset campo — ideale per array di struct: studenti[i].voto.
✓Formula universale EA = DS×10h + base + index + displacement — usa solo i componenti presenti. BP → usa SS di default.

📚 Prossimo passo — ISA: Instruction Set Architecture dell'8086

Ora che sai DOVE la CPU prende i dati, vedrai COSA può fare con quei dati: tutte le istruzioni dell'8086, i flag e gli interrupt. Fondamentale per scrivere i primi programmi in EMU8086.