Simulation du processeur
Ce projet simule un système informatique simple composé d'un processeur et d'une mémoire. Le processeur et la mémoire sont simulés par des processus distincts qui communiquent. La mémoire contient un programme que le CPU exécutera, puis la simulation se terminera.
Pour CPU:
- Il aura ces registres: PC, SP, IR, AC, X, Y.
- Il prendra en charge les instructions ci-dessous.
- Il exécutera le programme utilisateur à l'adresse 0.
- Les instructions sont récupérées dans l'IR depuis la mémoire. L'opérande peut être récupéré en une variable locale.
- Chaque instruction doit être exécutée avant que l'instruction suivante ne soit récupérée.
- La pile utilisateur réside à la fin de la mémoire de l'utilisateur et se développe vers l'adresse 0.
- La pile système réside à la fin de la mémoire du système et se développe vers l'adresse 0.
- Il n'y a pas d'application matérielle de la taille de la pile.
- Le programme se termine lorsque l'instruction de fin est exécutée. Les 2 processus devraient se terminer à ce moment-là.
- Le programme utilisateur ne peut pas accéder à la mémoire du système (quitte avec message d'erreur).
Pour la mémoire:
- Il comprendra 2000 entrées entières, 0-999 pour le programme utilisateur, 1000-1999 pour le code système.
- Il prendra en charge deux opérations: lire (adresse) - Renvoie la valeur à l'adresse; écrire (adresse, données) - écrit les données à l'adresse
- La mémoire s'initialisera en lisant un fichier de programme.
Pour la minuterie:
- Une minuterie interrompra le processeur après toutes les instructions X, où X est un paramètre de ligne de commande.
Pour le traitement d'interruption:
- Il existe deux formes d'interruptions: la minuterie et un appel système à l'aide de l'instruction INT.
- Dans les deux cas, le CPU doit entrer en mode noyau.
- Le pointeur de pile doit être basculé vers la pile système.
- Les registres SP et PC doivent être enregistrés sur la pile système. (Le gestionnaire peut économiser des registres supplémentaires).
- Une interruption de minuterie doit entraîner l'exécution à l'adresse 1000.
- L'instruction INT doit entraîner l'exécution à l'adresse 1500.
- Les interruptions doivent être désactivées pendant le traitement des interruptions pour éviter l'exécution imbriquée.
- L'instruction IRET revient d'une interruption.
Ensemble d'instructions:
-> 1 = Valeur de charge # Chargez la valeur dans l'AC
-> 2 = chargez addr # Chargez la valeur à l'adresse dans l'AC
-> 3 = chargend addr # Chargez la valeur de l'adresse trouvée dans l'adresse donnée dans l'AC. (Par exemple, si Loadind 500 et 500 contient 100, alors chargez à partir de 100).
-> 4 = chargeidxx addr # Chargez la valeur à (adresse + x) dans l'AC. (Par exemple, si LoadIDXX 500 et X contient 10, alors chargez à partir de 510).
-> 5 = chargeidxy addr # Chargez la valeur à (adresse + y) dans l'AC
-> 6 = Loadspx # Charge de (SP + X) dans l'AC (si SP est 990 et X est 1, charge à partir de 991).
-> 7 = Store Addr # Stockez la valeur de l'AC dans l'adresse
-> 8 = Get # Obtient un int aléatoire de 1 à 100 dans l'AC
-> 9 = mettre le port # si port = 1, écrit AC comme un int à l'écran; Si port = 2, écrit AC comme un char à l'écran
-> 10 = addx # ajouter la valeur en x à l'AC
-> 11 = addy # ajouter la valeur en y à l'AC
-> 12 = subx # soustraire la valeur en x de l'AC
-> 13 = suby # soustraire la valeur en y de l'AC
-> 14 = CopyTox # Copiez la valeur de l'AC vers x
-> 15 = CopyFromx # Copiez la valeur en x à l'AC
-> 16 = CopyToy # Copiez la valeur en AC vers Y
-> 17 = CopyFromy # Copiez la valeur en Y à l'AC
-> 18 = CopyTosp # Copiez la valeur en AC vers le SP
-> 19 = CopyFromsp # Copiez la valeur en SP à l'AC
-> 20 = Jump addr # Jump à l'adresse
-> 21 = jumpifequal addr # sautez à l'adresse uniquement si la valeur de l'AC est nulle
-> 22 = JumpFnoTequal addr # sautez à l'adresse uniquement si la valeur de l'AC n'est pas nulle
-> 23 = appelez addr # push return adresse sur pile, sautez à l'adresse
-> 24 = RET # POP Retour Adresse de la pile, sautez à l'adresse
-> 25 = incx # incrément la valeur en x
-> 26 = DECX # décrément la valeur en x
-> 27 = push # push AC sur la pile
-> 28 = pop # pop de la pile dans AC
-> 29 = int # effectuer un appel système
-> 30 = IRET # retour de l'appel système
-> 50 = End # End Exécution
====================================================================.
Un exemple de dossier contient 5 exemples de fichiers.
échantillon1.txt
- Teste les instructions de charge indexées.
- Imprime deux tables, l'une des AZ, l'autre de 1-10.
échantillon.txt
- Teste les instructions d'appel / ret.
- Imprime un visage où les lignes sont imprimées à l'aide d'appels de sous-programme.
Exemple3.txt
- Teste les instructions INT / IRET.
- La boucle principale est d'imprimer la lettre A suivie d'un nombre qui est périodiquement incrémenté par la minuterie.
- Le nombre augmentera plus rapidement si la période de minuterie est plus courte.
sample4.txt
- Teste le bon fonctionnement de la pile utilisateur et de la pile système, et teste également que l'accès à la mémoire système en mode utilisateur donne une erreur et des sorties.
sampon5.txt
- C'est celui que vous devez créer. Assurez-vous d'inclure des commentaires afin que la niveleuse sache ce que fait le programme.
====================================================================.
Étape pour compiler et exécuter le projet:
- S1: Copiez les fichiers source dans le système Linux.
- S2: modifiez les fichiers directs en source
- S3: Exécutez la commande suivante: GCC Memory.C CPU.C Simulator.C
- S4: exécutez le programme: ./a.out
- S5: Selon les informations de sortie, saisissez le paramètre du temporisateur x, nom de fichier que vous souhaitez exécuter respectivement. Chaque élément se termine par "Entrée". par exemple: 10 ( n) échantillon2.txt
- S6: Répétez S4 pour les exemples de fichiers de test restants pour obtenir les différentes sorties