Il Microprocessore

Le istruzioni del microprocessore


Anche il più piccolo e semplice microprocessore (come quello che abbiamo visto in precedenza) deve avere un set di istruzioni che può eseguire. Ogni istruzione è in pratica una serie di bits che vengono caricati di volta in volta nel registro istruzioni. Ovviamente è quasi impossibile memorizzare delle sequenze di 0 e 1 e ricordarle, quindi per facilitare la programmazione dei microprocessori vengono ridefiniti usando delle brevi parole (short words).


Questa collezione di brevi parole formano il linguaggio assembler. Attraverso un traduttore assembler è possibile successivamente trasformare ogni singola "parola" in sequenze di bits che vengono inserite in memoria per essere eseguite dal microprocessore.

Ecco una sequenza di possibili parole che potrebbero essere create per il nostro microprocessore di esempio:
  • LOADA mem - Carica il registro A con un valore di memoria
  • LOADB mem - Carica il registro B con un valore di memoria
  • CONB con - Carica il registro B con una costante
  • SAVEB mem - Salva il registro B in un indirizzo di memoria
  • SAVEC mem - Salva il registro C in un indirizzo di memoria
  • ADD - Somma A e B e mette il risultato in C
  • SUBD - Sottrae B da A e mette il risultato in C
  • MUL - Moltiplica A e B e mette il risultato in C
  • DIV - Divide A con B e mette il risultato in C
  • COMP - Confronta A e B e mette il risultato in C
  • JUMP addr - Salta ad un indirizzo
  • JEQ addr - Salta ad un indirizzo se uguale
  • JNEQ addr - Salta ad un indirizzo se non uguale
  • JG addr - Salta ad un indirizzo se maggiore
  • JL addr - Salta ad un indirizzo se minore
  • STOP - Ferma l'esecuzione

Ecco un esempio di programma in Assembler:

// Assume a is at address 128
// Assume F is at address 129
0   CONB 1      // a=1;
1   SAVEB 128
2   CONB 1      // f=1;
3   SAVEB 129
4   LOADA 128   // if a > 5 the jump to 17
5   CONB 5
6   COM
7   JG 17
8   LOADA 129   // f=f*a;
9   LOADB 128
10  MUL
11  SAVEC 129
12  LOADA 128   // a=a+1;
13  CONB 1
14  ADD
15  SAVEC 128
16  JUMP 4       // loop back to if
17  STOP



Come abbiamo già detto ogni singola parola deve essere definita nella ROM con il corrispondente valore numerico (detto opcode). Ecco un esempio di codifica:

LOADA - 1 
LOADB - 2 
CONB - 3 
SAVEB - 4 
SAVEC mem - 5 
ADD - 6 
SUB - 7 
MUL - 8 
DIV - 9 
COM - 10 
JUMP addr - 11 
JEQ addr - 12 
JNEQ addr - 13 
JG addr - 14 
JGE addr - 15 
JL addr - 16 
JLE addr - 17 
STOP - 18 

Il nostro programma, codificato opportunamente sostituendo ad ogni parola il corrispndente opcode diventerà così:

// Assume a is at address 128
// Assume F is at address 129
Addr opcode/value
0    3             // CONB 1
1    1
2    4             // SAVEB 128
3    128
4    3             // CONB 1
5    1
6    4             // SAVEB 129
7    129
8    1             // LOADA 128
9    128
10   3             // CONB 5
11   5
12   10            // COM
13   14            // JG 17
14   31
15   1             // LOADA 129
16   129
17   2             // LOADB 128
18   128
19   8             // MUL
20   5             // SAVEC 129
21   129
22   1             // LOADA 128
23   128
24   3             // CONB 1
25   1
26   6             // ADD
27   5             // SAVEC 128
28   128
29   11            // JUMP 4
30   8
31   18            // STOP

Il programma che abbiamo appena visto è in realtà una semplice routine che calcola il fattoriale di un numero. In altri linguaggi (Visual Basic o C) l'avremmo scritta con 10 o al massimo 15 righe. In assembler come visto ne occorrono 17 che poi diventano 31 bytes in ROM/RAM.

Il componente del microprocessore che poi legge e traduce questi opcode in una serie di segnali che muovono i differenti componenti del processore è l' instruction decoder.