ASSEMBLATORE E SIMULATORE DEL PROCESSORE 6502 REALIZZATO IN VISUAL BASIC

Click to rate this post!
[Total: 1 Average: 4]

Introduzione

Scopo del corso Questo corso si propone di guidare gli studenti nella creazione di un assemblatore e di un simulatore per un microprocessore a loro scelta, utilizzando un linguaggio di programmazione. Questa sfida richiederà la progettazione di un programma complesso, che permetterà di approfondire le competenze nel linguaggio scelto. Anche se alcune caratteristiche hardware, come gli interrupt, potrebbero non essere simulate completamente nel programma, al termine del corso gli studenti acquisiranno una solida comprensione del funzionamento di un assemblatore e di un simulatore.

La Scelta del linguaggio

Scelte del linguaggio Per questo progetto, abbiamo selezionato il linguaggio di programmazione Visual Basic. Questo linguaggio opera in ambiente Windows e offre notevoli vantaggi, soprattutto in termini di grafica e creazione di tabelle, rispetto ad altri linguaggi utilizzati in ambiente MS-DOS. Nonostante ciò, le istruzioni utilizzate non differiscono significativamente da quelle di altri linguaggi. Una delle principali caratteristiche dei linguaggi Visual è la loro strutturazione, che si basa sulla gestione delle caratteristiche grafiche e sulla suddivisione del codice in subroutine. Queste subroutine non vengono richiamate da un programma principale, ma da eventi scatenati da controlli grafici forniti da VB, come pulsanti e barre di stato. Abbiamo scelto questo linguaggio per le sue eccellenti capacità nella gestione di tabelle e nella grafica, due aspetti fondamentali per questo progetto.

Il tipo del processore

Tipo di microprocessore Il microprocessore selezionato per questo progetto è il 6502. Questo microprocessore dispone di un bus di indirizzi a 16 bit, consentendo l’accesso a una memoria di 64 Kbyte. Inoltre, è dotato di un bus dati e di registri interni di 8 bit ciascuno. Questa configurazione implica che, per lavorare con dati a 16 bit o superiori, è necessario affrontare il problema dal punto di vista del software, il che comporta tempi di esecuzione più lunghi rispetto ai microprocessori con bus dati e registri di dimensioni maggiori.

Assemblatore

Assemblatore Il programma è stato progettato per creare un assemblatore simile a uno reale, senza apportare modifiche significative per semplificare la scrittura del programma in Visual Basic. Questa scelta consente di utilizzare programmi assembler già sviluppati senza doverli adattare ulteriormente. Tuttavia, il principale svantaggio di questa approccio è che l’esecuzione del programma assembler risulta più lenta, poiché è necessario attraversare il listato del programma assembler almeno tre volte per ottenere il risultato desiderato.

Ora passiamo a descrivere l’interfaccia grafica che verrà presentata all’utente:

In questo programma, il linguaggio assembler non viene scritto in un tradizionale editor di testo, ma all’interno di una griglia simile a un foglio di lavoro di MS-Excel. Questa griglia è un oggetto reso disponibile da VB (DBGrid) e ha il compito di rappresentare un database sotto forma di tabella. Fondamentalmente, quando scriviamo il nostro programma all’interno di questa tabella, stiamo effettivamente popolando un database in memoria.

Ora, dobbiamo valutare se questa scelta sia migliore rispetto all’uso di un tradizionale editor di testo. Nel caso di un editor di testo, il programma dovrebbe essere salvato in un file, che successivamente verrebbe letto dall’assemblatore. Questo avrebbe comportato l’apertura e la chiusura del file per ogni istruzione, rallentando notevolmente l’esecuzione del programma.

Nel nostro approccio, il database è sempre in memoria, il che implica tempi di lettura delle celle del database notevolmente più rapidi rispetto all’apertura di un file scritto precedentemente con l’aiuto di un editor di testo. Inoltre, il nostro metodo offre un aspetto grafico migliore, il che facilita la scrittura e la comprensione del programma assembler. Questa scelta è stata resa possibile grazie all’uso di VB.

Una volta scritto il programma, è possibile salvarlo facilmente in un file con estensione .ASS. In questo modo, è possibile cancellare tutto il contenuto del database per creare un nuovo programma o aprire un altro file .ASS precedentemente creato. Questa capacità di gestire file sequenziali è una caratteristica fornita da VB.

