2026-03-16 18:40:23 +01:00
2026-03-16 18:10:43 +01:00
2026-03-16 18:40:23 +01:00
2026-03-11 03:55:12 +01:00
2026-03-16 04:36:59 +01:00
2026-03-14 00:48:03 +01:00
2026-03-06 19:27:37 +00:00
2026-03-16 16:35:40 +00:00

Assembleur

pour assembler un fichier:

  • depuis ce dossier cargo run --release -p asm fichierentre [fichiersortie]
  • depuis le sous dossier asm cargo run --release fichierentre [fichiersortie]

syntaxe supplémentaire supportée:

  • let rx label assigne l'adresse de label a rx
  • D valeur rentre la donné brute égale à la valeur (immédiate ou addresse de label) (pour mettre des données dans le fichier et pas du code executable)
  • eint Active les interruptions
  • dint Desactive les interruptions
  • swi Active l'interruption swi
  • reti Retourne depuis le handler d'interruption
  • umull multiplication non signée usuelle
  • umulh multiplication non signée, moitié haute du résultat 64 bits
  • smull et sumlh versions signée de la multiplication
  • div division non signée
  • mod modulo non signé

Simulateur

pour lancer la simulation:

  • depuis ce dossier cargo run --release -p simu fichierentre
  • depuis le sous dossier simu cargo run --release fichierentre

Features

rajouter --features=[liste séparé par des virgules]

  • div_mul: Support des instruction de multiplication / division
  • rgba: Écran au format RGBA plutot que 0BGR
  • rich_keyboard: rajoute trois champs de mmio pour le clavier. Voir MMIO
  • debug: repl similaire a la version python du simulateur

instruction spéciale:

halt (jump 0) met le programme en pause, mais on peut se reveiller par des interuptions

call 0 termine l'exécution du simulateur proprement

mmio:

  • 0x01000000 à 0x0112c000 : Écran en lecture/écriture. un pixel par 32bits, de gauche a droite puis de bas en haut. Format de pixel en 0BGR, 4 bits par couleur. Passage au format RGBA (a pour alpha) avec la feature rgba
  • 0x01200000 : Clavier (scancode) (lecture seule)
  • 0x01200004 : Horloge (millisecondes écoulé depuis le début de la simulation, wrappe tout les 49 jours) (lecture seule)
  • 0x01200008 : Boutons de la souris (OR des boutons préssés) Gauche = 1, Droit=2, Clic Molette = 3, Autres non testé (lecture seule)
  • 0x0120000c : Position horizontale de la souris (en pixels, -1 si hors de l'écran) (lecture seule)
  • 0x01200010 : Position verticale de la souris (en pixels, -1 si hors de l'écran) (lecture seule)
  • 0x01201000 : Activation des Interupts de MMIO. Remis a zero par dint. Attention, Écrire ici sans activer les interruptions va bloquer les intéruptions et l'affichage (écriture seule)

Si la feature rich_keyboard est active, tout en lecture seule:

  • 0x01200000 - 12 : Clavier : Representation ascii multichar de la touche pressé, modifié par Alt, Ctrl ... (eg ascii(a), ascii(A), ascii(^)<<8 | ascii(a))
  • 0x01200000 - 8 : Clavier Representation ascii multichar non modifié (eg ascii(a), ascii(\)<<8 | ascii(r))
  • 0x01200000 - 4: Clavier (press | repeat << 1) press: 1 si appuis, 0 si relache. repeat: 1 si l'appuis vient d'une répétition due a l'OS
  • 0x01200000 : Clavier (scancode, comme précédement) (lecture seule)

Interuptions:

Si les interruptions sont activées (avec eint), qu'il y a une raison de faire une interruption, et qu'on n'est pas déjà dans une routine d'interruption de priorité >=, alors le cpu effectue les actions suivantes:

Finis l'instruction en cours si c'est une interruption externe si interruption a des arguments, les mets dans les registres par ordre croissant, Mets PC a (priorité de l'intéruption)*4 (instruction n°priorité)

Cela veut dire que votre début de programme, si vous voulez utiliser les interruption, doit être une table de jump vers les handler correspondant

Pour sortir d'une interuption, utilisez reti Il FAUT sortir avec un reti

Les interuptions utilisent la stack, donc lorsque les interuptions sont activés, il est interdit de stocker des information au dessus du pointeur de stack. de même, reti ne peut pas être appellé par une sous fonction appellée depuis l'interrupt handler

Les intéruptions et leurs arguments, par priorité croissante:

0: Point d'entrée

C'est ici que le programme commence. Seul cas d'utilisation

1: MMIO

Doivent être activé par le MMIO a l'adresse 0x01201000, en y écrivant le OR des (1<<identifiant) On toujours pour argument (r0) leur identifiant Les mmio corespondant sont modifié avant d'entrer dans l'intéruption, et TOUT LES MMIO d'une interuption active sont bloqués tant qu'on n'est pas sorti

  • 1 : Clavier
  • 2 : Boutons de la souris
  • 3 : Mouvements de la souris
  • 4 : Écran (rien n'est modifié, attend la sortie de l'intéruption pour afficher une frame)

2: SWI

Pas d'argument

3: Division par zero

2 arguments: numéro de registre de sortie et valeur du dividende. lors de l'appel a reti, attend que r0 n'ai pas été modifié et un retour dans r1. la registre de destination prend la valeur retourné dans r1

4: Load/Store illégal

Un load store a été fait a une adresse non multiple de 4 3 aruments: si c'est un load: 0, addresse, numéro de registre de retour si c'est un store: 1, addresse, valeure a stocker ne modifiez pas r0, et dans le cas des load, r2. (ou restaurez avant le reti) Si c'est un load, le registre destination prendra la valeur de retour, attendue dans r1

5: Unsupported Opcode

Une division multiplication alors qu'elle ne sont pas activées 4 arguments: indice de registre de retour, argument 1, argument 2, fonction Même mode de retour que la division par zero

6: Instruction Illégale

Une instruction non légale, ou un load / store a une adresse non mappé. 1 argument: l'opcode de l'instruction associé Il est fortement recommendé d'utiliser cette intéruption pour afficher du debug, puis de quitter le programme, mais il est possible de continuer a l'instruction suivante à l'aide d'un reti

Description
Un petit simulateur de processeur pour les cours de L3 de l'ENS de Lyon
Readme MIT 2.7 MiB
Languages
Rust 100%