Sistemi E Reti

Output

Lezione tecnica sulla gestione dell'output video in ambiente MS-DOS tramite l'uso dell'Interrupt 21h. Il laboratorio guida lo studente nella creazione di un file .com per la visualizzazione di caratteri e stringhe di testo con terminatore dollaro utilizzando EMU8086.

Durata

100 minuti

Software

EMU8086

Assembly X86 | Output

L'Output e l'Interrupt 21h

Per poter comunicare con l'utente, un programma Assembly deve inviare dati alla periferica di output (il monitor). In un ambiente a basso livello come quello dei file .com (standard MS-DOS), non abbiamo a disposizione funzioni come printf o cout. Dobbiamo invece invocare i servizi del Sistema Operativo tramite gli Interrupt.

Il Meccanismo degli Interrupt

Un interrupt (INT) è una chiamata a una routine predefinita che il sistema operativo (o DOS, in EMU8086) esegue per te. Serve a comunicare con l’hardware o il sistema senza dover conoscere tutti i dettagli delle porte, buffer e registri.
Ti permette di fare cose come:

  • stampare a video (AH = 09h)
  • leggere un tasto (AH = 01h)
  • emettere un beep (AH = 02h)
  • uscire dal programma (AH = 4Ch)

L'istruzione INT 21h è la porta d'accesso ai servizi del DOS. Prima di chiamare l'interrupt, dobbiamo istruire la CPU su quale specifica operazione vogliamo compiere caricando un codice identificativo nel registro AH.

AH (Codice Funzione) Descrizione Parametri richiesti
02h Visualizza un singolo carattere ASCII Il carattere deve essere in DL
09h Visualizza una stringa di testo L'indirizzo della stringa deve essere in DX
4Ch Termina l'esecuzione del programma AL può contenere il return code (solitamente 0)

La Stringa in Assembly: Il Terminatore "$"

A differenza dei linguaggi di alto livello che usano il terminatore null (\0), la funzione 09h del DOS richiede che la stringa termini obbligatoriamente con il carattere $. Se questo manca, il sistema continuerà a stampare i dati presenti nelle celle di memoria successive fino a trovare un simbolo di dollaro casuale, causando errori visivi o blocchi del sistema.


Istruzione Descrizione Esempio
MOV Copia un valore in un registro o memoria MOV AH, 09h
LEA Load Effective Address: carica l'indirizzo della variabile in un registro LEA DX, msg
CMP Confronta due valori (non modifica registri, ma imposta i flags) CMP AL, 1
JE Jump if Equal: salta se i flag indicano uguaglianza (ZF=1) JE pezzo_ok
JMP Salta incondizionatamente a una label JMP fine
INT Interruzione software: chiama i servizi DOS (INT 21h, etc.) INT 21h

LABORATORIO

I/O Video su EMU8086

In questo laboratorio imparerai a stampare caratteri singoli e intere frasi utilizzando le funzioni di sistema.


1 Stampa di un carattere singolo

Scriviamo un piccolo programma che visualizzi la lettera 'Z' sullo schermo.

ORG 100h

MOV AH, 02h       ; Prepariamo la funzione per la stampa di un carattere
MOV DL, 'Z'       ; Carichiamo il carattere nel registro DL
INT 21h           ; Eseguiamo la chiamata di sistema

MOV AH, 4Ch       ; Funzione per chiudere il programma correttamente
INT 21h

END

2 Stampa di una stringa

Per stampare una frase, dobbiamo usare la funzione 09h e definire una variabile in memoria tramite la direttiva DB (Define Byte).


ORG 100h

; CODICE
MOV AH, 09h       ; Funzione stampa stringa
LEA DX, messaggio ; LEA carica l'indirizzo (offset) della variabile in DX
INT 21h           ; Visualizza il testo

MOV AH, 4Ch
INT 21h

; DATI
messaggio DB "Benvenuti nel Laboratorio ITP$"

END

3 Esercizio: Sistema di Selezione Scarti (Controllo Qualità)

Scenario: State programmando il software di una stazione di controllo qualità. Un sensore rileva se un pezzo è conforme o difettoso.

Logica del programma: Il programma deve simulare la lettura di un valore (nel nostro caso lo caricheremo manualmente nel registro AL).

  • Se AL = 1: Il pezzo è OK. Stampa "PEZZO CONFORME$".
  • Se AL = 0: Il pezzo è difettoso. Stampa "SCARTO!$" e attiva il segnale acustico (Beep).


ORG 100h

; SIMULAZIONE INPUT SENSORE (Cambia questo valore per testare i due casi)
MOV AL, 1         ; 1 = OK, 0 = Errore

; LOGICA DI SELEZIONE (IF)
CMP AL, 1         ; Confronta il valore in AL con 1
JE pezzo_ok       ; Se sono uguali (Jump If Equal), vai alla label pezzo_ok

; PARTE ELSE (Se AL non è 1)
MOV AH, 09h
LEA DX, msg_err   ; Carica "SCARTO!$"
INT 21h

MOV AH, 02h       ; Funzione segnale acustico
MOV DL, 07h       ; Codice ASCII Beep
INT 21h
JMP fine          ; Salta alla fine per non eseguire il blocco OK

pezzo_ok:         ; PARTE THEN
MOV AH, 09h
LEA DX, msg_ok    ; Carica "PEZZO CONFORME$"
INT 21h

fine:
MOV AH, 4Ch       ; Chiusura programma
INT 21h

; AREA DATI
msg_ok  DB "ESITO: PEZZO CONFORME$"
msg_err DB "ATTENZIONE: SCARTO!$"

END

  • Copiate il codice in EMU8086.
  • Eseguite l'emulazione con MOV AL, 1 e osservate il monitor.
  • Cambiate la riga in MOV AL, 0, ricompilate e verificate che il messaggio cambi e che l'altoparlante (virtuale) emetta il suono.


4 Perché abbiamo usato JMP fine?

Notate che dopo la stampa del messaggio di errore abbiamo inserito un JMP fine. Senza quel salto, la CPU continuerebbe a leggere le istruzioni riga dopo riga, finendo per stampare anche il messaggio "PEZZO CONFORME" subito dopo lo scarto. In Assembly, dobbiamo gestire manualmente l'uscita dai rami decisionali.




Confronto tra RET e END in EMU8086

Caratteristica RET END
Tipo Istruzione eseguibile dalla CPU Direttiva dell'assemblatore
Genera codice Sì, diventa codice macchina No, non genera codice
Scopo Ritorna all’indirizzo in cima allo stack (usato dopo una CALL) Indica la fine del sorgente all’assemblatore
Quando la legge la CPU Runtime, durante l’esecuzione Mai, è ignorata dalla CPU
Quando la legge l’assemblatore Il compilatore lo converte in codice macchina Compile-time, serve solo per sapere dove finisce il sorgente
Uso corretto Solo per terminare procedure dopo una CALL Alla fine del file sorgente
Effetto in .COM senza CALL “Funziona” perché lo stack iniziale punta al DOS, ma non è sicuro Nessun effetto sul programma
Alternativa moderna per uscire INT 21h, AH=4Ch




Assembly, x86, INT 21h, Sistemi e Reti, Output Video, DOS,