Assembly — il linguaggio mnemonico del processore
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.
1011 0000 0100 1101
1000 1001 1100 0011
1010 0001 0110 1010MOV AL, 4Dh
MOV BX, AX
MOV AX, [6Ah]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à.
Struttura di un’istruzione Assembly x86
Un’istruzione Assembly x86 segue una sintassi precisa e può contenere fino a quattro elementi:
JMP loop_start) e chiamate.MOV destinazione, sorgente. Non è possibile avere entrambi gli operandi in memoria nello stesso ciclo — almeno uno deve essere un registro.I registri principali dell’8086
Prima di analizzare i metodi di indirizzamento è essenziale conoscere i registri disponibili — sono loro i protagonisti di quasi ogni istruzione.
| Registro | Nome esteso | Dimensione | Uso tipico |
|---|---|---|---|
AX / AH / AL | Accumulator | 16 / 8 / 8 bit | Operazioni aritmetiche, risultati I/O |
BX / BH / BL | Base | 16 / 8 / 8 bit | Indirizzamento base per accesso a memoria |
CX / CH / CL | Counter | 16 / 8 / 8 bit | Contatore per cicli (LOOP), shift |
DX / DH / DL | Data | 16 / 8 / 8 bit | Dati, coppia con AX per MUL/DIV a 32 bit |
SI | Source Index | 16 bit | Puntatore sorgente — indirizzamento indiretto |
DI | Destination Index | 16 bit | Puntatore destinazione — indirizzamento indiretto |
BP | Base Pointer | 16 bit | Accesso ai dati nello stack frame (parametri funzione) |
SP | Stack Pointer | 16 bit | Punta alla cima dello stack — gestito automaticamente da PUSH/POP |
I tre tipi fondamentali di indirizzamento
Il metodo di indirizzamento specifica dove si trova il dato che l’istruzione deve elaborare. Ogni modalità offre un diverso compromesso tra velocità, flessibilità e complessità.
Indirizzamento Immediato
Il dato è incorporato direttamente nell’istruzione. Non serve alcun accesso aggiuntivo a memoria o registri — il valore è lì, pronto in un solo passo.
MOV AL, 4Dh ; scrivi il valore 0x4D (77 decimale) nel registro AL
MOV BX, 1234h ; scrivi il valore 0x1234 nel registro BX a 16 bit
MOV CX, 10 ; scrivi il valore decimale 10 nel registro CXB0 identifica “MOV AL, imm8” e il byte successivo 4D è il dato immediato4Dh viene scritto direttamente in AL — nessun accesso aggiuntivo a memoriaIndirizzamento Diretto
Da registro a registro
Entrambi gli operandi sono registri — la CPU opera interamente al suo interno, senza accedere alla RAM. La velocità è massima.
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 AXBX — operazione interna, nessun bus da attraversareBX viene copiato in AX. Il contenuto di BX rimane invariato — MOV è una copia, non uno spostamentoDa registro a memoria e viceversa
Un operando è un registro, l’altro è una locazione di memoria specificata direttamente dall’offset nell’istruzione, indicato tra parentesi quadre. La CPU deve calcolare l’indirizzo effettivo e poi accedere alla RAM.
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 0200hbase address (DS) + offset (6Ah) = indirizzo fisicoAXIndirizzo effettivo = 1000h × 10h + 6Ah = 1006Ah
AX ← Mem[1006Ah]
DS (Data Segment). La formula esatta è: EA = DS × 10h + offset.Indirizzamento Indiretto
Nell’indirizzamento indiretto, l’istruzione non contiene il dato né il suo indirizzo diretto — contiene dove trovare l’indirizzo. Il dato finale è sempre in memoria e mai in un registro o nell’istruzione stessa.
Tramite registro (register indirect)
L’offset non è scritto nell’istruzione — è contenuto in un registro indice o puntatore (SI, DI, BX, BP). Le parentesi quadre intorno al registro indicano “usa il contenuto come indirizzo”.
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 BXbase address (DS) + contenuto di SI = indirizzo fisicoAXIndirizzo effettivo = 10000h + 0050h = 10050h
AX ← Mem[10050h]
SI a runtime (es. INC SI), si può scorrere un array in memoria senza modificare l’istruzione stessa — è la base di cicli e strutture dati dinamiche in Assembly.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.
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]SI = 0050hEA = DS×10h + SI + 03h = 10000h + 0050h + 03h = 10053hAXEA = 10000h + 0050h + 03h = 10053h
BX puntato all’inizio di una struttura in memoria, il displacement è l’offset del campo all’interno della struttura — es. se il campo “età” è 2 byte dopo l’inizio: MOV AL, 02h[BX]. Equivalente a struct->field in C.Tramite registri base e indice
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.
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)EA = DS×10h + BX + DIAX viene scritto nella RAM all’indirizzo calcolatoEA = 20000h + 0100h + 0004h = 20104h
Mem[20104h] ← AX
Tramite registri base, indice e displacement
La modalità più completa: si sommano registro base + registro indice + displacement fisso. È la forma più potente di indirizzamento indiretto — ideale per array di strutture dove base = inizio array, indice = elemento corrente, displacement = campo della struttura.
MOV AX, 02h[BX][SI] ; legge da Mem[DS + BX + SI + 2] → AX
MOV 04h[BP][DI], CX ; scrive CX in Mem[SS + BP + DI + 4]BX (base) e SI (indice)EA = DS×10h + BX + SI + 02hAXEA = 30000h + 0100h + 0006h + 02h = 30108h
; BX = indirizzo base dell'array
; SI = indice × 10 (elemento corrente)
; displacement 06h = offset del campo "voto"
MOV AL, 06h[BX][SI] ; legge il voto dello studente SI-esimo
INC SI ; prossimo byte — scorrimento arrayQuadro comparativo — tutti i metodi
| Metodo | Sintassi esempio | Formula EA | Passi | Uso tipico |
|---|---|---|---|---|
| Immediato | MOV AL, 4Dh | — (dato nell’istruzione) | 1 | Costanti, inizializzazioni |
| Diretto reg→reg | MOV AX, BX | — (solo registri) | 1 | Copia rapida tra registri |
| Diretto reg↔mem | MOV AX, [6Ah] | DS×10h + offset | 2 | Variabili globali a indirizzo fisso |
| Indiretto via reg | MOV AX, [SI] | DS×10h + SI | 2 | Puntatori, scorrimento array |
| Indiretto + disp | MOV AX, 03h[SI] | DS×10h + SI + disp | 3 | Accesso a campi di strutture |
| Base + indice | MOV AX, [BX][DI] | DS×10h + BX + DI | 2 | Array bidimensionali, matrici |
| Base + indice + disp | MOV AX, 02h[BX][SI] | DS×10h + BX + SI + disp | 3 | Array di strutture — massima flessibilità |
Riepilogo
- L’Assembly è la rappresentazione simbolica del codice macchina — ogni mnemonico corrisponde esattamente a un opcode binario, senza livelli di astrazione intermedi
- Ogni istruzione x86 è composta da: label opzionale, opcode obbligatorio, operando destinazione e operando sorgente — in questo ordine fisso
- Nell’indirizzamento immediato il dato è nell’istruzione stessa — un solo passo, massima velocità
- Nell’indirizzamento diretto l’istruzione specifica il registro o l’indirizzo di memoria dove si trova il dato — uno o due passi
- Nell’indirizzamento indiretto l’istruzione indica dove trovare l’indirizzo — il dato finale è sempre in memoria
- La formula dell’indirizzo effettivo è sempre: EA = DS×10h + base + index + displacement (con i componenti presenti nella modalità usata)
- I registri indice (
SI,DI) e base (BX,BP) sono i protagonisti dell’indirizzamento indiretto — cambiarli a runtime permette di navigare strutture dati dinamicamente - La modalità base + indice + displacement è la più potente: ideale per array di strutture dove base = inizio array, indice = elemento, displacement = campo della struttura