Sistemi e Reti - Modulo 2 Lezione 03 - Algoritmi e Linguaggi di Programmazione | Prof. Giagnotti
Sistemi e Reti · Anno 3 · Modulo 2 · Lezione 03
✍ Autore: profgiagnotti · Materia: Sistemi e Reti

Algoritmi e Linguaggi di Programmazione – dal problema al codice macchina

Cosa significa davvero scrivere un programma? Partiamo dalla logica pura dell'algoritmo fino al bit eseguito dalla CPU, per capire perché l'Assembly 8086 è il ponte perfetto tra software e hardware.

⏱ 50 min 📚 Anno 3 🧠 Algoritmi 💻 Linguaggi
// OBIETTIVI DI APPRENDIMENTO
✓Distinguere con precisione algoritmo (logica astratta) e programma (implementazione eseguibile su architettura specifica).
✓Classificare i linguaggi per livello di astrazione: alto livello, basso livello e linguaggio macchina.
✓Spiegare la corrispondenza 1:1 tra mnemonico Assembly e opcode binario definito dall'ISA 8086.
✓Valutare trade-off tra portabilità, controllo hardware e performance nei diversi livelli linguistici.
✓Collegare la necessità di conoscere registri, dimensioni e indirizzamento alla programmazione in Assembly 8086.

1. Algoritmo e programma — due concetti distinti

Prima di scrivere qualsiasi codice è fondamentale distinguere due concetti che spesso vengono confusi dagli studenti al primo approccio.

01 · Logica pura

Algoritmo

Una sequenza finita, non ambigua e ordinata di istruzioni per risolvere un problema — indipendente dal linguaggio e dall'hardware. Descrive il cosa fare.

02 · Implementazione

Programma

L'implementazione dell'algoritmo in un linguaggio eseguibile — dipende dalla piattaforma, dal compilatore e dall'architettura. Descrive il come farlo in un contesto specifico.

📌 Definizione da ricordare

Algoritmo = idea risolutiva astratta. Programma = traduzione concreta di quell'idea in un linguaggio che una macchina (reale o virtuale) può eseguire.

Esempio — somma di due numeri

Lo stesso problema espresso prima come algoritmo in pseudocodice, poi come programma Assembly 8086. Nota come la logica non cambi, ma le conoscenze richieste sì.

Pseudocodice · Algoritmo
Leggi a Leggi b Somma = a + b Stampa Somma
Assembly 8086 · Programma
MOV AX, a ; carica a in AX ADD AX, b ; somma b ad AX MOV somma, AX ; salva il risultato in memoria
💬 Tip del docente

All'interrogazione non dire “l'algoritmo è il programma”. L'algoritmo sta nella testa, il programma sta nel file. Se cambi CPU, il programma Assembly va riscritto, l'algoritmo no. Questa frase ti salva il 30.

🎯 Esempio in classe

Pensa alla ricetta della carbonara: la sequenza “cuoci pasta, rosola guanciale, mescola uovo...” è l'algoritmo. Scriverla in italiano, in inglese o in simboli per un robot da cucina sono tre programmi diversi della stessa ricetta.

2. Classificazione dei linguaggi di programmazione

I linguaggi si classificano in base al livello di astrazione rispetto all'hardware. Più il linguaggio è ad alto livello, più si avvicina al linguaggio naturale e si allontana dalla macchina — e viceversa.

Alto livello

Python, C, Java, JS

Indipendente dall'hardware, vicino al linguaggio naturale. Concentrato sulla logica.

Basso livello

Assembly x86, ARM ASM

Dipendente dall'architettura, accesso diretto a registri e memoria.

Macchina

Binario puro · 10110000

Unico eseguito direttamente dalla CPU. Bit puri, nessun simbolo.

ALTO LIVELLO — Python / C / Java · Portabile · Logica del problema x = 5 + 3 → nessuna conoscenza hardware BASSO LIVELLO — Assembly 8086 · Non portabile · Registri + Memoria esplicita MOV AL, 05h / ADD AL, 03h → devi conoscere AX, AL, dimensioni LINGUAGGIO MACCHINA — 10110000 00000101 · Solo CPU specifica opcode + operando · eseguito direttamente

