- Comprendere il funzionamento di base della CPU e dei registri di controllo
- Analizzare l’esecuzione sequenziale delle istruzioni in Assembly
- Utilizzare ambienti di sviluppo e simulazione per il linguaggio Assembly
- Scrivere semplici programmi Assembly in formato .COM
- Interpretare il ruolo dei registri CS e IP nell’esecuzione dei programmi
Formato .COM
Un file .COM è un programma Assembly molto semplice:- utilizza un solo segmento di memoria
- inizia sempre all’indirizzo 0100h
Registro CS (Code Segment)
Il registro CS contiene l’indirizzo del segmento di memoria dove si trova il codice del programma. La CPU usa CS insieme a IP per sapere dove leggere la prossima istruzione. Il registro rimane sempre costante e non viene mai aggiornato.
Registro IP (Instruction Pointer)
Il registro IP contiene l’offset della prossima istruzione da eseguire all’interno del segmento indicato da CS. Dopo ogni istruzione, IP viene automaticamente aggiornato.
CS e IP: cosa sono e perché si usano insieme
Nel processore 8086 la CPU individua la prossima istruzione tramite la coppia CS:IP. CS (Code Segment) contiene l’indirizzo del segmento di codice, mentre IP (Instruction Pointer) contiene l’offset della prossima istruzione all’interno di quel segmento.
| Elemento | Che cos’è | Chi lo imposta | Quando |
|---|---|---|---|
| CS | Segmento del codice (base logica del codice) | Loader/ambiente (es. DOS/EMU8086) | All’avvio del programma |
| IP | Offset della prossima istruzione (posizione nel segmento) | CPU, inizialmente il loader; poi aumenta/esegue salti | All’avvio e durante l’esecuzione |
| CS:IP | Puntatore completo alla prossima istruzione | CPU | Continuamente |
2) Indirizzo fisico: formula 8086
L’8086 trasforma segmento:offset in un indirizzo fisico con la formula:
indirizzo_fisico = CS * 16 + IP
Esempio: se CS=0700h e IP=0100h, allora:
0700h * 10h = 7000h
7000h + 0100h = 7100h
3) Perché nei file .COM IP parte da 0100h
Nei programmi .COM (ambiente DOS) il loader riserva i primi 256 byte del segmento per il PSP (Program Segment Prefix). Per questo motivo il codice del programma viene eseguito a partire dall’offset 0100h.
| Intervallo (offset) | Contenuto | Nota |
|---|---|---|
| 0000h - 00FFh | PSP | Informazioni di avvio, parametri, servizi DOS |
| 0100h - ... | Codice + dati del programma | Qui parte l’esecuzione: CS:0100h |
4) ORG 100h: la direttiva che “allinea” il codice
ORG 100h è una direttiva dell’assemblatore (non è un’istruzione CPU). Serve a dire: “Considera che il primo byte del mio programma si trova a offset 0100h”.
| Domanda | Risposta |
|---|---|
| ORG 100h imposta IP? | No. IP lo imposta il DOS per i .COM (tipicamente a 0100h). |
| Allora a cosa serve ORG 100h? | A fare in modo che l’assemblatore calcoli correttamente offset di salti e variabili sapendo che il codice parte da 0100h. |
| Cosa succede se scrivo ORG 200h in un .COM? | Il DOS parte comunque da 0100h: si crea disallineamento e il programma tende a funzionare male (offset errati). |
La dimensione delle istruzioni
IP viene incrementato del numero di byte dell’istruzione eseguita.org 100h
mov al, num1
add al, num2
L’istruzione mov al, num1 viene tradotta in 3 byte in memoria.
Quindi IP passa da:
0100h → 0103h
Nota:
- IP non avanza di “una riga”, ma di 3 byte, cioè della dimensione dell’istruzione macchina.
- IP viene incrementato in base al numero di byte dell’istruzione macchina, non in base alle righe del codice sorgente.
- Single Step esegue una istruzione macchina, e IP avanza della sua lunghezza in byte.
LABORATORIO
Dimensione delle istruzioni e variazione dell’offset (IP) in EMU8086
In questo laboratorio si osserva che l’Instruction Pointer (IP) non viene incrementato di 1, ma della dimensione in byte dell’istruzione eseguita. L’obiettivo è collegare istruzioni Assembly, byte in memoria e valore di IP.
- PC con EMU8086 installato
- Modalità Single Step
- Finestre Registers e Memory Dump
1 Codice di partenza
Creare un nuovo programma .COM e inserire il seguente codice:
org 100h
mov al, num1
add al, num2
sub al, num2
mov ax, num3
int 20h
num1 db 5
num2 db 1
num3 dw 0
Questo programma contiene istruzioni di lunghezza diversa.
2 Osservazione iniziale di IP
1) Avviare il programma in modalità Single Step.
2) Prima di eseguire la prima istruzione, osservare la finestra Registers.
- Annotare il valore iniziale di IP (atteso: 0100h).
- Annotare il valore di CS.
Questo conferma che l’esecuzione parte dall’offset 0100h.
3 Esecuzione Single Step e variazione di IP
Eseguire il programma una istruzione alla volta con Single Step. Dopo ogni istruzione, osservare il nuovo valore di IP.
Compilare la seguente tabella. La prima riga è già completata.
| Istruzione | IP iniziale | IP finale | Incremento IP | Dimensione istruzione |
|---|---|---|---|---|
| mov al, num1 | 0100h | 0103h | +3 | 3 byte |
| add al, num2 | ________ | ________ | ________ | ________ |
| sub al, num2 | ________ | ________ | ________ | ________ |
| mov ax, num3 | ________ | ________ | ________ | ________ |
| int 20h | ________ | ________ | ________ | ________ |
4 Verifica con il Memory Dump
Aprire la finestra Memory Dump e posizionarsi all’indirizzo CS:0100.
- Osservare quanti byte consecutivi occupa ogni istruzione.
- Verificare che il numero di byte corrisponda all’incremento di IP osservato.
Questo dimostra che IP avanza della lunghezza in byte dell’istruzione.
5 Conclusione guidata
Rispondere alle seguenti domande:
- IP aumenta sempre di 1? Perché?
- Da cosa dipende l’incremento di IP?
- La CPU esegue righe di codice o byte di memoria?
L’Instruction Pointer (IP) viene incrementato in base al numero di byte dell’istruzione eseguita, non in base al numero di righe del codice sorgente.