Unité Centrale 4 bits

publicité
Unité Centrale 4 bits
architecture d’un ordinateur
c Jacques Duma
19 octobre 2012
Ce document décrit l’architecture d’un tout petit ordinateur très simple
basé sur un processeur 4 bits.
L’application Web "UC4bits" simule cet ordinateur et permet de le faire
fonctionner de façon interactive :
Pour montrer les fonctions disponibles sur cet ordinateur et expliquer
comment les utiliser, on présente d’abord section 1 un exemple très simple
que l’on réalise pas à pas.
On décrit ensuite avec précision section 2 l’architecture de la machine,
ses registres et sa mémoire.
Puis on définit section 3 l’ensemble des seize instructions du langage de
programmation machine.
Un mode d’emploi de l’application est présenté section 4.
Enfin, pour terminer, on propose section 5 d’autres exemples classés par
ordre de difficulté croissante.
1
Table des matières
1 Exemple simple
1.1 Le problème . . . . . . . . . . . . . . . . . .
1.2 Algorithme de résolution du problème . . . .
1.3 Adaptation de l’algorithme au processeur . .
1.4 Écriture de l’algorithme en langage machine
1.5 Codage de l’algorithme en binaire . . . . . .
1.6 Programmation de la machine et tests . . .
1.7 Test de l’algorithme . . . . . . . . . . . . . .
1.8 Résumé . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2 Architecture de la machine
2.1 Registres du processeur . . . . . . . . . . . . . . . .
2.1.1 Registres de contrôle . . . . . . . . . . . . .
2.1.2 Registre de calcul et bascule de débordement
2.1.3 Registre d’Entrée/Sortie . . . . . . . . . . .
2.2 Mémoire . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Cycle d’exécution des instructions . . . . . . . . . .
3 Langage machine
3.0 0000 : STOP . . . . . . . . . . . .
3.1 0001 : JIFOVR Jump if overflow
3.2 0010 : JUMP . . . . . . . . . . . .
3.3 0011 : JIFZ Jump if zero . . . .
3.4 0100 : JIFNZ Jump if not zero .
3.5 0101 : READ . . . . . . . . . . . .
3.6 0110 : WRITE . . . . . . . . . . . .
3.7 0111 : LDA Load A . . . . . . .
3.8 1000 : STA Store A . . . . . . .
3.9 1001 : ADDA Add A . . . . . . .
3.10 1010 : SUBA Subtract A . . . . .
3.11 1011 : INC Increment . . . . . .
3.12 1100 : DEC Decrement . . . . .
3.13 1101 : LSHIFT Left shift . . . .
3.14 1110 : RSHIFT Right shift . . .
3.15 1111 : CMPL Complement . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
4
5
6
7
7
7
8
. . .
. . .
. .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
9
9
10
10
11
11
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
12
13
13
13
13
14
14
15
15
15
15
16
16
16
17
17
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4 Mode d’emploi de l’application
18
4.1 Programmation . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2 Exécution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2
4.3
Assembleur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5 Autres exemples
5.1 Complémenter bit à bit . . . . .
5.2 Clignoter les diodes N fois . . .
5.3 Additioner de deux entiers . . .
5.4 Tripler un nombre sans retenue
5.5 Tripler un nombre avec retenue
5.6 Multiplier deux nombres . . . .
5.7 Somme des N premiers entiers .
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
22
23
25
27
29
32
1
Exemple simple
Cette Unité Centrale 4 bits contrôle une mémoire de 16 octets dans laquelle on peut coder de petits programmes écrits à l’aide d’un jeu de 16
instructions machine.
Un premier exemple simple va être décrit en détail pour montrer ce qu’il
est possible de faire avec ce minuscule ordinateur.
1.1
Le problème
On se propose de lire deux nombres et d’afficher le plus grand.
En réalité, on se propose d’écrire un petit programme que l’on enregistrera
dans la mémoire de la machine. On lancera alors l’exécution de ce petit
programme. Et, en principe, il devra résoudre le problème.
Donc, précisons d’abord le sens que l’on donne à tous les mots du problème
qui a été proposé ci-dessus :
– on appelle nombre un entier compris entre 0 et 255, c’est à dire un
entier qu’il est possible de coder en binaire sur un octet.
– lire signifie que lors de l’exécution du programme une interruption se
produira pour permettre à l’utilisateur de donner un nombre à la machine qui pourra alors le lire, c’est à dire l’enregistrer dans sa mémoire.
– afficher signifie que lors de l’exécution du programme une interruption se produira pour permettre à la machine d’afficher un octet de sa
mémoire.
Les opérations d’enregistrement dans la mémoire, de lecture ou d’affichage aussi appelée Entrées/Sorties, se font sur le Panneau de commande
présenté page 18, à l’aide de 8 diodes bleues (les 8 bits d’un octet) qu’il est
possible d’allumer (mettre à 1) ou d’éteindre (mettre à 0) avant de valider la
configuration.
La conception du programme va s’effectuer pas à pas, en langage courant
d’abord, de façon symbolique ensuite, puis enfin en codant le problème en
binaire comme l’exige la machine.
On découvrira ainsi petit à petit le principe des contraintes imposées par
l’utilisation d’un ordinateur.
1.2
Algorithme de résolution du problème
Un minimum d’expérience en algorithmique permet assez facilement de
décrire la solution du problème :
4
Lire M
Lire N
Si M > N alors
Afficher M
Sinon
Afficher N
Fin
Si l’on consulte la liste des instructions disponibles section 3 page 11 on
constate l’absence d’un test de supériorité.
Pour tester que M > N il sera nécessaire de calculer la différence M − N et
de tester que cette opération s’est déroulée sans débordement.
En informatique on parle de débordement (ou overflow ) lorsqu’une opération arithmétique dépasse la capacité du processeur. Dans notre cas, comme
on traite uniquement des entiers compris entre 0 et 255, un débordement se
produira dans le calcul de M − N si N > M.
1.3
Adaptation de l’algorithme au processeur
On va réécrire l’algorithme, toujours dans un langage symbolique, mais
plus proche de celui de la machine. Dans ce qui suit, les variables représentées
par les lettres M et N représente des octets de la mémoire, mais certaines
contraintes liées à l’architecture de la machine apparaissent.
Comme il n’existe pas de test de supériorité, il faudra le remplacer par
une soustraction et un test de débordement.
Selon le résultat du test, la suite du programme sera située à deux endroits
distincts de la mémoire, donc il sera nécessaire d’effectuer un saut à une
adresse particulière de la mémoire que l’on va étiqueter.
Comme il n’est pas possible de soustraire directement des octets de la
mémoire, il faudra utiliser le registre de calcul de l’unité centrale. Ce registre
nommé A est décrit sous-section 2.1.
L’algorithme de résolution du problème va prendre la fore suivante :
Lire M
Lire N
A ← M
A ← A - N
Saut_Si_Débordement
Aller_à SUITE
Afficher N
Stop
SUITE Afficher M
Stop
5
Ci-dessus M et N représentent des variables informatiques habituelles. Pour
notre machine ces variable seron situées en mémoire aus adresses m et n.
A représente l’accumulateur, registre de calcul de l’unité centrale. suite
est une étiquette qui pointe sur une adresse mémoire, celle de l’octets qui
contiendra l’instruction Afficher m.
Lors de l’exécution normale du programme, les instructions sont exécutées
successivement, sauf lorsqu’on rencontre des instruction de saut.
L’instruction Saut_Si_Débordement est un saut conditionnel. Si il n’y a
pas de débordement lors du calcul précédent, on exécute ensuite l’instruction
suivante. Si, par contre il y a débordement, on saute l’instruction suivante
pour exécuter celle d’après.
L’instruction Aller_à suite est un saut immédiat. L’instruction exécutée ensuite sera celle qui est située à l’adresse indiquée par l’étiquette suite.
Pour continuer la mise au point du programme, il est nécessaire de comprendre comment il sera exécuté par l’unité centrale.
1.4
Écriture de l’algorithme en langage machine
Les instructions du programme seront placées dans les octets pris successivement en mémoire à partir de l’adresse 0000, c’est-à-dire l’adresse contenue
initialement dans le registre INDX après "Reset".
Pour éviter les conflits, il est usuel de placer les données dans les dernières
adresses de la mémoire.
On codera l’algorithme en deux temps, d’abord symboliquement, puis on
remplacera les symboles par des adresses mémoire effectives :
– m = 1111
– n = 1110
– suite = 1000
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
suite 1000:
1001:
....
n 1110:
m 1111:
READ
READ
LDA
SUBA
JIFOVR
JUMP
WRITE
STOP
WRITE
STOP
m
n
m
n
suite
n
m
6
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
....
1111:
READ
READ
LDA
SUBA
JIFOVR
JUMP
WRITE
STOP
WRITE
STOP
1111
1110
1111
1110
0000
1000
1110
0000
1111
0000
Le programme occupe 10 octets (adresses 0000 à 1001), et les derniers
octets de la mémoire (adresses 1010 à 1111) peuvent rester quelconques.
1.5
Codage de l’algorithme en binaire
Il ne reste plus qu’à consulter la liste des instructions, section 3 page 11,
pour remplacer le le nom symbolique de l’instruction ou mnémonique par le
code binaire et définir ainsi ce qu’il faut enregistrer en mémoire :
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
0101
0101
0111
1010
0001
0010
0110
0000
0110
0000
1111
1110
1111
1110
0000
1000
1110
0000
1111
0000
Cette phase du travail et particulièrement délicate, car il est nécessaire
de rester concentré et particulièrement attentif pour ne pas faire d’erreur.
1.6
Programmation de la machine et tests
La programmation de cette machine est aussi délicate, car les erreurs sont
difficiles à détecter à ce niveau. On se reportera à la section 4 pour un mode
d’emploi complet de l’interface. Sur le Panneau de commande on procède pas
à pas de la façon suivante :
1. clic sur le bouton "Remise à Zéro" ou sur les diodes INDX pour mettre
l’adresse à zéro
2. clic sur les diodes IO pour définir la valeur binaire d’un octet
3. clic sur le bouton "Valider" l’octet à l’adresse INDX prend la valeur
définie par les diodes, le registre INDX est automatiquement incrémenté
4. retour à l’étape 2 tant qu’il y des octets à définir
1.7
Test de l’algorithme
Une fois la machine programmée on peut lancer l’exécution du programme,
on procède pas à pas de la façon suivante :
7
1. clic sur le bouton "Remise à Zéro" puis sur le bouton "Exécuter"
interruption diodes encadrées en rouge : attente du premier nombre
2. clic sur les diodes pour définir la valeur du premier nombre
3. clic sur le bouton "Valider" seconde interruption diodes encadrées
en rouge : attente du second nombre
4. clic sur le bouton "Valider"
affichage de la réponse
interruption diodes encadrées en bleu :
5. clic sur le bouton "Continuer"
interruption sur le STOP de fin de programme
Pour vérifier la validité du programme, on fera au moins deux tests successifs, un en donnant le nombre le plus grand en premier, un autre en donnant
le nombre le plus grand en second.
1.8
Résumé
Dans cette section, nous avons vu comment concevoir un algorithme
simple, comment l’écrire en langage machine, comment le coder en binaire,
comment l’enregistrer dans la mémoire de la machine et enfin, comment le
tester lors de l’exécution.
On a constaté que la tâche à effectuer est difficile, car contrainte par le
matériel utilisé, l’architecture de la machine, la taille de la mémoire et le jeux
des instructions disponibles.
On va maintenant décrire en détail cette machine.
2
Architecture de la machine
L’ordinateur utilise un processeur à cinq registres et une mémoire vive de
16 octets. Un jeu de 16 instructions permet de le faire fonctionner.
Le pilotage de la machine s’effectue à l’aide du Panneau de commande
présenté page 18.
Les instructions seront décrites de façon précise à section 3. Il est cependant nécessaire de connaître leur structure pour bien comprendre l’architecture de la machine décrite ci-dessous page 9.
Chaque instruction est codée sur un octet placé dans la mémoire à l’adresse
codée sur un demi-octet contenue dans le registre INDX :
– le demi-octet partie haute de l’octet est le code de l’instruction
il est donc possible de coder 16 instructions distinctes
8
– le demi-octet partie basse de l’octet est l’argument de l’instruction
il représente une des 16 adresses de la mémoire
2.1
2.1.1
Registres du processeur
Registres de contrôle
Pour son fonctionnement le processeur de l’unité centrale utilise trois
registres de contrôle 4 bits :
– INDX le registre d’index aussi appelé compteur ordinal
– DKOD le registre de décodage
– ADRS le registre d’adresse
Le registre d’index INDX, aussi appelé compteur ordinal, contient l’adresse
du prochain octet de mémoire à traiter lors de l’exécution. Le bouton "Reset"
permet de le mettre à zéro. Le bouton "Exécuter" l’incrémente automatiquement après exécution de chaque instruction, sauf dans le cas d’une instruction
de saut.
Le registre de décodage DKOD contient le demi-octet de poids fort de l’octet
de mémoire en cours de traitement. Il sera interprété comme une instruction
machine à zéro ou un argument. Le code de chaque instruction machine est
précisé section 3.
Le registre d’adresse ADRS contient le demi-octet de poids faible de l’octet
de mémoire en cours de traitement. Il sera interprété comme argument de
l’instruction, adresse d’un autre octet de la mémoire. Pour les instructions
sans argument, il sera simplement ignoré.
9
2.1.2
Registre de calcul et bascule de débordement
Les instructions de cette machine n’ont qu’un seul argument.
Pour effectuer des opérations à deux arguments, comme l’addition ou la
soustraction, le processeur dispose de registres supplémentaires :
– A le registre de calcul 8 bits appelé accumulateur
– OVERFLOW une bascule 1 bit qui signale le débordement du calcul
On peut affecter au registre A la valeur d’un octet de la mémoire situé
à l’adresse m (A ← m) ou affecter à la mémoire d’adresse m la valeur de
l’accumulateur (m ← A)
On peut aussi ajouter (A ← A + m) ou soustraire (A ← A - m) au registre A la valeur d’un octet de la mémoire situé à l’adresse m.
Lors de ces opérations, un débordement peut se produire si le résultat est
inférieur à 0 ou supérieur à 255. Dans ce cas, la bascule OVERFLOW est fixée à
1, et le résultat est donné modulo 256.
Exemple d’addition : 255 + 3 donne 2 avec overflow car le reste de 258
par 256 est 2. Dans ce cas, l’overflow représente le quotient. Autrement dit,
après une addition, le vrai résultat est OVERFLOW×256+A. L’overflow joue le
rôle de retenue.
Exemple de soustraction : 23 − 7 donne 252 avec overflow car le reste de
−4 par 256 est 252. Dans ce cas, l’overflow représente l’opposé du quotient.
Après une soustraction, le vrai résultat est A−OVERFLOW×256
On verra plus loin section 3 dans la description des différentes instructions
machine, celles qui peuvent aussi provoquer un débordement.
2.1.3
Registre d’Entrée/Sortie
Pour communiquer avec l’extérieur le contenu d’un registre est visualisé
à l’aide de 8 diodes :
– IO le registres d’Entrée/Sortie 8 bits
Le registre IO (Input/Output) est utilisé pour les Entrées/Sorties. La
valeur de ce registre est visible sur le Panneau de commande page 18, comme
huit diodes bleues allumées (1) ou éteintes (0).
En mode Programmation (diode rouge allumée) le bouton "Valider"
permet de charger un programme en mémoire.
En mode Exécution (diode verte allumée) toute opération d’Entrée/Sortie
interrompt provisoirement le déroulement du programme après avoir encadré
en rouge les 8 diode du registre IO :
– Entrée ou lecture
clics pour configurer l’état des diodes, puis bouton "Valider"
10
– Sortie ou affichage
consulter l’état des diodes, puis bouton "Continuer"
Le programme interrompu continue alors à se se dérouler normalement.
2.2
Mémoire
Le registre INDX du processeur, aussi appelé compteur ordinal, permet d’adresser une mémoire de seize
octets dans laquelle on peut enregistrer des valeurs
numériques entières comprises entre 0 et 255 qui représentent, soit des données, soit les instructions d’un
tout petit programme.
Il n’y a aucune différence en mémoire entre les
données et le programme. Seule l’interprétation qu’on
en fait est significative.
Comme le bouton "Reset" permet de remettre à
zéro les registres de l’unité centrale, en particulier le
registre INDX, il est nécessaire de placer le programme
aux adresses 0000 et suivantes. Il est d’usage de placer les données aux adresses 1111 et précédentes.
2.3
Cycle d’exécution des instructions
Le cycle d’exécution de chaque instruction se décompose en 3 phases :
Phase 1 le registre INDX pointe sur l’adresse de l’octet mémoire à traiter
Phase 2 l’octet est chargé dans les registres DKOD et ADRS pour décodage
Phase 3 l’instruction correspondante est exécutée
À la fin de chaque cycle une nouvelle valeur est affectée au registre INDX.
– L’instruction STOP ne modifie pas le registre INDX ce qui revient à dire
que le processeur s’arrête sur cette instruction.
– Les instructions de saut sont décrites en détail ci-dessous. Ces instructions modifient le registre INDX d’une manière particulière.
– À la fin des autres instructions le registre INDX est incrémenté.
INDX ← INDX + 1
3
Langage machine
Cet ordinateur peut être programmé à l’aide d’un jeu de seize instructions
machine distinctes.
11
Chaque instruction machine est codée sur un octet dans la mémoire :
– Le demi-octet de poids fort de cet octet définit l’instruction
– Le demi-octet de poids faible est l’argument de l’instruction
il fait référence à une adresse mémoire
Pour être rigoureux dans la définition des instruction, on va utiliser les
notations particulières suivantes :
Les registres sont repérés par leurs noms INDX, A, IO et leur contenu est
noté entre parenthèses (INDX), (A), (IO).
adrs représente une adresse mémoire symbolique et (adrs) le contenu de
la mémoire à cette adresse (un octet).
Les seuls cas où on utilise un nom de registre ou une adresse mémoire
directement (et non leur contenu) sont :
– à gauche d’une affectation
– en argument de l’instruction de saut
Pour chaque instruction, on trouvera ci-dessous :
– le code binaire et le mnémonique suivi éventuellement du nom anglais
Exemple :
0111 : LDA Load A
– une forme symbolique précisant l’action de l’instruction
Exemple :
A ← (adrs)
– la définition détaillée du fonctionnement de l’instruction
Exemple : Cette instruction affecte le registre A avec la valeur
de l’octet pointé par adrs en mémoire.
– cette définition sous une forme algorithmique précise
A ← (adrs)
Exemple :
INDX ← (INDX) + 1
Lors de l’exécution du programme, les débordements éventuellement provoqués par les calculs seront signalés.
De plus, une interruption du programme peut survenir lors de l’incrément
du registre INDX si sa valeur dépasse 15 (sortie de la mémoire).
Voici la liste complète des seize instructions machine disponibles :
3.0
0000 : STOP
l’argument, partie basse de l’octet, est ignoré
Stop
Interruption du programme.
L’incrément automatique du registre INDX est interrompu.
INDX ← (INDX)
12
3.1
Jump if overflow
0001 : JIFOVR
l’argument, partie basse de l’octet, est ignoré
Saut_Si_Débordement
Cette instruction ne fait rien, mais la suite dépend de l’état de la bascule
OVERFLOW qui, lui-même, dépend de l’exécution de l’instruction précédente.
Si OVERFLOW = 1 alors
on saute l’instruction suivante et on continue à celle d’après
INDX ← (INDX) + 2
sinon (OVERFLOW) = 0 alors
on continue à l’instruction suivante
INDX ← (INDX) + 1
fin_Si
3.2
0010 : JUMP
Aller_à adrs
Saut immédiat sans condition à l’adresse donnée comme argument
INDX ← adrs
Attention : ici, c’es bien la valeur adrs qui est affectée au registe INDX et
non pas le contenu de la mémire à cette adresse.
3.3
0011 : JIFZ
Jump if zero
Saut_Si_Zéro (adrs)
Cette instruction ne fait rien, mais la suite dépend de la valeur de l’octet
pointé par adrs en mémoire.
Si (adrs) = 0 alors
on saute l’instruction suivante et on continue à celle d’après
INDX ← (INDX) + 2
sinon (adrs) 6= 0 alors
on continue à l’instruction suivante
INDX ← (INDX) + 1
fin_Si
3.4
0100 : JIFNZ
Jump if not zero
Saut_Si_Non_Zéro (adrs)
13
Cette instruction ne fait rien, mais la suite dépend de la valeur de l’octet
pointé par adrs en mémoire.
Si (adrs) 6= 0 alors
on saute l’instruction suivante et on continue à celle d’après
INDX ← (INDX) + 2
sinon (adrs) = 0 alors
on continue à l’instruction suivante
INDX ← (INDX) + 1
fin_Si
3.5
0101 : READ
Lire adrs
Cette instruction interrompt le déroulement du programme dans l’attente
d’une donnée fournie par l’utilisateur.
Sur le Panneau de commande les diodes sont éteintes et encadrées en
rouge. L’utilisateur peut modifier leur état par des clics. Comme les diodes
sont synchronisées avec le registre IO l’utilisateur définit ainsi son état.
Le bouton "Valider" permet alors d’affecter cette valeur à la mémoire
dont l’adresse est argument de l’instruction, avant de continuer
IO ← 0
...interruption... puis "Valider"
adrs ← (IO)
INDX ← (INDX) + 1
3.6
0110 : WRITE
Afficher (adrs)
Cette instruction interrompt le déroulement du programme pour laisser
à l’utilisateur le temps de lire une réponse.
Le contenu de la mémoire dont l’adresse est argument de l’instruction est
affecté au registre IO qui est synchronisé avec les diodes. Celle-ci sont alors
encadrées en rouge, puis l’interruption se produit.
Dès que l’utilisateur a consulté l’état des diodes, le bouton "Continuer"
permet reprendre l’exécution du programme.
IO ← (adrs)
...interruption... puis "Continuer"
INDX ← (INDX) + 1
14
3.7
0111 : LDA
Load A
A ← (adrs)
Cette instruction affecte le registre A avec la valeur de l’octet pointé par
adrs en mémoire.
A ← (adrs)
INDX ← (INDX) + 1
3.8
1000 : STA
Store A
adrs ← (A)
Cette instruction affecte l’octet de la mémoire pointé par adrs avec la
valeur du registre A .
adrs ← (A)
INDX ← (INDX) + 1
3.9
1001 : ADDA
Add A
A ← (A) + (adrs)
Cette instruction ajoute à l’accumulateur A la valeur de l’octet pointé par
adrs en mémoire. Un débordement éventuel est signalé.
Si (A) + (adrs) > 255 alors
débordement
OVERFLOW ← 1
A ← (A) + (adrs) - 256
somme modulo 256
sinon
OVERFLOW ← 0
A ← (A) + (adrs)
fin_Si
INDX ← (INDX) + 1
3.10
1010 : SUBA
Subtract A
A ← (A) - (adrs)
Cette instruction retranche à l’accumulateur A la valeur de l’octet pointé
par adrs en mémoire. Un débordement éventuel est signalé.
15
Si
(A) - (adrs) < 0 alors
OVERFLOW ← 1
A ← (A) - (adrs) + 256
sinon
OVERFLOW ← 0
A ← (A) - (adrs)
fin_Si
INDX ← (INDX) + 1
3.11
1011 : INC
débordement
somme modulo 256
Increment
adrs ← (adrs) + 1
Cette instruction incrémente l’octet pointé par adrs en mémoire. Un débordement éventuel est signalé.
Si (adrs) = 255 alors
débordement
OVERFLOW ← 1
adrs ← 0
sinon
OVERFLOW ← 0
adrs ← (adrs) + 1
fin_Si
INDX ← (INDX) + 1
3.12
1100 : DEC
Decrement
adrs ← (adrs) - 1
Cette instruction décrémente l’octet pointé par adrs en mémoire. Un
débordement éventuel est signalé.
Si adrs = 0 alors
débordement
OVERFLOW ← 1
adrs ← 255
sinon
OVERFLOW ← 0
adrs ← (adrs) - 1
fin_Si
INDX ← (INDX) + 1
3.13
1101 : LSHIFT
Left shift
adrs ← (adrs) × 2
16
Cette instruction décale vers la gauche les bits de l’octet pointé par adrs
en mémoire.
Cette opération correspond à une multiplication par 2 de la valeur.
Un débordement éventuel est signalé si le bit de poids fort est à 1 et qu’il
disparaît lors du décalage (c’est à dire pour une valeur supérieure à 127).
(adrs) > 127 alors
débordement
OVERFLOW ← 1
adrs ← (adrs) × 2 - 256
sinon
OVERFLOW ← 0
adrs ← (adrs) × 2
fin_Si
INDX ← (INDX) + 1
Si
3.14
1110 : RSHIFT
Right shift
adrs ← (adrs) ÷ 2
Cette instruction décale vers la droite les bits de l’octet pointé par adrs
en mémoire.
Cette opération correspond à une division entière par 2 de la valeur.
Un débordement éventuel est signalé si le bit de poids faible est à 1 et
qu’il disparaît lors du décalage (c’est à dire si on divise une valeur impaire).
Si
(adrs) est impair alors
OVERFLOW ← 1
adrs ← ((adrs) - 1) ÷ 2
sinon
OVERFLOW ← 0
adrs ← (adrs) ÷ 2
fin_Si
INDX ← (INDX) + 1
3.15
1111 : CMPL
débordement
Complement
adrs ← (adrs)
Cette instruction effectue le complément bit à bit de l’octet pointé par
adrs en mémoire.
adrs ← 255 - (adrs)
INDX ← (INDX) + 1
17
4
4.1
Mode d’emploi de l’application
Programmation
En mode "Programme", on voit sur le panneau
de commande les quatre diodes du demi-octet du registre INDX encadrées en vert.
Clic sur le bouton "Remise à Zéro" éteint toute
les diodes et permet de sélectionner la première
adresse de la mémoire. Clic sur les diodes du registre
INDX permet de sélectionner une adresse quelconque.
Les huit diodes du registre IO encadrées en vert
permettent, de même, de définir la valeur d’un octet.
Clic sur le bouton "Valider" pour charger dans
la mémoire à l’adresse définie par le registre INDX la
valeur définie par le registre IO.
Le registre INDX est automatiquement incrémenté
à la fin de cet enregistrement. On peut suivre sur
le panneau "Mémoire vive" le bon déroulement des
opérations.
4.2
Exécution
Une fois le programme enregistré en mémoire, un clic sur la diode de mode
permet de passer en mode "Exécution", la diode de mode devient rouge :
Le bouton "•" en haut à droite du panneau de commande est le bouton
"Reset" de la machine. Il est toujour disponible et permet éventuellement
d’interrompre un programme qui boucle.
18
Lors du passage en mode "Exécution", le panneau de l’unité centrale
apparaît sous le panneau de commande :
Pour exécuter un programme, on fixe l’adresse de départ à l’aide des
diodes du registre INDX ou avec le bouton "Remise à Zéro".
Il y a ensuite deux façons d’exécuter le code en mémoire :
– clic sur le bouton "Exécuter" lance un exécution automatique rapide
Cette exécution peut être interrompue :
– par une lecture... clic sur le bouton "Valider" pour continuer
– par un affichage... clic sur le bouton "Continuer"
– par un STOP de fin de programme
– par une erreur de sortie de la mémoire
– par un clic sur le bouton "•" de reset.
– clic sur le bouton "Pas à Pas" lance l’exécution d’une instruction :
– cette instruction s’exécute phase par phase
– un clic sur "Pas à Pas" est nécessaire à chaque phase pour continuer
– des messages sont affichés en bas de l’écran pour décrire le fonctionnement de l’unité centrale
4.3
Assembleur
Pour des programmes un peu complexes, la programmation en binaire sur
le panneau de commande est un peu fastidieuse. On propose donc une façon
de programmer plus souple grâce à l’assembleur.
en haut à droite
Pour pouvoir utiliser l’assembleur : clic sur le bouton
de la fenêtre.
19
Dans les exemples présentés à la section 5 on utilise dans les paragraphes
« Écriture de l’algorithme en langage machine » un langage symbolique
simple dans lequel les adresses de la mémoire sont simplement étiquetées symboliquement, mais pas calculée explicitement. Il est possible de programmer
la machine en utilisant ce langage.
En haut de la fenêtre on voit deux boutons : "Dump" et "Assembleur".
il ouvrent une fenêtre d’édition de texte qui affiche le contenu de la mémoire
de façon plus lisible :
– "Dump" affiche le contenu de la mémoire avec chaque ligne sous la forme
<adresse>: <instruction> <argument> avec :
– <adresse>: un entier entre 0 et 15 en binaire ou en décimal
– <instruction> un mnémonique ou un entier entre 0 et 15
– <argument> un entier entre 0 et 15 en binaire ou en décimal
– "Assembleur" affiche le contenu de la mémoire exprimé dans le langage
symbolique « Assembleur » de la machine
Inversement, on peut écrire dans fenêtre d’édition de texte un programme
indifféremment sous formes numérique ou symbolique.
Le bouton "Enregistrer" place les données en mémoire si elles sont
correctes. En cas d’erreur, des messages sont affichés pour faciliter la mise au
point du programme.
Lorsque la fenêtre d’édition est ouverte, un menu propose de charger
automatiquement les programmes des exercices présenté section 5.
À titre d’exemple utilisons l’exercice « Multiplier deux nombres » présenté page 29 pour préciser les différentes formes sous lesquelles le programme
peut être écrit :
Le programme peut être entré en mémoire ainsi :
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
READ
READ
RSHIFT
JIFOVR
JUMP
ADDA
LSHIFT
JIFZ
JUMP
STA
WRITE
STOP
1111
1110
1110
0000
0110
1111
1111
1110
0010
1101
1101
0000
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
20
0101
0101
1110
0001
0010
1001
1101
0011
0010
1000
0110
0000
1111
1110
1110
0000
0110
1111
1111
1110
0010
1101
1101
0000
0:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
5
5
14
1
2
9
13
3
2
8
6
0
15
14
14
0
6
15
15
14
2
13
13
0
Avec cette syntaxe les trois champs sont toujours obligatoires à chaque
ligne, mais on peut écrire les nombres, soit en binaire (avec 4 chiffres obligatoires) soit en décimal (0 à 15).
En assembleur, on l’écrira plus simplement :
READ
READ
debut RSHIFT
JIFOVR
JUMP
ADDA
suite LSHIFT
JIFZ
JUMP
STA
WRITE
STOP
m
n
n
suite
m
m
n
debut
p
p
Les adresses symboliques seront automatiquement remplacées par les adresses
numériques effectives.
5
Autres exemples
Les exemples suivants sont classés par ordre de difficulté croissante.
Le premier exemple « Complément bit à bit » page 21 est élémentaire et
permet de se familiariser avec la machine. Le dernier exemple « Somme des
N premiers entiers » page 32 est un des plus complexe qu’il est possible de
réaliser sur cette machine, compte tenu de la faible capacité de sa mémoire.
5.1
Complémenter bit à bit
Le problème
Lire un octet,
afficher son complément bit à bit.
Algorithme de résolution du problème
Le problème ne présente aucune difficulté :
Lire M
Complémenter M
Afficher M
Stop
21
Adaptation de l’algorithme au processeur et codage en binaire
On peut effectuer une traduction immédiate de l’algorithme et le coder
en binaire ensuite :
0000:
0001:
0010:
0011:
READ
CMPL
WRITE
STOP
1111
1111
1111
0000
0000:
0001:
0010:
0011:
0101
1111
0110
0000
0100
0100
0100
0000
Le test du programme ne présente pas de difficulté.
5.2
Clignoter les diodes N fois
Le problème
Entrer un entier N,
faire clignoter les diodes N fois
Algorithme de résolution du problème
Lire N
M ← 0
Lire N
Tant_Que N > 0 faire
M ← Complément(M)
Afficher M
N ← N - 1
Fin_Tant_Que
Stop
Adaptation de l’algorithme au processeur
M ← A
Lire N
BOUCLE Complémenter M
Afficher M
N ← N - 1
Saut_Si_Zéro N
Aller_à BOUCLE
Stop
zéro dans M
si N=0 c’est fini
si N6=0 on continue
Écriture de l’algorithme en langage machine
Codage d’abord symbolique, puis avec adresses mémoire effectives :
22
0000:
STA
m
0001:
READ n
0010: boucle CMPL m
0011:
WRITE m
0100:
DEC
n
0101:
JIFZ n
0110:
JUMP boucle
0111:
STOP
1000: m
1001: n
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
STA
READ
CMPL
WRITE
DEC
JIFZ
JUMP
STOP
....
....
1000
1001
1000
1000
1001
1001
0010
0000
Codage de l’algorithme en binaire
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000
0101
1111
0110
1100
0011
0010
0000
1000
1001
1000
1000
1001
1001
0010
0000
Tests
Après avoir entré un entier à l’aide des diodes IO puis clic sur le bouton
"Valider" les diodes IO seront successivement allumées puis éteintes après
chaque clic sur le bouton "Continuer" jusqu’à l’interruption du programme.
5.3
Additioner de deux entiers
Le problème
Entrer deux entiers M et N , afficher M + N
Algorithme de résolution du problème
La somme de deux entiers codés chacun sur un octet (c’est à dire compris
entre 0 et 255) peut dépasser 255 et occasionner un débordement. La réponse
sera donc donnée par affichage de deux octets successivement :
1. R la retenue : 0 si la somme est inférieure à 256 et 1 sinon
2. S la somme modulo 256 (sans la retenue)
23
R ← 0
Lire M
Lire N
S ← M + N
Si overflow faire
R ← R + 1
Fin_Si
Afficher R
Afficher S
Fin
Adaptation de l’algorithme au processeur
R ← A
Lire M
A ← M
Lire N
A ← A + N
Saut_Si_Overflow
Aller_à SUITE
R ← R + 1
SUITE Afficher R
S ← A
Afficher S
Stop
zéro dans la retenue R
somme
si overflow, retenue
sinon affichage
retenue
somme
Écriture de l’algorithme en langage machine
Codage d’abord symbolique, puis avec adresses mémoire effectives :
24
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
r
READ m
LDA
m
READ n
ADDA n
JIFOVR
JUMP suite
INC
r
suite WRITE r
STA
s
WRITE s
STOP
r
s
n
m
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
READ
LDA
READ
ADDA
JIFOVR
JUMP
INC
WRITE
STA
WRITE
STOP
....
....
....
....
1100
1110
1110
1111
1111
0000
1000
1100
1100
1101
1101
0000
Codage de l’algorithme en binaire
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1000
0101
0111
0101
1001
0001
0010
1011
0110
1000
0110
0000
1100
1110
1110
1111
1111
0000
1000
1100
1100
1101
1101
0000
Tests
Pour vérifier le calcul de la retenue, on effectuera au moins deux tests :
– un avec une somme inférieure à 256
– un avec une somme supérieure à 256
5.4
Tripler un nombre sans retenue
Le problème
Entrer un entiers N ,
afficher 3 × N
25
Dans ce premier exemple simple, on donnera un nombre N inférieur à 86,
de façon à ce que son triple soit inférieur à 256. En effet dans cet exemple,
on ignore les débordements éventuels.
On trouvera ci-dessous sous-section 5.5 le même problème dans lequel les
retenues sont prises en compte dans les calculs.
Algorithme de résolution du problème
Pour effectuer des multiplications en binaire, on effectue des décalages bit
à bit et des additions. En effet un décalage vers la gauche des bits d’un octet
correspond à une multiplication par 2.
La multiplication de N par 3 sera effectuée comme la somme de N avec
2 × N , c’est à dire N décalé vers la gauche :
Lire N
A ← N
N ← N × 2
A ← A + N
N ← A
Afficher N
Fin
Écriture de l’algorithme en langage machine
0000:
0001:
0010:
0011:
0100:
0101:
0110:
....
1111: n
READ
LDA
LSHIFT
ADDA
STA
WRITE
STOP
n
n
n
n
n
n
0000:
0001:
0010:
0011:
0100:
0101:
0110:
....
1111:
Codage de l’algorithme en binaire
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0101
0111
1101
1001
1000
0110
0000
26
1111
1111
1111
1111
1111
1111
0000
READ
LDA
LSHIFT
ADDA
STA
WRITE
STOP
....
1111
1111
1111
1111
1111
1111
0000
5.5
Tripler un nombre avec retenue
Le problème
Entrer un entiers N ,
afficher 3 × N
Dans cet exemple les retenues sont prises en compte dans les calculs.
Algorithme de résolution du problème
On teste les débordements éventuels après les opérations de décalage à
gauche et d’addition.
On utilise une mémoire R pour les retenues éventuelles. En fin de programme on affiche successivement la mémoire de retenue puis le produit.
R ← 0
Lire N
A ← N
N ← N × 2
Si overflow faire
R ← R + 1
Fin_Si
A ← A + N
Si overflow faire
R ← R + 1
Fin_Si
Afficher R
N ← A
Afficher N
Fin
Adaptation de l’algorithme au processeur
On utilise la variable R pour cumuler les retenus éventuelles. Le produit
est effectué dans l’accumulateur A.
On affiche ensuite successivement R qui est la partie haute de la réponse
et A la partie basse, c’est a dire que le triple de N est égal à 256 × R + A.
27
R ← A
Lire N
A ← N
N ← N × 2
Saut_Si_Overflow
Aller_à SUITE
R ← R + 1
SUITE A ← A + N
Saut_Si_Overflow
Aller_à FIN
R ← R + 1
FIN
Afficher R
N ← A
Afficher N
Stop
zéro dans la retenue R
décalage à gauche
si overflow, retenue
sinon somme
si overflow, retenue
sinon affichage
retenue
triple
Écriture de l’algorithme en langage machine
Codage d’abord symbolique, puis avec adresses mémoire effectives :
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
READ
LDA
LSHIFT
JIFOVR
JUMP
INC
suite ADDA
JIFOVR
JUMP
INC
fin
WRITE
STA
WRITE
r
n
r
n
n
n
suite
r
n
fin
r
r
n
n
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
READ
LDA
LSHIFT
JIFOVR
JUMP
INC
ADDA
JIFOVR
JUMP
INC
WRITE
STA
WRITE
....
....
1110
1111
1111
1111
0000
0111
1110
1111
0000
1011
1110
1110
1111
1111
On remarquera une petite astuce de programmation. En raison du manque
de place en mémoire l’instruction STOP de fin de programme a été omise.
L’octet d’adresse 1110: qui suit l’instruction WRITE du dernier affichage
est utilisé pour calculer la retenue. Cet octet est initialisé à 0 à la première
instruction du programme et peut être incrémenté une ou deux fois selon les
cas. Sa valeur ne dépassera donc pas 2 c’est à dire 0000 0010.
28
On remarque donc que l’octet d’adresse 1110 a toujours dans son demioctet en partie haute la valeur 0000. le décodage de cette valeur comme
instruction est interprété comme un STOP. Le programme s’arrêtera donc.
Cette astuce montre bien que la mémoire contient indifféremment des
données ou des instructions, et que seule l’interprétation qui en est faite à un
instant donné est significative.
Codage de l’algorithme en binaire
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1000
0101
0111
1101
0001
0010
1011
1001
0001
0010
1011
0110
1000
0110
1110
1111
1111
1111
0000
0111
1110
1111
0000
1011
1110
1110
1111
1111
Tests
Pour vérifier la validité du résultat, on testera avec au moins deux exemples,
un sans retenue et un avec retenue.
Voici quelques jeux de valeurs possibles :
• N = 0000 0101 (5) → 0000 0000/0000 1111 (0 × 256 + 15 = 15)
• N = 1111 1111 (255) → 0000 0010/1111 1101 (2 × 256 + 253 = 765)
• N = 1000 0000 (128) → 0000 0001/1000 0000 (1 × 256 + 128 = 184)
5.6
Multiplier deux nombres
Nous avons vu précédemment comment multiplier par 3. On peut aussi
multiplier deux nombres quelconques avec une méthode similaire.
Le problème
Entrer deux entier M et N,
afficher le produit M × N .
29
On procède par étape. Le multiplicande est multiplié par 2 à chaque
étape, et, simultanément on effectue la division entière du multiplicateur par
2. On accumule les valeurs successives du multiplicande à chaque fois que le
multiplicateur est impair.
Exemple : M × N = 123 × 70 = 8610
multiplicande multiplicateur
reste
M ×2
N ÷ 2 N modulo 2 somme partielle
123
70
0
0 × 123) + 0
246
35
1
1 × 246 + 0
492
17
1
1 × 492 + 246
984
8
0
0 × 984 + 738
1968
4
0 0 × 1968 + 738
3936
2
0 0 × 3936 + 738
7872
1
1 1 × 7872 + 738
123 × 70 =
8610
Algorithme de résolution du problème
A ← 0
Lire M
Lire N
Tant_Que N > 0 faire
M ← M × 2
Si N impair faire
A ← A + M
Fin_Si
N ← N ÷ 2
Fin_Tant_Que
Afficher A
Stop
Adaptation de l’algorithme au processeur
Une adaptation de l’algorithme est vraiment nécessaire, car on ne dispose
de condition sur la parité. Mais, la valeur d’un octet est paire si son bit de
droite est 0, et sa valeur est impaire si son bit de droite est 1. Si on effectue
un décalage à droite bit à bit, il y a débordement dans le cas où le bit de
droite est 1, et donc le test de débordement informe sur la parité.
Le test d’arrêt de la boucle portera sur la nullité du multiplicateur.
On peut réécrire l’algorithme ainsi :
30
Lire M
Lire N
DEBUT N ← N ÷ 2
Saut_Si_Overflow
Aller_à SUITE
A ← A + M
SUITE M ← M × 2
Saut_Si_Zéro N
Aller_à DEBUT
P ← A
Afficher P
Stop
On remarque que le résultat est accumulé dans le registre A et qu’il ne
peut donc pas dépasser la valeur 256.
La gestion des débordements et des retenues dans le calcul n’est hélas pas
possible dans une mémoire aussi petite.
Écriture de l’algorithme en langage machine
Codage d’abord symbolique, puis avec adresses mémoire effectives :
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
READ
READ
debut RSHIFT
JIFOVR
JUMP
ADDA
suite LSHIFT
JIFZ
JUMP
STA
WRITE
STOP
p
n
m
m
n
n
suite
m
m
n
debut
p
p
...
...
...
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
READ
READ
RSHIFT
JIFOVR
JUMP
ADDA
LSHIFT
JIFZ
JUMP
STA
WRITE
STOP
....
....
....
....
1111
1110
1110
0000
0110
1111
1111
1110
0010
1101
1101
0000
Cette multiplication ne donnera un résultat correct que si le produit des
deux nombres est inférieur à 256. Dans le cas contraire le résultat sera en
réalité affiché modulo 256.
31
Codage de l’algorithme en binaire
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
0101
0101
1110
0001
0010
1001
1101
0011
0010
1000
0110
0000
1111
1110
1110
0000
0110
1111
1111
1110
0010
1101
1101
0000
Tests
Pour vérifier la validité du programme, on utilisera de petits nombres
pour ne pas dépasser les capacités de calcul.
Voici quelques jeux de valeurs possibles :
• M = 0000 0101 (5) N = 0000 0110 (6)
• M = 0111 1111 (127) N = 0000 0010 (2)
• M = 0000 1111 (15) N = 0000 0111 (7)
→ M × N = 0001 1110 (30)
→ M × N = 1111 1110 (254)
→ M × N = 0110 1001 (105)
Par contre on ne sera pas surpris par :
• M = 0001 0000 (16) N = 0001 0000 (16) → M × N = 0000 0000 (256)
Et on pourra vérifier en calculant modulo 256 que :
• M = 0101 0101 (85) N = 1010 1010 (170) → M × N = 0111 0010 (114)
5.7
Somme des N premiers entiers
Cet exercice est un des plus complexe qu’il est possible de réaliser sur
cette machine, compte tenu de la faible capacité de sa mémoire.
On va procéder pas à pas, comme dans l’exemple de la section 1, pour
concevoir l’algorithme et écrire le programme.
Le problème
Lire un nombre N.
Afficher la somme des entiers de 1 à N.
Algorithme de résolution du problème
Voici un algorithme pour résoudre le problème :
32
Lire N
A ← 0
Tant_Que N > 0
A ← A + N
N ← N - 1
Fin_Tant_Que
Afficher A
Stop
faire
Évidement, cet algorithmique n’est pas adapté à notre machine. Il faut
prendre en compte certaines contraintes :
– A ← 0 est inutile, car effectué lors du "Reset"
– Afficher A n’est pas possible, il faut d’abord affecter la valeur en
mémoire avant de l’afficher
Mais surtout, la somme des entiers de 1 à N (avec N de 0 à 255), peut
être un entier supérieure à 255. Le résultat doit être donné sur deux octets.
La somme doit être effectuée en tenant compte des retenues (débordements)
dans le calcul.
Adaptation de l’algorithme au processeur
Dans ce qui suit, la somme sera effectuée dans l’accumulateur A.
Lors des additions, si des débordements ont lieu, les retenues seront accumulées dans la variable H.
Le registre A étant à zéro au départ, il sera affectée à la variable H pour
l’initialiser aussi à zéro avant de commencer le calcul.
L’affichage de la réponse se fera par les affichages successifs de la variable
H, partie haute de la réponse et du registre A, partie basse de la réponse.
Voici un algorithme, assorti de quelques commentaires, qui tient compte
des contraintes imposées par le processeur en utilisant les instructions symboliques proposées dans la section 3 :
33
R ← A
zéro dans R
Lire N
DEBUT Saut_Si_Non_Zéro N
Aller_à FIN
si N=0
A ← A + N
si N6=0 on accumule
Saut_Si_Débordement
Aller_à SUITE
pas de retenue
R ← R + 1
retenue dans R
SUITE N ← N - 1
on décrémente N
Aller_à DEBUT
et on recommence
FIN
Afficher R
réponse partie haute
R ← A
Afficher R
réponse partie basse
Stop
Tel qu’il est, ce programme peut facilement être codé en langage machine.
Écriture de l’algorithme en langage machine
Codage d’abord symbolique, puis avec adresses mémoire effectives :
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
READ
debut JIFNZ
JUMP
ADDA
JIFOVR
JUMP
INC
suite DEC
JUMP
fin
WRITE
STA
WRITE
STOP
r
n
r
n
n
fin
n
suite
r
n
debut
r
r
r
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1110:
1111:
STA
READ
JIFNZ
JUMP
ADDA
JIFOVR
JUMP
INC
DEC
JUMP
WRITE
STA
WRITE
STOP
....
....
1110
1111
1111
1010
1111
0000
1000
1110
1111
0010
1110
1110
1110
0000
Codage de l’algorithme en binaire
Il ne reste plus qu’à remplacer les mnémoniques par le code binaire pour
définir ce qu’il faut enregistrer en mémoire :
34
0000:
0001:
0010:
0011:
0100:
0101:
0110:
0111:
1000:
1001:
1010:
1011:
1100:
1101:
1000
0101
0100
0010
1001
0001
0010
1011
1100
0010
0110
1000
0110
0000
1110
1111
1111
1010
1111
0000
1000
1110
1111
0010
1110
1110
1110
0000
Tests
On pourra tester sur quelques jeux de valeurs, par exemple :
• N = 0000 0011 (3) → 0000 0000/0000 0110 (0 × 256 + 6 = 6)
• N = 1111 1111 (255) → 0111 1111/1000 0000 (127 × 256 + 128 = 32640)
• N = 0101 0101 (85) → 0000 1110/0100 0111 (14 × 256 + 71 = 3655)
• N = 0101 1010 (90) → 0000 1111/1111 1111 (15 × 256 + 255 = 4095)
35
Téléchargement