Core War

Le but de ce TP est de comprendre les principes de la programmation assembleur, avec un langage simplifié.

Core War est un jeu où plusieurs programmes (virus) tournent simultanément sur une machine virtuelle. Le but est de faire se terminer tous les autres programmes. Cf. Beginner's guide, FAQ et autres références.

  1. Dans un premier temps, faire un court programme C (éventuellement perl) fonctionnant avec un argument, un nom de fichier qui contient le code assembleur Redcode d'un n programme CoreWar. Il s'agit d'allouer la mémoire de la machine MARS (taille 8000 par exemple) d'y placer le code du programme CoreWar, de mettre le pointeur d'instruction au début de ce programme, et d'exécuter le programme.

    On n'utilisera pas les 18 ou 19 instructions de l'assembleur Redcode, mais seulement les 6 ci-dessous et les modes d'adressage immédiat, direct et B-indirect : MOV, ADD, JMP, CMP, SLT, DAT.
    NB : l'adressage immédiat signifie que la valeur considérée est celle de l'argument de l'instruction, l'adressage direct signifie que la valeur considérée celle à l'adresse (relative) donnée par l'argument de l'instruction, l'adressage indirect signifie que la valeur considérée celle à l'adresse donnée par ce qui est à l'adresse donnée par l'argument de l'instruction.

    Exemple de corrigé
    à utiliser avec les codes de Imp et Dwarf et aussi un code plus compliqué.

  2. On modifie le programme pour qu'il fonctionne avec n arguments (des noms de fichiers, contenant chacun le code assembleur Redcode d'un programme CoreWar). Les codes assembleur sont placés à intervalle régulier. On exécute sucessivement une instruction pour chaque programme CoreWar.

    Exemple de corrigé

Dans les règles standardisées de Core War, il y a un scheduler qui exécute successivement une instruction de chaque programme. On va programmer ici une version modifiée de la machine virtuelle MARS, où chaque programme utilise un processus Unix et où la concurrence entre ces programmes est gérée par le scheduler Unix. La mémoire de la machine virtuelle est donc de la mémoire partagée entre ces processus.

  1. Modifier le programme de la première question pour qu'il utilise de la mémoire partagée.

    Exemple de corrigé
    Plus complet (avec gestion des signaux)

  2. Modifier le programme de la seconde question pour qu'il utilise de la mémoire partagée. Il s'agit de forker un fils pour chaque programme CoreWar. Chacun de ces processus a accès à la mémoire partagée et c'est le scheduler Unix qui gère les priorités.

    Exemple de corrigé, avec utilisation de nanosleep

  3. Rajouter un affichage graphique de l'évolution du jeu : la mémoire est représentée par un rectangle, initialement noir. Chaque programme a une couleur, lorsqu'un programme modifie la valeur d'une case mémoire, celle-ci change de couleur.

    Exemple de corrigé

NB : le TP 11 reprendra les concepts de mémoire partagée...