A questo punto, per ottenere il risultato dell’assemblatore, è necessario eseguire la fase di compilazione, che costituisce essenzialmente l’intero processo dell’assemblatore. Durante questa fase, vengono popolate la tabella dei simboli e la tabella di listing, che rappresentano i risultati dell’assemblaggio. È importante notare che questa fase richiede tre cicli del programma assembler creato:

  1. Nel primo ciclo:
  • Vengono inseriti i label del programma assembler nella colonna dei label della tabella dei simboli, che è stata già caratterizzata in precedenza come una tabella statica.
  • Si determina se ciascun label nella tabella dei simboli rappresenta una variabile o un indicatore.
  • Si identifica se la variabile si trova nella pagina 0 o meno. Questa informazione è ottenuta grazie agli indirizzi assegnati alle variabili nel programma assembler.
  • Si ricerca il valore MACCHINA1 di tutti i codici operativi (C.O.) di tutte le righe e si inserisce in una tabella provvisoria chiamata “tabella intermedia”.
  • In questa tabella intermedia, vengono assegnati i valori di tipo che caratterizzano le parti dei C.O. con un indirizzamento specifico.
  • Si determina il tipo di indirizzamento utilizzando le lettere dell’alfabeto secondo un ordine specifico, basato sulla forma in cui è scritto l’operando nel programma assembler.
  • Conoscendo il tipo di indirizzamento, è possibile calcolare la lunghezza dell’istruzione e incrementare l’indirizzo del codice di conseguenza. Queste informazioni vengono registrate nella tabella intermedia.
  • Utilizzando l’indirizzamento e il valore di tipo, è possibile calcolare il valore di MACCHINA1PLUS. La somma esadecimale di MACCHINA1 e MACCHINA1PLUS rappresenta il codice macchina che identifica il codice operativo con un determinato indirizzamento.
  1. Nel secondo ciclo:
  • Vengono inseriti gli indirizzi corrispondenti ai label nella tabella dei simboli, utilizzando le informazioni precedentemente inserite nella tabella intermedia durante il primo ciclo.
  1. Nel terzo ciclo:
  • Si cerca il valore dell’operando nella tabella dei simboli, che è presente nel programma assembler.
  • La tabella di listing viene completamente compilata con le informazioni necessarie, la cui struttura è già stata definita in precedenza.

Le tre figure successive mostreranno la tabella dei simboli, la tabella intermedia e la tabella di listing.

L’assemblatore inoltre può creare il file listing che ha estensione .LIS e il file numerico che ha
estensione .NUM . Una volta creato il file numerico si può accedere al simulatore. Prima non si può
accedere perchè il nostro simulatore prende i dati proprio dal file numerico.

Il file listing è un file che può essere letto da qualsiasi test editor la sua forma è il seguente

Il file numerico è un file che è realizzato con la corrispondenza uno a uno cioè se l’istruzione è
lunga tre byte allora vengono trasferiti nel file tre byte.
Il file formato è un file binario (caratteristica VB) e vengono inseriti all’interno i valori integer di
ogni byte esadecimale del codice.
Il simulatore che da adesso tratteremo prende i dati proprio da questo file numerico

Il simulatore

La prima operazione eseguita dal simulatore è quella di acquisire i byte dal file numerico e memorizzarli nella memoria del simulatore. La memoria del simulatore è rappresentata da una matrice di dimensioni 255×255, in cui ogni riga corrisponde a una pagina di memoria. La prima riga rappresenta quindi la pagina 0.

Il programma viene inserito in memoria a partire dalla locazione indicata dalla prima istruzione nel file numerico. Ad esempio, considerando il contenuto del file listing mostrato precedentemente, la prima istruzione è “FF 0020”. Questa istruzione indica che il file numerico deve essere scritto nella memoria del simulatore a partire dalla locazione 0200.

Nel programma possono essere presenti delle subroutine, e in tal caso, esse devono essere precedute da un’istruzione del tipo “FF __” che indica il punto in memoria in cui iniziare a scrivere la subroutine. Il programma principale deve essere scritto dopo tutte le subroutine.

Una volta caricati i byte nella memoria, il Program Counter (PC) si trova automaticamente all’inizio della locazione indicata dalla prima istruzione del programma principale.

Il simulatore deve ora eseguire le istruzioni, e per farlo, deve riconoscere ciascuna istruzione del programma. Per ottenere ciò, è necessario associare una procedura a ciascun codice macchina che rappresenta un codice operativo.

Per gestire questa operazione, si può utilizzare una struttura di controllo “CASE” che, in base al codice macchina presente, determina il tipo di indirizzamento e l’operazione da eseguire. Tuttavia, questa soluzione potrebbe non essere la più efficiente, poiché potrebbe comportare oltre 150 diramazioni nel “CASE”, rendendo l’esecuzione lenta.

Invece, la soluzione adottata consiste nell’utilizzare una tabella in cui sono elencati tutti i possibili codici macchina, insieme ai rispettivi codici operativi e tipi di indirizzamento. Quando si cerca un codice macchina, si individua anche il tipo di indirizzamento e il codice operativo corrispondente dalla tabella.

Una volta noto il tipo di indirizzamento, è possibile utilizzare un secondo “CASE” con 8 diramazioni per determinare i dati necessari per le operazioni. Successivamente, un terzo “CASE” con 59 diramazioni viene utilizzato per determinare la specifica operazione da eseguire per ciascun codice operativo, utilizzando i dati ottenuti dal “CASE” sull’indirizzamento.

Questa soluzione risulta più efficiente, e la velocità di ricerca del codice macchina dalla tabella può essere ulteriormente migliorata assegnando un indice ai campi del codice macchina nella tabella, in modo da ordinarli in memoria.

