Aller au contenu

Programmer en assembleur AQA sur un simulateur

Le simulateur développé par Peter L Higginson est disponible ici.

Vous aurez l'affichage suivant :

On peut observer :

  • À droite, la mémoire vive ou RAM. Par défaut, le contenu est affiché en base 10 (signed = entiers avec un signe donc avec le complément à deux) mais avec l'onglet OPTIONS en bas on peut choisir la base 10 "unsigned" sans complément à deux, le binaire ou l'hexadécimal. Testez ces différentes options.
  • Au centre, le processeur ou CPU avec les registres R0 à R12 et le registre PC qui a l'adresse de l'instruction à exécuter, l'unité arithmético-logique, l'unité de contrôle, et des zones input/output pour simuler des périphériques.
  • À gauche, la zone d'édition pour écrire le programme en assembleur. "Run" l'exécute (on peut modifier la vitesse en cours), et "Step" exécute une étape à la fois.

L'assembleur utilisé est celui qu'on a vu la semaine dernière (mémo en pdf que vous avez déjà ici).

exercice 1

Dans la partie de gauche, copiez le code suivant :

MOV R0,#42
STR R0,150
HALT

Cliquez sur le bouton "submit". S'il n'y a pas d'erreur, vous devrez voir apparaître des nombres dans les cellules de la RAM d'addresse 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")).

Nous pouvons donc déduire que :

  • l'instruction machine 11100011 10100000 00000000 00101010 correspond au code assembleur MOV R0,#42
  • l'instruction machine 11100101 10001111 00000010 01001100 correspond au code assembleur STR R0,150
  • l'instruction machine 11101111 00000000 00000000 00000000 correspond au code assembleur HALT

Au passage, pour la première instruction, vous pouvez remarquer que l'octet le plus à droite, 00101010, est bien égal à 42 en base 10 !

Repassez à un affichage en base 10 afin de faciliter la lecture des données présentes en mémoire.

Pour exécuter notre programme, il suffit maintenant de cliquer sur le bouton "RUN". Vous allez voir le CPU "travailler" en direct grâce à de petites animations. Si cela va trop vite (ou trop doucement), vous pouvez régler la vitesse de simulation à l'aide des boutons "<<" et ">>". Un appui sur le bouton "STOP" met en pause la simulation, si vous rappuyez une deuxième fois sur ce même bouton "STOP", la simulation reprend là où elle s'était arrêtée.

Une fois la simulation terminée, vous pouvez constater que la cellule mémoire d'adresse 150, contient bien le nombre 42 (en base 10). Vous pouvez aussi constater que le registre R0 a bien stocké le nombre 42.

Attention

Pour relancer la simulation, il est nécessaire d'appuyer sur le bouton "RESET" afin de remettre les registres R0 à R12 à 0, ainsi que le registre PC (il faut que l'unité de commande pointe de nouveau sur l'instruction située à l'adresse mémoire 000). La mémoire n'est pas modifiée par un appui sur le bouton "RESET", pour remettre la mémoire à 0, il faut cliquer sur le bouton "OPTIONS" et choisir "clr memory". Si vous remettez votre mémoire à 0, il faudra cliquer sur le bouton "ASSEMBLE" avant de pouvoir exécuter de nouveau votre programme.

exercice 2

Recopier votre programme pour la multiplication, qui calcule le produit de R0 et R1 et le stocke dans R2. Ajoutez deux valeurs quelconques dans R0 et R1 au début (avec des instructions comme MOV R0,#27) et testez-le pour le vérifier.

exercice 3

Observez l'exemple "max" (avec le menu déroulant SELECT).

Il y a deux instructions qu'on n'a pas vues :

  • INP R0,2 (input) charge une valeur tapée dans la zone INPUT dans le registre R0 (2 est l'adresse du périphérique en quelque sorte).
  • OUT R0,4 (output) écrit en base 10 le contenu de R0 dans la zone d'OUTPUT.

Modifiez le programme pour qu'il renvoie non pas le maximum mais le minimum des deux nombres.

exercice 4

Créez un programme qui affiche (avec une instruction OUT) dans l'ordre le nombre de la suite de Fibonacci, sans jamais s'arrêter.

La suite de Fibonacci commence par 1,1 et ensuite chaque nombre est calculé en additionnant les deux précédents. Il suffira donc d'utiliser deux registres pour les deux dernières valeurs de la suite, un autre registre pour calculer le nombre suivant, et ensuite de décaler les nouvelles deux dernières valeurs dans les bons registres.

exercice 5

Ce qu'on a vu jusque là permet seulement de stocker en mémoire à une adresse fixée dans le code, avec par exemple :

STR R0, 150

Mais on a le droit de faire de l'adressage indirect avec une instruction comme :

STR R0, [R1]

qui va stocker le contenu de R0 à l'adresse mémoire écrite dans R1.

Cela va permettre de faire l'équivalent de tableaux en mémoire.

1) Commencez par faire un programme qui remplit la mémoire entre les adresses 50 et 150 par la valeur 42

2) Puis faites un programme qui stocke dans les adresses à partir de 50 les puissances de 2 : 1,2,4,8... Quelle est la plus grande qui peut être contenue dans notre mémoire ? (vérifiez ce qu'il se passe en regardant les affichages en base 10 signée, base 10 non signée, et binaire)

Bonus : multiplication efficace