Afin de mettre en pratique ce que nous avons étudié dans le cours "Modèle d'architecture de von Neumann", nous allons utiliser un simulateur développé par Peter L Higginson. Ce simulateur est basé sur une architecture de von Neumann. Nous allons trouver dans ce simulateur :
Une version en ligne de ce simulateur est disponible ici :
Voici ce que vous devriez obtenir en vous rendant à l'adresse indiquée ci-dessus :
Il est relativement facile de distinguer les différentes parties du simulateur :
Revenons sur les parties RAM et CPU
Par défaut le contenu des différentes cellules de la mémoire est en base 10 (entier signé), mais d'autres options sont possibles : base 10 (entier non-signé, "unsigned"), base 16 ("hex"), base 2 ("binary"). On accède à ces options à l'aide du bouton "OPTIONS" situé en bas dans la partie gauche du simulateur.
À l'aide du bouton "OPTIONS", passez à un affichage en binaire.
Comme vous pouvez le constater, chaque cellule de la mémoire comporte 32 bits (nous avons vu que classiquement une cellule de RAM comporte 8 bits). Chaque cellule de la mémoire possède une adresse (de 000 à 199), ces adresses sont codées en base 10.
Vous pouvez repasser à un affichage en base 10 (bouton "OPTION"->"signed")
Dans la partie centrale du simulateur, nous allons trouver en allant du haut vers le bas :
Nous ne nous intéresserons pas aux autres composants de la partie CPU
Comme déjà dit plus haut, la partie de gauche permet de saisir des programmes en assembleur. L'assembleur du simulateur correspond exactement à l'assembleur que nous avons présenté dans l'introduction, n'hésitez pas à consulter cette partie.
Dans la partie "éditeur" ("Langage Assembleur") saisissez les lignes de codes suivantes
MOV R0,#42 STR R0,150 HALT
Une fois la saisie terminée, cliquez sur le bouton "Enregistrer". Vous devriez voir apparaitre des nombres "étranges" dans les cellules mémoires d'adresses 000, 001 et 002 :
L'assembleur a fait son travail, il a converti les 3 lignes de notre programme en instructions machines, la première instruction machine est stockée à l'adresse mémoire 000 (elle correspond à "MOV R0,#42" en assembleur), la deuxième à l'adresse 001 (elle correspond à "STR R0,150" en assembleur) et la troisième à l'adresse 002 (elle correspond à "HALT" en assembleur) Pour avoir une idée des véritables instructions machines, vous devez repasser à un affichage en binaire ((bouton "OPTION"->"binary")). Vous devriez obtenir ceci :
Nous pouvons donc maintenant affirmer que :
Au passage, pour l'instruction machine "11100011 10100000 00000000 00101010", vous pouvez remarquer que l'octet le plus à droite, (00101010)2, est bien égale à (42)10 !
Repassez à un affichage en base 10 afin de faciliter la lecture des données présentes en mémoire.
Il n'est pas question d'apprendre à programmer en assembleur dans ce cours, mais voici tout de même quelques exemples d'instructions en assembleur :
LDR R1,78
Place la valeur stockée à l'adresse mémoire 78 dans le registre R1 (par souci de simplification, nous continuons à utiliser des adresses mémoire codées en base 10)
STR R3,125
Place la valeur stockée dans le registre R3 en mémoire vive à l'adresse 125
INP R0, 2
Saisit un nombre dans le registre R0
OUT R0, 4
Affiche en sortie le registre R0. Pour OUT, le 4 est traité comme signé, le 5 comme non signé, le 6 comme hexadécimal ou le 7 comme caractères.
ADD R1,R0,#128
Additionne le nombre 128 (une valeur immédiate est identifiée grâce au symbole #) et la valeur stockée dans le registre R0, place le résultat dans le registre R1
ADD R0,R1,R2
Additionne la valeur stockée dans le registre R1 et la valeur stockée dans le registre R2, place le résultat dans le registre R0
SUB R1,R0,#128
Soustrait le nombre 128 de la valeur stockée dans le registre R0, place le résultat dans le registre R1
SUB R0,R1,R2
Soustrait la valeur stockée dans le registre R2 de la valeur stockée dans le registre R1, place le résultat dans le registre R0
MOV R1, #23
Place le nombre 23 dans le registre R1
MOV R0, R3
Place la valeur stockée dans le registre R3 dans le registre R0
B 45
Nous avons une structure de rupture de séquence, la prochaine instruction à exécuter se situe en mémoire vive à l'adresse 45
CMP R0, #23
Compare la valeur stockée dans le registre R0 et le nombre 23. Cette instruction CMP doit précéder une instruction de branchement conditionnel BEQ, BNE, BGT, BLT (voir ci-dessous)
CMP R0, R1
Compare la valeur stockée dans le registre R0 et la valeur stockée dans le registre R1.
CMP R0, #23 BEQ 78
La prochaine instruction à exécuter se situe à l'adresse mémoire 78 si la valeur stockée dans le registre R0 est égale à 23
CMP R0, #23 BNE 78
La prochaine instruction à exécuter se situe à l'adresse mémoire 78 si la valeur stockée dans le registre R0 n'est pas égale à 23
CMP R0, #23 BGT 78
La prochaine instruction à exécuter se situe à l'adresse mémoire 78 si la valeur stockée dans le registre R0 est plus grand que 23
CMP R0, #23 BLT 78
La prochaine instruction à exécuter se situe à l'adresse mémoire 78 si la valeur stockée dans le registre R0 est plus petit que 23
HALT
Arrête l'exécution du programme
Encore une fois, il n'est pas question d'apprendre à programmer en assembleur, les instructions ci-dessus sont uniquement des exemples.
Label
En faite, les instructions assembleur B, BEQ, BNE, BGT et BLT n'utilisent pas directement l'adresse mémoire de la prochaine instruction à exécuter, mais des "labels". Un label correspond à une adresse en mémoire vive (c'est l'assembleur qui fera la traduction "label"->"adresse mémoire"). L'utilisation d'un label évite donc d'avoir à manipuler des adresses mémoires en binaire ou en hexadécimale. Voici un exemple qui montre comment utiliser un label :
CMP R4, #18 BGT monLabel MOV R0,#14 HALT monLabel: MOV R0,#18 HALT
Dans l'exemple ci-dessus, nous avons choisi "monLabel" comme nom de label. La ligne "MOV R0,#18" a pour label "monLabel" car elle est située juste après la ligne "monLabel:". Concrètement, voici ce qui se passe avec ce programme : si la valeur stockée dans le registre R4 est supérieure à 18 on place le nombre 18 dans le registre R0 sinon on place le nombre 14 dans le registre R0. ATTENTION : la présence du "HALT" juste après la ligne "MOV R0,#14" est indispensable, car sinon, la ligne "MOV R0,#18" sera aussi exécutée (même si la valeur stockée dans le registre R4 est inférieure à 18 )