Devoir 1 - Simulateur

Information

Deadline: le 21 Mars, 23:55
Points: 1 point de la note finale
Link: Devoir 1
Téléchargement tardif: 1p/jour (maximum 2 jours)

Objectifs

Le but de ce travail est de vous familiariser avec les concepts suivants:

  1. développement de base de TypeScript
  2. utilisation de structures de données dans TypeScript
  3. utilisation des paramètres de la ligne de commande
  4. lecture de données à partir de fichiers
  5. division et traitement de chaînes
  6. le mode de fonctionnement d'un processeur simple

Description du devoir

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.

Ensemble d'instructions

L'ensemble d'instructions est divisé en cinq catégories d'instructions:

  1. Aucune action - ces instructions n'effectuent aucune action
  2. Memory - ces instructions permettent au CPU d'interagir avec la pile (la mémoire)
  3. Math - ces instructions permettent au CPU d'effectuer des opérations mathématiques
  4. Flow - ces instructions permettent au CPU d'effectuer des if et des boucles
  5. Pseudo Debug - ces instructions sont utilisées pour le débogage
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
print - 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 ]
 

Erreurs

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

Les erreurs doiventetre affichés exactement comme dans l'exemple suivant:

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

Exécution du simulateur

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

Le $ dans les exemples est le prompt du shell et ne fait pas partie de la commande

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

Conseils d'implémentation

Le devoir comprend beaucoup de fonctionnalités a implémenter, donc on vous suggere de suivre les étapes:

  1. Lire le contenu du fichier dans le string s et implémenter l'erreur no file
  2. Séparer l'entrée lue par \n (\r\n pour Windows, assurez-vous de l'avoir changé avant de transférer sur git), en utilisant la fonction split
  3. Séparer chaque ligne par ' ' (espace) et extraire l'instruction et ses parametres
  4. Implémenter l'erreur unknown instruction
  5. Implémenter les instructions push et pop en utilisant un array de numéros pour la pile
  6. Implémenter les fonctions mathématiques
  7. Implémenter toutes les instructions

Bonus

Pour 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

Le bonus ne sera attribué que si tous les autres tests réussissent.

Règles

  1. Vous ne pouvez pas utiliser RegEx ou toute autre bibliothèque qui utiliserait des expressions régulières (outre \n\r? pour séparer les lignes d'entrée de la source)
  2. Le code source doit être indenté (-0.1p)
  3. Vous devez expliquer en détail dans le Readme.md comment vous avez rédigé les devoirs (-1p)

Tricher

Les devoirs sont individuels. Toute tentative de tricher entraînera 0p pour les devoirs. Un système anti-copie automatisé sera utilisé.

Questions

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.

NE POSTEZ AUCUN CODE . Cette action est considéré comme tentative de tricher et alors vous obtiendrez 0p pour le devoir.

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.

alf/teme/tema_1.txt · Last modified: 2021/03/17 16:33 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0