Le but de ce travail est de vous familiariser avec les concepts suivants:
Le but de ce devoir est de simuler un CPU. Il s'agit d'un processeur très simple, qui a un registre, appelé R, et un espace de pile infini, appelé STACK. Le CPU effectue tous les calculs en utilisant des nombres entiers signés. Il ne sait pas comment gérer les nombres à virgule flottante.
L'ensemble d'instructions est divisé en cinq catégories d'instructions:
Instruction | Paramètres | Description | Exemple |
---|---|---|---|
No Action | |||
nop | pas de paramètres | Elle ne fait rien, en étant utilisée seulement pour les commentaires | nop
|
Memory | |||
push | numéro entier | Elle ajoute le paramètre dans la pile | ; la pile est [ ] push 1 ; la pile est [ 1 ] push 2 ; la pile est [ 1 2 ] |
pop | - | Elle extrait un nombre de la pile; en d'autres termes, il supprime un nombre de la pile | ; la pile est [ 1 2 ] pop ; la pile est [ 1 ] |
load | - | Elle extrait un nombre de la pile et le stocke dans R (le registre du processeur) | ; la pile est [ 1 2 ] load ; la pile est [ 1 ] ; R est 2 |
store | - | Elle ajoute le nombre de R (le registre du processeur) dans la pile | ; la pile est [ 1 ] ; R est 2 store ; la pile est [ 1 2 ] ; R est 2 |
Math | |||
add | - | Elle extrait deux nombres de la pile, fait l'addition, et ajoute le résultat à la pile | push 1 push 2 ; la pile est [ 1 2 ] add ; la pile est [ 3 ] |
sub | - | Elle extrait deux nombres de la pile, fait la soustraction, et ajoute le résultat à la pile | push 1 push 2 ; la pile est [ 1 2 ] sub ; la pile est [ -1 ] |
mul | - | Elle extrait deux nombres de la pile, fait la multiplication, et ajoute le résultat à la pile | push 1 push 2 ; la pile est [ 1 2 ] mul ; la pile est [ 2 ] |
div | - | Elle extrait deux nombres de la pile, fait la division en utilisant une division entière et ajoute le résultat à la pile | push 1 push 2 ; la pile est [ 1 2 ] div ; la pile est [ 0 ] |
mod | - | Elle extrait deux nombres de la pile, calcule le reste de leur division et ajoute le résultat à la pile | push 5 push 3 ; la pile est [ 5 3 ] mod ; la pile est [ 2 ] |
Flow | |||
jump | numéro entier / étiquette | Au lieu d'exécuter l'instruction suivante, la CPU prendra l'instruction: a) au numéro de ligne spécifié comme paramètre or b) de l'étiquette spécifié par le paramètre | ; exemple avec la ligne push 5 ; line 1 jump 5 ; line 2 push 3 ; line 3 - ignoré push 2 ; line 4 - ignoré push 2 ; line 5 - jump ici mul ; la pile est [ 10 ] ; exemple avec étiquette push 5 jump two push 3 ; ignoré push 2 ; ignoré two: push 2 ; label two mul ; la pile est [ 10 ] |
jumpz | numéro entier / étiquette | Si la valeur supérieure de la pile est zéro, cela fonctionne de la même manière que jump , sinon cela ne fait rien | ; example ignore push 5 jumpz two ; ignoré, le sommet de la pile est 5 push 3 push 3 two: push 2 mul ; la pile est [ 5 3 6 ] ; example jump push 0 jumpz two ; saute, le sommet de la pile est 0 push 3 ; ignoré push 3 ; ignoré two: push 2 mul ; la pile est [ 0 ] |
jumpnz | numéro entier / étiquette | Si la valeur du sommet de la pile n'est pas zéro, cela fonctionne de la même manière que jump , sinon cela ne fait rien | ; example ignore push 5 jumpz two ; jumps, le sommet de la pile n'est pas 0 push 3 ; ignoré push 3 ; ignoré two: push 2 mul ; la pile est [ 10 ] ; example jump push 0 jumpz two ; ignoré, le sommet de la pile est 0 push 3 push 3 two: push 2 mul ; la pile est [ 0 3 6 ] |
Pseudo Debug | |||
- | Affiche le numéro du sommet de la pile | ; la pile est [ 1 2 ] print ; affiche 2 |
|
stack | - | Affiche la pile | ; la pile est [ 1 2 ] stack ; imprime [ 1 2 ] |
Le fichier que le simulateur de processeur exécute peut contenir des erreurs. Lorsque le simulateur rencontre une erreur, il ignore cette instruction et continue l'exécution avec la ligne suivante.
Le format d'erreur général est:
ERROR (nom_instruction): texte d'erreur
Erreur | Signification | Exemple |
---|---|---|
unknown instruction | le simulateur a trouvé une instruction qu'il ne connaît pas | multi ; ERROR (multi): unknown instruction
|
stack underflow | le simulateur essaie d'exécuter une instruction qui extrait certaines valeurs de la pile, mais la pile n'a pas assez de valeurs | push 1 mul ; ERROR (mul): stack underflow |
unable to open file filename (node error message ) | le simulateur tente d'ouvrir un fichier qu'il ne peut pas ouvrir | $ node index not_a_filename.asm ERROR unable to open file filename.asm(ENOENT: no such file or directory, open 'filename.asm') |
undefined label | le simulateur essaie de faire un jump à une étiquette qui n'est pas définie | jump jumper ; ERROR (jump): undefined label jumper
|
invalid jump address | le simulateur essaie de faire un jump à une adresse (numéro de ligne) qui n'existe pas dans le fichier | jump 2 ; ERROR (mul): invalid jump address 2 |
Pour exécuter le simulateur, un utilisateur va taper la commande:
$ node index.js filename.asm
Le simulateur lira les instructions du fichier donné en paramètre et les exécutera.
Si aucun paramètre n'est indiqué, le message suivant s'affiche:
$ node index.js USAGE: node index.js filename.asm
Les tests du devoir auront le format suivant:
Tous les tests auront des instructions de débogage.
Note | Tests |
---|---|
50% | pile et instructions mathématiques |
20% | instructions jump |
10% | étiquettes |
10% | instructions du registre |
10% | erreurs |
Le devoir comprend beaucoup de fonctionnalités a implémenter, donc on vous suggere de suivre les étapes:
no file
\n
(\r\n
pour Windows, assurez-vous de l'avoir changé avant de transférer sur git), en utilisant la fonction split
unknown instruction
push
et pop
en utilisant un array de numéros pour la pilePour 2p supplémentaires, implémentez une mémoire pour le CPU. Le simulateur recevra un autre paramètre dans la ligne de commande qui représente le nombre d'emplacements mémoire disponibles.
Implémentez les instructions de mémoire suivantes:
Instruction | Paramètre | Détails |
---|---|---|
write | - | Extrait 2 numéros de la pile et écrit le premier a l'emplacement de la mémoire défini par le deuxième |
read | - | Extrait un numéro de la pile et lit un numéro de l'emplacement de la mémoire défini par le premier numéro, en ajoutant le deuxieme a la pile |
Les devoirs sont individuels. Toute tentative de tricher entraînera 0p pour les devoirs. Un système anti-copie automatisé sera utilisé.
Si vous avez des questions concernant les devoirs, posez-les en publiant un problème sur le github repository pour les questions avec le format du titre [simulator] <titre de votre question>. Vous aurez besoin d'un compte github pour cela.
Si vous souhaitez recevoir un e-mail lorsque des problèmes sont publiés ou lorsqu'il y a de nouveaux messages, accédez au repository pour les questions github et cliquez sur Regarder.