3. Linguaggi di alto livello

I linguaggi di alto livello sono indipendenti dall'hardware e più vicini al modo in cui gli esseri umani ragionano. Il programmatore si concentra sulla logica del problema senza preoccuparsi di registri, indirizzi o dimensioni dei dati. Un compilatore o interprete penserà alla traduzione.

Python · Alto livello
# alto livello: leggibile, portabile x = 5 + 3 print(x) # Output: 8 # Non so quale registro è usato, non mi interessa
Vantaggi

Perché si usano

✓ Codice leggibile e manutenibile
✓ Portabile su architetture diverse
✓ Sviluppo più rapido, meno bug di basso livello

Limiti

Cosa non puoi fare

✗ Nessun controllo diretto sull'hardware
✗ Overhead introdotto dalla traduzione
✗ Meno efficiente in scenari real-time o embedded

🎯 Perché non basta l'alto livello in Sistemi e Reti

Quando configuri una periferica o gestisci un interrupt dell'8086, Python non ti permette di dire “metti questo bit nel registro DX”. Devi scendere di livello.

4. Linguaggi di basso livello — Assembly

I linguaggi di basso livello sono strettamente dipendenti dall'architettura hardware. Il programmatore interagisce direttamente con registri, indirizzi di memoria e dimensioni dei dati — nulla è gestito automaticamente. È qui che si vede davvero come funziona una CPU.

Assembly 8086 · Basso livello
; Assembly 8086 — devi sapere cosa fai MOV AL, 05h ; carica il valore 5 nel registro AL (8 bit) ADD AL, 03h ; somma 3 ad AL → risultato 8 in AL ; Differenza AL vs AX? Fondamentale.

Per scrivere questo codice il programmatore deve conoscere esplicitamente:

01 · Registri

Quale registro per cosa

Quale registro usare — AX accumulatore, BX base, AL parte bassa di AX.

02 · Dimensione dati

Byte vs Word

Byte (8 bit) o word (16 bit) — AL vs AX non è intercambiabile, cambia encoding.

03 · Indirizzamento

Come accedere alla memoria

Diretto, indiretto, tramite registro base, segmento:offset — a basso livello tutto è esplicito.

⚠️ Errore comune in verifica

Scrivere MOV AX, 5 e poi MOV BL, AX è SBAGLIATO: BL è 8 bit, AX è 16 bit. In Assembly le dimensioni devono combaciare: usa MOV AL, 5 se poi lavori su 8 bit, oppure MOV BX, AX per 16 bit. L'assembler 8086 segnala errore di operandi.

📌 Dipendenza dall'architettura

Un programma Assembly scritto per l'8086 NON è eseguibile su ARM o RISC-V senza riscrittura completa. Ogni famiglia ha propria ISA, propri registri e convenzioni → codice non portabile.

5. Confronto diretto — alto livello vs basso livello

La stessa operazione somma 5 + 3 a confronto sui tre livelli, per fissare bene la differenza:

LivelloCodiceCosa gestisce il programmatorePortabilità
Alto livellox = 5 + 3Solo la logicaQualsiasi architettura
AssemblyMOV AL, 05h
ADD AL, 03h
Registri, dimensioni, indirizzamentoSolo architettura specifica
Macchina10110000 00000101Tutto — bit per bitSolo CPU specifica
🎯 Domanda da esame

Perché Python è portabile e Assembly 8086 no? Perché Python viene tradotto da interprete/compilatore per ogni CPU, mentre Assembly è già legato all'ISA: i mnemonici sono simboli per opcode reali dell'8086.

6. Linguaggio macchina e Assembly — il rapporto

Il linguaggio macchina è l'unico formato eseguibile direttamente dalla CPU — pura sequenza di bit. L'Assembly è la sua rappresentazione simbolica leggibile dall'uomo: ogni mnemonico (MOV, ADD, JMP) corrisponde a una specifica sequenza binaria definita dall'ISA dell'8086.