Infine, il “CASE” sull’indirizzamento determina i dati, incrementa il PC in modo appropriato e recupera l’operando di ciascuna istruzione macchina (MACCHINA2). L’esecuzione del programma continua finché non si raggiunge l’istruzione “END”, che indica l’ultima istruzione da elaborare da parte del simulatore.

Ora descriviamo come il simulatore viene visualizzato dal punto di vista grafico:

Come evidenziato nel formulario precedente, è possibile individuare facilmente i registri interni e i flag di sistema. Inoltre, è agevole osservare i risultati presenti nelle rispettive locazioni di memoria nella “memoria a richiesta”. Quest’ultima rappresenta una tabella nella quale è possibile visualizzare i contenuti di qualsiasi locazione di memoria. Il nome “memoria a richiesta” deriva dal fatto che l’indirizzo da esaminare può essere selezionato esternamente. Tuttavia, quando si avvia il simulatore, nella “memoria a richiesta” vengono automaticamente visualizzati gli indirizzi delle variabili del programma assembler.

Ora, parliamo delle differenze tra l’esecuzione veloce e l’esecuzione normale del programma. L’esecuzione veloce fornisce solo i risultati della simulazione, mentre l’altra modalità di esecuzione crea anche una tabella, chiamata “Tabella della Simulazione,” che tiene traccia di tutti i possibili valori che si sono verificati nei registri e nelle variabili durante lo sviluppo del programma.

Nella pagina successiva, verrà fornito un esempio di questa “Tabella della Simulazione”:

Il simulatore offre anche la funzionalità di esecuzione in modalità DEBUG. Quando si clicca sul pulsante DEBUG nel simulatore, compare una tabella (che, in realtà, rappresenta la tabella di listing creata dall’assemblatore). Ogni volta che si fa clic su DEBUG, viene eseguita un’istruzione, e nella tabella visualizzata nel formulario del simulatore, si sposta un indicatore che mostra quale istruzione è stata appena eseguita.

Questo approccio ottimizza l’analisi di ciascuna istruzione del programma, consentendo di individuare rapidamente la riga in cui potrebbe essere presente un eventuale errore durante l’esecuzione del programma.

Nella pagina successiva, sarà mostrato il formulario del simulatore nel momento in cui viene eseguito il DEBUG:

Nel simulatore è possibile aprire un file diverso da quello creato dall’assemblatore nel momento in cui si è acceduto al simulatore. Tuttavia, in questo caso, ci sono alcune limitazioni. È possibile eseguire solo la modalità “esecuzione veloce” del programma, e non vengono visualizzati gli indirizzi delle variabili nella “memoria a richiesta.”

Per quanto riguarda le caratteristiche di input e output, sono state apportate alcune modifiche rispetto alla situazione reale. Poiché è impossibile che durante l’esecuzione del programma si verifichino cambiamenti negli stati esterni, è stato introdotto un nuovo codice operativo (CO) chiamato “IMP” che richiama un controllo di VB, consentendo di inserire dati e assegnarli a una specifica locazione di memoria per simulare l’input.

Per la simulazione dell’output, è stato adottato un approccio simile. I dati in uscita vengono inviati senza tener conto di uno stato reale. Inoltre, per simulare l’output, è stato utilizzato VB per creare un display a 7 segmenti e un monitor.

Queste modifiche sono state necessarie per gestire le caratteristiche di input e output all’interno del simulatore, anche se possono differire dalla realtà.

Solitamente, per inviare dati in uscita, si fa riferimento a un buffer intermedio in cui vengono temporaneamente memorizzati i dati. Tuttavia, in questo simulatore, la situazione è leggermente diversa. Qui, non esiste un buffer intermedio, e i dati visualizzati direttamente sul monitor o sul display a 7 segmenti vengono prelevati direttamente dalla locazione di memoria il cui indirizzo è chiaramente specificato nei form delle uscite.

Questo significa che i dati in uscita vengono letti direttamente dalla memoria, senza passare attraverso un buffer intermedio, quando sono pronti per essere visualizzati.

Conclusioni

In conclusione, il simulatore descritto offre un approccio dettagliato per eseguire e analizzare programmi scritti in linguaggio assembler. Con una varietà di funzionalità, tra cui la modalità di esecuzione veloce, la modalità di debug e la visualizzazione grafica dei registri e della memoria, il simulatore fornisce un ambiente versatile per l’analisi e il test dei programmi.

Sebbene alcune variazioni rispetto alla realtà siano state introdotte per gestire le caratteristiche di input e output, queste modifiche consentono comunque di simulare in modo efficace il comportamento di un microprocessore e di eseguire programmi assembler in modo efficiente.

Inoltre, la capacità di aprire file diversi da quelli creati dall’assemblatore offre una maggiore flessibilità nell’uso del simulatore.

Nel complesso, questo simulatore rappresenta uno strumento prezioso per gli studenti e gli appassionati di informatica che desiderano esplorare il mondo dell’assembler e acquisire una comprensione approfondita del funzionamento interno di un microprocessore. La combinazione di funzionalità di visualizzazione grafica, esecuzione controllata e analisi dettagliata dei programmi lo rende un’importante risorsa per l’apprendimento e la sperimentazione nel campo dell’informatica.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x