# Esempio di Architettura Computer - Macchina von Neumann

{% file src="/files/mkHXoBhSbEAOxna1t9FT" %}
Slide sull'argomento
{% endfile %}

Il 30 giugno 1945 il geniale matematico ungherese [John von Neumann](https://it.wikipedia.org/wiki/John_von_Neumann) pubblicò un famoso rapporto propedeutico alla realizzazione del progetto EDVAC (*Electronic Discrete Variable Automatic Calculator*) presso la Scuola di Ingegneria Elettrica della Pennsylvania University a Filadelfia, negli Stati Uniti. L’immagine che segue mostra una pagina del progetto originale:&#x20;

![](/files/wQDWurXLXTVcEFewoFTU)

Il rapporto di von Neumann viene universalmente considerato il progetto logico dell’architettura del computer moderno e ancora oggi la struttura interna dei computer è realizzata sulla base delle [idee di von Neumann](https://it.wikipedia.org/wiki/Architettura_di_von_Neumann). Ovviamente le tecnologie attuali sono completamente diverse da quelle degli anni Cinquanta del secolo scorso; la figura sotto mostra la fotografia di un moderno microprocessore per PC. EDVAC è stato il primo computer a utilizzare una rappresentazione binaria dei numeri, ma l’idea realmente innovativa di von Neumann consiste nel concetto di «programma memorizzato»: la memoria del computer – oltre ai dati da elaborare e i risultati prodotti – contiene, codificate in formato numerico, anche le istruzioni di elaborazione, che possono essere di conseguenza facilmente modificate o sostituite, rendendo il computer lo strumento versatile che conosciamo.

![](/files/G9u6IUiZVyCVWan3BlWG)

### L'architettura

L’**architettura del computer** di von Neumann prevede due componenti fondamentali tra loro interconnesse:

* l’**unità centrale di elaborazione** denominata **CPU** (Central Processing Unit);
* la cosiddetta **memoria ad accesso casuale**. (**RAM**, Random Access Memory)

La **CPU** è a sua volta composta dall’**unità di controllo** (**CU**, *Control Unit*), che sovrintende al funzionamento della macchina (in particolare al controllo della sequenza delle istruzioni da eseguire), e dall’**unità aritmetico-logica** (**ALU**, *Arithmetic-Logic Unit*), all’interno della quale si svolgono le operazioni specificate dalle istruzioni.&#x20;

La memoria **RAM** è organizzata come una sequenza di locazioni – identificate da **indirizzi** consecutivi – ciascuna delle quali può contenere un numero intero che codifica un dato o un’istruzione.&#x20;

La struttura di interconnessione tra CPU e RAM è costituita da un *bus* unidirezionale per gli indirizzi e da un *bus* bidirezionale per i dati e le istruzioni (FIGURA 1).

![](/files/uZzTsQUPdbzgOKY1d4Bk)

L’unità di controllo può richiedere alla memoria operazioni di lettura (trasferimento di dati o istruzioni dalla RAM alla CPU) o di scrittura (trasferimento di dati dalla CPU alla RAM). L’operazione richiesta coinvolge la locazione di memoria indirizzata dal numero inviato alla RAM mediante il bus indirizzi, mentre i dati (o le istruzioni) transitano da un’unità all’altra attraverso il bus dati/istruzioni.

Il numero di locazioni della memoria RAM è ovviamente finito, ma nei computer di fascia alta è piuttosto elevato (dell’ordine dei miliardi di byte). La dimensione della memoria si misura in multipli di byte che assumono le seguenti denominazioni:

<mark style="color:red;">1 Kilobyte (KB) = 1024 byte</mark>

<mark style="color:red;">1 Megabyte (MB) = 1024 KB = 1 048 576 byte</mark>

<mark style="color:red;">1 Gigabyte (GB) = 1024 MB = 1 073 741 824 byte</mark>

<mark style="color:red;">1 Terabyte (TB) = 1024 GB = 1 099 511 627 776 byte</mark>

L’uso della decima potenza di 2 (1024 = 2^10 ) rende più agevole l’uso di questi valori in formato binario e, al tempo stesso, i multipli non si discostano troppo dalle usuali potenze di 10 (1000, 1000000, 1000000000, 1000000000000) a cui siamo abituati.&#x20;

**OSSERVAZIONE** L’idea fondamentale che sta alla base della macchina ideata da von Neumann più di mezzo secolo fa e su cui ancora oggi è fondata l’architettura dei computer è la coesistenza in un’unica unità di memoria2 sia dei dati da utilizzare per il calcolo, sia dei risultati intermedi e finali prodotti dall’esecuzione del calcolo, sia delle istruzioni che specificano i calcoli da effettuare sui dati memorizzati. Tutte queste «informazioni» sono memorizzate nella memoria della macchina in formato numerico.

L’unità ALU comprende normalmente un registro, denominato **accumulatore**, per la memorizzazione temporanea del risultato di operazioni aritmetiche effettuate tra il contenuto numerico dello stesso accumulatore e quello di una specifica locazione di memoria individuata da un indirizzo, in simboli:

`A ← A ⛛ RAM[ind]`

Il simbolo ⛛ rappresenta una qualsiasi delle operazioni aritmetiche che l'unità ALU è in grado di effettuare.

Completano l’architettura di una macchina di von Neumann due registri contenuti nell’unità di controllo:&#x20;

* il **registro istruzioni** (**IR**, *Instruction Register*), dove un’istruzione prelevata dalla memoria viene interpretata per essere eseguita;
* il **registro contatore di programma** (**PC**, *Program Counter*), il cui valore individua l’indirizzo della locazione di memoria contenente la prossima istruzione da eseguire.

Il valore del registro PC viene automaticamente incrementato di una posizione – divenendo l’indirizzo della locazione successiva di memoria – nel corso dell’esecuzione da parte della CPU dell’istruzione stessa.

Il funzionamento di un computer è di conseguenza definito dalla seguente sequenza di fasi di lavoro che viene continuamente ripetuta:

**FETCH**: l’istruzione contenuta nella locazione di memoria indirizzata dal valore del registro PC viene letta e copiata nel registro IR dell’unità di controllo; successivamente viene incrementato il valore del PC in modo da indirizzare l’istruzione successiva da eseguire;

**EXECUTE**: l’istruzione presente nell’IR viene esaminata per riconoscere l’operazione che essa codifica e quindi eseguita.

I termini *fetch* (prelevamento) ed execute (esecuzione) identificano le due fasi del ciclo di funzionamento della CPU che un computer attuale è in grado di ripetere anche alcuni miliardi di volte al secondo.&#x20;

**OSSERVAZIONE** Memorizzando ordinatamente le istruzioni che si intendono eseguire in locazioni successive della memoria RAM e stabilendo il valore iniziale del registro contatore di programma uguale all’indirizzo della prima di esse, si ottiene da parte del computer l’esecuzione automatica della sequenza di operazioni specificata dalle istruzioni. La sequenza di istruzioni da eseguire è denominata **programma**.

### Le istruzioni

Ma quali istruzioni è in grado di eseguire un computer? La tabella sotto elenca e descrive un insieme di istruzioni minimo, ma sufficiente al funzionamento di una macchina di von Neumann la cui ALU sia in grado di eseguire le operazioni di addizione, sottrazione, moltiplicazione e divisione di numeri interi positivi e negativi e comprenda un registro accumulatore impegnato per le operazioni di lettura/scrittura dei dati dalla/nella memoria e per contenere i risultati delle operazioni aritmetiche.

| Istruzione | Descrizione analitica                                                                                                                                                                                                                                                                                                                              | Descrizione sintetica           |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| `LOD ind`  | Carica il valore contenuto nella locazione di memoria di indirizzo `ind` nel registro accumulatore                                                                                                                                                                                                                                                 | `A <-- RAM[ind]`                |
| `LOD #num` | Carica direttamente il numero specificato nel registro accumulatore                                                                                                                                                                                                                                                                                | `A <-- num`                     |
| `STO ind`  | Copia il valore contenuto nel registro accumulatore nella locazione di memoria di indirizzo `ind`                                                                                                                                                                                                                                                  | `RAM[ind] <-- A`                |
| `ADD ind`  | Addiziona il valore contenuto nel registro accumulatore e il valore contenuto nella locazione di memoria di indirizzo `ind` calcolando la somma nel registro accumulatore                                                                                                                                                                          | `A <-- A + RAM[ind]`            |
| `ADD #num` | Addiziona il valore contenuto nel registro accumulatore e il numero specificato calcolando la somma nel registro accumulatore                                                                                                                                                                                                                      | `A <-- A + num`                 |
| `SUB ind`  | Sottrae il valore contenuto nella locazione di memoria di indirizzo `ind` dal valore contenuto nel registro accumulatore calcolando la differenza nel registro accumulatore                                                                                                                                                                        | `A <-- A - RAM[ind]`            |
| `SUB #num` | Sottrae il numero specificato dal valore contenuto nel registro accumulatore calcolando la differenza nel registro accumulatore                                                                                                                                                                                                                    | `A <-- A - num`                 |
| `MUL ind`  | Moltiplica il valore contenuto nel registro accumulatore con il valore contenuto nella locazione di memoria di indirizzo `ind` calcolando il prodotto nel registro accumulatore                                                                                                                                                                    | `A <-- A * RAM[ind]`            |
| `MUL #num` | Moltiplica il valore contenuto nel registro accumulatore con il numero specificato calcolando il prodotto nel registro accumulatore                                                                                                                                                                                                                | `A <-- A * num`                 |
| `DIV ind`  | Divide il valore contenuto nel registro accumulatore per il valore contenuto nella locazione di memoria di indirizzo `ind` calcolando il quoziente nel registro accumulatore (il quoziente è un numero intero anche se il valore contenuto in A non è divisibile per il valore contenuto nella memoria in questo caso viene trascurato il "resto") | `A <-- A / RAM[ind]`            |
| `DIV #num` | Divide il valore contenuto nel registro accumulatore per il numero specificato calcolando il quoziente nel registro accumulatore (il quoziente è un numero intero alche se il valore contenuto in A non è divisibile per il numero specificato: in questo caso viene tralasciato il "resto")                                                       | `A <-- A / num`                 |
| `JMP ind`  | Inserisce il valore `ind` nel registro PC (la prossima istruzione eseguita sarà l'istruzione contenuta nella locazione di memoria avente indirizzo `ind`, anziché l'istruzione contenuta nella posizione di memoria successiva a quella contenente questa istruzione)                                                                              | `PC <-- ind`                    |
| `JMZ ind`  | Inserisce il valore `ind` nel registro PC se il contenuto del registro accumulatore è **zero** (in questo caso la prossima istruzione eseguita sarà l'istruzione contenuta nella locazione di memoria avente indirizzo `ind`, altrimenti sarà l'istruzione contenuta nella locazione di memoria successiva a quella contenente questa istruzione   | `Se A è zero allora PC <-- ind` |
| `NOP`      | Operazione nulla                                                                                                                                                                                                                                                                                                                                   |                                 |
| `HLT`      | Interrompe il ciclo di funzionamento della macchina                                                                                                                                                                                                                                                                                                |                                 |

**Esempio MOLTIPLICAZIONE di un NUMERO per SUCCESSORE:** Il seguente programma – memorizzato nella RAM a partire dall’indirizzo 0 – effettua il prodotto del numero N inizialmente contenuto nella locazione di indirizzo 100 con il suo successore N+ 1 e memorizza il risultato nella locazione di indirizzo 101:&#x20;

```nasm
0. LOD 100 
1. ADD #1 
2. MUL 100 
3. STO 101 
4. HLT
```

Per comprenderne il funzionamento è utile «tracciare» in una tabella (TABELLA 1) le variazioni del contenuto del registro contatore di programma dell’unità di controllo, del registro accumulatore dell’unità ALU e delle locazioni di memoria interessate durante l’esecuzione del programma, nell’ipotesi che inizialmente la locazione di indirizzo 100 della RAM contenga il valore «9».

<figure><img src="/files/ITytV62ukjVa4waiujZJ" alt=""><figcaption><p>TABELLA 1</p></figcaption></figure>

&#x20;**OSSERVAZIONE:** Il registro PC contiene sempre l’indirizzo della prossima istruzione da eseguire. Esso viene incrementato prima dell’esecuzione dell’istruzione presente nel registro IR (prelevata dalla locazione di memoria indirizzata dal precedente valore del registro PC stesso), di conseguenza nella tabella di traccia risulta sfalsato di una locazione rispetto all’istruzione corrispondente. Normalmente quindi un programma viene eseguito in modo sequenziale.

**OSSERVAZIONE:** Gli indirizzi di memoria 100 e 101 potrebbero rappresentare locazioni speciali il cui contenuto viene in realtà fornito da un dispositivo di input, come per esempio una tastiera, o a un dispositivo di output, per esempio un monitor. L’**unità di input/output** dei dati e dei risultati costituisce il terzo componente che von Neumann aveva previsto nel progetto logico della sua macchina.

**Esempio PARI e DISPARI:** Il seguente programma – memorizzato nella RAM a partire dall’indirizzo 0 – determina la metà del numero N inizialmente contenuto nella locazione di indirizzo 100 se esso è pari, altrimenti – se N è dispari – determina il successore del suo triplo e memorizza il risultato nella locazione di indirizzo 101:&#x20;

```nasm
0.  LOD 100 
1.  DIV #2 
2.  MUL #2 
3.  STO 200 
4.  LOD 100 
5.  SUB 200 
6.  JMZ 11 
7.  LOD 100 
8.  MUL #3 
9.  ADD #1 
10. JMP 13 
11. LOD 100 
12. DIV #2 
13. STO 101 
14. HLT 
```

Dovendo diversificare il comportamento del programma per i numeri pari e i numeri dispari, le istruzioni dal 7 al 12 sono eseguite in modo alternativo: le istruzioni contenute nelle locazioni di memoria dall’indirizzo 7 all’indirizzo 9 nel caso che il numero sia dispari, le istruzioni contenute nelle locazioni di memoria dall’indirizzo 11 all’indirizzo 12 nel caso che sia pari; le istruzioni in nero sono eseguite in entrambe le situazioni e in particolare quelle contenute nelle locazioni di memoria dall’indirizzo 0 all’indirizzo 6 determinano se il numero è pari o dispari, calcolando il resto della sua divisione per 2 e sfruttando la caratteristica della ALU di effettuare esclusivamente calcoli con numeri interi. Il confronto tra le tabelle di tracciatura dei valori contenuti nel registro accumulatore dell’unità ALU e nelle locazioni di memoria interessate in due situazioni iniziali diverse – nel primo caso la locazione di indirizzo 100 della RAM contiene il valore «12» (pari), nel secondo caso il valore «13» (dispari) – consente di comprendere come le istruzioni di «salto» ("jump" in inglese) alterano il meccanismo di incremento sequenziale del registro PC (TABELLE 2 e 3).

<figure><img src="/files/Q7swtQmyk63seWts607C" alt=""><figcaption></figcaption></figure>

**OSSERVAZIONE:** L'istruzione `JMP` è nota come **salto incondizionato**, in quanto il valore del registro contatore di programma viene modificato in ogni caso, mentre l'istruzione `JMZ` è nota come **salto condizionato** perché il valore del registro contatore di programma viene modificato solo se sussiste una specifica condizione (in questo caso data dal fatto che il contenuto del registro accumulatore sia il valore "0").

**Esempio SOMMA primi N numeri:** Il seguente programma – memorizzato nella RAM a partire dall’indirizzo 0 – determina la somma dei primi N numeri, con il valore N inizialmente contenuto nella locazione di indirizzo 100 e memorizza il risultato nella locazione di indirizzo 101:

```nasm
0. LOD 100 
1. STO 101 
2. SUB #1 
3. STO 100 
4. JMZ 9 
5. ADD 101 
6. STO 101 
7. LOD 100 
8. JMP 2 
9. HLT
```

**N**ell’ipotesi che inizialmente la locazione di indirizzo 100 della RAM contenga il valore «4», la somma dei primi 4 numeri è 1 + 2 + 3 + 4 = 10.

**OSSERVAZIONE** Il programma dell’esempio precedente illustra una tecnica di programmazione della macchina di von Neumann molto utile; le locazioni di memoria di indirizzo 100 e 101 sono utilizzate ciascuna per memorizzare nel corso del calcolo i risultati intermedi: la locazione di indirizzo 101 contiene il risultato parziale della somma, mentre quella di indirizzo 100 contiene il prossimo valore da sommare e, diminuendo fino a divenire 0, determina la fine della ripetizione del calcolo stesso.

A ogni istruzione è associato un codice numerico - usualmente chiamato **codice operativo** - che le identifica: le istruzioni che devono specificare un valore numerico o un indirizzo di memoria hanno un codice numerico composto dal codice operativo più una parte variabile che consente di specificare il numero o l'indirizzo.

E' compito dell'unità di controllo della CPU leggere il codice numerico dell'istruzione contenuto nella locazione di memoria indirizzata dal registro PC e interpretarlo al fine di eseguire l'operazione specificata.

**OSSERVAZIONE:** La memoria RAM di un computer contiene esclusivamente numeri, alcuni dei quali codificano le istruzioni del programma da eseguire, mentre altri rappresentano i valori a cui si applicano le operazioni aritmetiche specificate dalle istruzioni eseguite.

### Esempio Conversione da gradi Celsius a Fahrenheit

Scrivere un programma per il computer di von Neumann che converta la temperatura espressa in °C, specificata nella locazione di memoria di indirizzo 100, in una temperatura espressa in °F nella locazione di memoria di indirizzo 101 (per convertire da °C in °F occorre moltiplicare per 9, dividere per 5 e sommare 32; esempio: 100 °C sono equivalenti a 100 × 9 : 5 + 32 = 900 : 5 + 32 = 180 + 32 = 212°F).

Codice in linguaggio macchina:

```nasm
0. LOD 100
1. MUL #9
2. DIV #5
3. ADD #32
4. STO 101
5. HLT
```

### Esempio Calcolo Fattoriale&#x20;

Scrivere un programma per il computer di von Neumann che calcoli il fattoriale di un numero N inizialmente contenuto nella locazione di memoria di indirizzo 100, memorizzando il risultato nella locazione di memoria di indirizzo 101.

Il fattoriale di un numero naturale N (in simboli N!) è il prodotto di tutti i numeri naturali compresi tra 1 e N (N incluso); per definizione 0! = 1.

Codice in linguaggio macchina:

```nasm
0. LOD #1
1. MUL 100
2. STO 101
3. LOD 100
4. SUB #1
5. STO 100
6. JMZ 9
7. LOD 101
8. JMP 1
9. HLT
```

### Esempio If - Else Flow Control

Scrivere un programma per il computer di von Neumann che verifichi se un numero N inizialmente contenuto nella locazione di memoria 100 è un multiplo di 11; in caso affermativo dovrà inserire il valore 1 («vero») nella locazione di memoria di indirizzo 101, in caso negativo dovrà inserirvi il valore 0 («falso»).

Codice in linguaggio macchina:

```nasm
0.  LOD 100
1.  DIV #11
2.  MUL #11
3.  STO 101
4.  LOD 100
5.  SUB 101
6.  JMZ 9
7.  LOD #0
8.  JMP 10
9.  LOD #1
10. STO 101
11. HLT
```

### Esempio Ordine Grandezza Numero

L’ordine di grandezza di un numero intero è il numero di volte per cui è possibile dividere il numero stesso per 10 prima di ottenere 0 come risultato (esempio: 123 → 123 : 10 = 12 → 12 : 10 = 1 → 1 : 10 = 0, l’ordine di grandezza è 2). Scrivere un programma per il computer di von Neumann che determini l’ordine di grandezza di un numero N inizialmente contenuto nella locazione di memoria di indirizzo 100 inserendo il risultato nella locazione di memoria di indirizzo 101.

Codice in linguaggio macchina:

```nasm
0.  LOD #0
1.  STO 101
2.  LOD 100
3.  DIV #10
4.  STO 100
5.  JMZ 10
6.  LOD 101
7.  ADD #1
8.  STO 101
9.  JMP 2
10. HLT

```

### Esempio Moltiplicazione

Scrivere un programma per il computer di von Neumann che implementi l’algoritmo definito dal seguente diagramma a blocchi e determinare lo scopo dell’algoritmo.

![](/files/-MKZvqiJeVE1uY-o6E8c)

Codice in linguaggio macchina:

```nasm
0.  LOD #0
1.  STO 102
2.  LOD 100
3.  JMZ 20
4.  DIV #2
5.  MUL #2
6.  STO 99
7.  LOD 100
8.  SUB 99
9.  JMZ 13
10. LOD 102
11. ADD 101
12. STO 102
13. LOD 100
14. DIV #2
15. STO 100
16. LOD 101
17. MUL #2
18. STO 101
19. JMP 2
20. HLT
```

Il programma esegue la moltiplicazione tra `X` e `Y` con valori memorizzati all'indirizzo 100 e 101 e salva il risultato `Z` all'indirizzo 102. Utilizza l'algoritmo del cosiddetto [Metodo del Contadino Russo](https://www.wikihow.it/Svolgere-le-Moltiplicazioni-con-il-Metodo-del-Contadino-Russo).

### Paragone con linguaggio di programmazione C

Per calcolare la potenza di un numero utilizzando un computer è possibile programmarlo usando il linguaggio del processore, come nel seguente esempio, in cui inizialmente i valori della base e dell’esponente sono rispettivamente memorizzati nelle locazioni di memoria di indirizzo 100 e 101 e il valore del risultato viene memorizzato dal programma nella locazione di memoria di indirizzo 102:

```nasm
0.  LOD #1 
1.  STO 102 
2.  LOD 101 
3.  JMZ 11 
4.  LOD 100 
5.  MUL 102 
6.  STO 102 
7.  LOD 101 
8.  SUB #1 
9.  STO 101 
10. JMP 2 
11. HLT 
```

&#x20;Ma i programmatori preferiscono ricorrere a linguaggi più astratti e meno dipendenti dalle caratteristiche di uno specifico processore. Il seguente frammento di codice C effettua esattamente lo stesso calcolo (inizialmente i valori della base e dell’esponente sono rispettivamente memorizzati nelle variabili x e y e il valore della potenza viene calcolato nella variabile z):

```c
... 
int z = 1;
while (y != 0) {
    z = z  * x; 
    y--;
} 
..
```

I programmi in linguaggio C, per essere eseguiti da un particolare processore, devono essere prima «compilati»: la compilazione converte il codice sorgente in linguaggio C in istruzioni per lo specifico processore del computer su cui si intende eseguire il programma stesso.

### Il simulatore della macchina di Von Neumann

Un simulatore di macchina di Von Neumann è possibile accederci tramite applicazione web a questo indirizzo:

{% embed url="<https://vnmsim.c2r0b.ovh/en-us>" %}

Il simulatore permette di caricare il codice assembler ed eseguirlo, come se fosse la CPU che lo esegue e facendo vedere passo-passo le fasi dell'esecuzione, lo stato dei registri e lo stato della memoria.

Il simulatore a differenza del codice visto sopra, e come in effetti avviene per l'assembler reale, non utilizza l'indirizzo numerico della cella di memoria ma utilizza delle "**ETICHETTE"** ("**LABEL**" in inglese) per rappresentare gli indirizzi delle celle di memoria. &#x20;

Sarà il **compilatore** del codice assembler (**assemblatore**) che tradurrà questa "etichetta" in un valore, cioè l'indirizzo della cella di memoria, quando produrrà il codice oggetto.&#x20;

L'assemblatore, lavora a più step (fasi):

1. Nella prima fase traduce tutte le occorrenze di un etichetta, in un indirizzo di memoria: costruisce in prima fase una TABELLA DEI SIMBOLO che associa a un'etichetta un indirizzo; utilizza questa tabella per fare la traduzione;
2. Il codice ottenuto nella prima fase poi viene tradotto in codice macchina: ogni operazione viene tradotta nel proprio opportuno codice binario per produrre il codice eseguibile (codice macchina che la CPU è in grado di eseguire);

<img src="/files/d96BYLA2OF3MO7rgUGyo" alt="Prima fase del lavoro dell&#x27;assemblatore" class="gitbook-drawing">

<img src="/files/UcF7X3anfeB8eZ1fktQV" alt="tabella per la traduzione delle ETICHETTE in INDIRIZZI" class="gitbook-drawing">

Possiamo utilizzare questo simulatore per eseguire i programmi visti sopra, leggermente modificati perché utilizziamo le etichette al posto degli indirizzi di memoria: sarà il programma che eseguirà la conversione da etichette in indirizzi, prima di eseguire il codice.

> Il simulatore utilizza ancora gli indirizzi di memoria numerici per le istruzioni di "salto", mentre nell'assembler "reale" anche le istruzioni di "salto" utilizzano le etichette.&#x20;

Sotto gli esempi che possiamo provare.

### Esempio Numero per SUCCESSORE

In memoria X dato input, in Y dato output

```
LOD X 
ADD #1 
MUL X 
STO Y 
HLT
```

### Esempio Pari Dispari

In memoria X data input, in Y l'output.

```
LOD X 
DIV #2 
MUL #2 
STO T0
LOD X 
SUB T0 
JMZ 11 
LOD X
MUL #3 
ADD #1 
JMP 13 
LOD X 
DIV #2 
STO Y
HLT
```

### Esempio Somma dei primi N numeri

X l'input, Y l'output

```
LOD X 
STO Y 
SUB #1 
STO X 
JMZ 9 
ADD Y 
STO Y 
LOD X 
JMP 2 
HLT
```

### Esempio Conversione da gradi Celsius a Fahrenheit

X come input, Y l'output

```
LOD X
MUL #9
DIV #5
ADD #32
STO Y
HLT
```

### Esempio Calcolo Fattoriale

X input, Y output

```
LOD #1
MUL X
STO Y
LOD X
SUB #1
STO X
JMZ 9
LOD Y
JMP 1
HLT
```

### Esempio If - Else Flow Control

X input, Y output

```
LOD X
DIV #11
MUL #11
STO Y
LOD X
SUB Y
JMZ 9
LOD #0
JMP 10
LOD #1
STO Y
HLT
```

### Esempio Ordine di Grandezza Numero

X input, Y output

```
LOD #0
STO Y
LOD X
DIV #10
STO X
JMZ 10
LOD Y
ADD #1
STO Y
JMP 2
HLT
```

### Esempio Moltiplicazione

X, Y input e Z ouput

```
LOD #0
STO Z
LOD X
JMZ 20
DIV #2
MUL #2
STO T0
LOD X
SUB T0
JMZ 13
LOD Z
ADD Y
STO Z
LOD X
DIV #2
STO X
LOD Y
MUL #2
STO Y
JMP 2
HLT
```

### Risorse

Codice del simulatore:

{% embed url="<https://github.com/c2r0b/vnmsim>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://checksound.gitbook.io/tecnologie3/architettura-computer/esempio-architettura.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