Assembly → Codice macchina · Corrispondenza diretta
; Assembly → codice macchina (corrispondenza diretta 8086)MOV AL, 05h → 10110000 00000101 │opcode│ │operando│ADD AL, 03h → 00000100 00000011 │opcode│ │operando│; L'assemblatore fa solo sostituzione tabella mnemonico ↔ binario
MOV AL, 05h Mnemonico umano leggibile → 10110000 00000101 Opcode + operando CPU 8086 Esegue direttamente solo binario
💬 Perché studiare Assembly sull'8086

L'8086 è il modello didattico ideale: architettura semplice, ISA ben documentata, corrispondenza diretta tra istruzione simbolica e bit. Ogni istruzione che scriveremo nelle prossime lezioni avrà effetto preciso e verificabile su registri, memoria e flag — nulla è nascosto da livelli di astrazione. Capito questo, capisci qualsiasi CPU.

7. Perché queste distinzioni contano in Sistemi e Reti

Comprendere la differenza tra livelli di astrazione è fondamentale per tre ragioni pratiche nel contesto di questo Modulo 2:

01 · Registri dedicati

Hardware non astratto

L'Assembly richiede conoscenza dell'hardware — per questo l'8086 ha registri con funzioni specifiche (AX, CX, SP) che in C non vedi.

02 · Memoria esplicita

Niente GC

A basso livello non esiste gestione automatica — ogni accesso richiede indirizzo, segmento e offset espliciti. Devi calcolarlo tu.

03 · ISA specifica

Confine SW/HW

Il codice Assembly è legato all'architettura — capire l'ISA dell'8086 significa capire il confine tra software e hardware, core di Sistemi e Reti.

🎯 Collegamento alla prossima lezione

Nella prossima lezione entreremo dentro l'8086 vero: registri, segmentazione e il motivo per cui AX, BX, CX, DX non sono uguali. Tutto ciò che hai visto oggi diventa concreto.

8. Verifica / Esercizio

🔬 Attività in classe — 15 min

Risolvi a mente, poi codifica.

  1. Scrivi l'algoritmo in pseudocodice per calcolare il quadrato di un numero letto in input. Quante istruzioni servono?
  2. Traduci x = 10 + 20 in Assembly 8086 usando solo AL. Quale istruzione scegli per caricare i valori? Perché AL e non AX se i numeri < 256?
  3. Spiega perché la sequenza binaria 10110000 00000101 è portabile solo su 8086 e non su ARM. Cosa rappresenta il primo byte?
  4. Errore: MOV BL, 300 — perché l'assembler segnala errore? Come lo correggi?
✅ Soluzione ragionata

1) Leggi N / Q = N * N / Stampa Q — 3 istruzioni logiche, indipendente dal linguaggio.

2) MOV AL, 0Ah (10) + ADD AL, 14h (20) — uso AL perché 8 bit bastano (0-255). Risparmio spazio e opcode più corto. Se usassi AX, dovrei usare MOV AX, 000Ah → 3 byte invece di 2.

3) Il primo byte è l'opcode B0h = MOV AL, imm8 specifico dell'ISA Intel x86. ARM ha codifica diversa, registri diversi, non riconosce quell'opcode.

4) BL è 8 bit (max 255). 300 > 255 → overflow. Soluzioni: usa registro 16 bit MOV BX, 300 oppure dividi in due operazioni se devi restare su 8 bit (non possibile per 300, serve word).

✓Algoritmo = sequenza logica indipendente dal linguaggio; Programma = implementazione eseguibile su architettura specifica.
✓Alto livello (Python, C, Java) → portabile, leggibile. Basso livello (Assembly) → controllo diretto, non portabile.
✓Linguaggio macchina = unico eseguito dalla CPU: sequenze binarie opcode + operando.
✓Assembly = rappresentazione simbolica 1:1 del linguaggio macchina, definita dall'ISA.
✓In Assembly 8086 devi conoscere registri (AX, AL...), dimensioni (byte/word) e indirizzamento esplicito.
✓L'8086 è didattico: semplice, ISA chiara, effetto di ogni istruzione visibile su registri/memoria/flag.

📚 Prossimo passo — Introduzione al microprocessore 8086

Ora che sai perché serve scendere di livello, apriremo la scatola: come è fatto dentro l'8086, perché ha segmenti, cosa significano CS:IP e perché AX non è uguale a BX. Porta con te questa distinzione algoritmo/programma.