ALMO TP n°1 - Simulateur MARS
Préambule
Ce premier TP a pour but de vous familiariser avec l'outil MARS
, que vous utiliserez dans les trois premiers TP
de l'UE ALMO. Le simulateur MARS
modélise un petit système composé d'un processeur MIPS32
et d'une mémoire, sans faire d'hypothèse sur l'architecture interne du processeur, qui est considéré comme une boîte noire, capable d'exécuter
séquentiellement (instruction par instruction) un code binaire stocké en mémoire.
MARS
fait l'hypothèse qu'un programme utilise trois segments en mémoire :
- Le segment text, qui contient le code binaire exécutable du programme (c'est-à-dire les instructions).
- Le segment data, qui contient les données globales du programme (dont les valeurs peuvent être initialisées).
- Le segment stack, qui contient la pile d'exécution du programme (les variables locales aux fonctions).
L'interface graphique de MARS
vous permet d'examiner les valeurs contenues dans chacun de ces trois segments.
Le logiciel MARS
fournit en pratique trois services distincts :
- Editeur: il contient un éditeur de texte permettant de saisir et de sauvegarder sur disque un programme écrit en langage d'assemblage.
- Assembleur : à partir d'un fichier source en langage d'assemblage, il réalise l'assemblage, c'est-à-dire la génération du code binaire. Il effectue également le chargement en mémoire de ce code binaire dans les deux segments
text
etdata
. - Simulateur : après chargement du code binaire en mémoire, il simule l'exécution en mode pas-à-pas, en vous permettant de visualiser comment l'exécution de chaque instruction modifie l'état du système (c'est-à-dire les valeurs stockées dans la mémoire externe et dans les registres internes du processeur).
Le langage d'assemblage est décrit dans le document MIPS32 : Langage d'assemblage. MARS
prend en entrée un fichier en langage d'assemblage possédant l'extension ".s
". Pour MARS
, la structure d'un fichier nom.s
doit être la suivante :
.data # début de la section des données globales label1: .word 0x3F, 0x45 label2: .asciiz "b" .text # début de la section instructions (code) en mémoire .globl main # définition du point d'entrée du programme main: la $5, label1 # première instruction du programme lw $8, 4($5) ... ori $2, $0, 10 # appel système numéro 10 pour terminer le programme (exit (0)) syscall
1. Addition de deux valeurs stockées en mémoire
- Saisir, soit sous votre éditeur de texte favori, soit en utilisant l'éditeur intégré dans l'outil
MARS
, le programme de calcul de la somme de deux nombres rangés en mémoire (Exercice n°4 du TD1), et sauvez le fichier sous le nomsum.s
.
- Définissez les valeurs des variables d'environnement UNIX utilisées par le logiciel
MARS
, en suivant les recommandations du manuel de configuration.
- Vous pouvez maintenant lancer le simulateur
MARS
, en tapant la commande :
$ mars &
Si le terminal vous répond qu'il ne trouve pas la commande mars
, c'est que l'environnement du terminal n'a pas été correctement configuré. Si le problème persiste, demandez de l'aide à votre encadrant.
- Lancez l'assemblage et le chargement du programme
sum.s
. - Prenez le temps de vérifier que le segment
text
de la mémoire contient bien le code binaire correspondant au programme que vous avez écrit.XSPIM
range ce segment à l'adresse 0x00400000. À quoi correspond la première instruction du segmenttext
?
- Prenez le temps de vérifier que le segment
data
de la mémoire contient bien les variables globales que vous avez définies et initialisées. À quelles adresses sont rangées les trois variablesvar1
,var2
etvar3
?
- Lancez l'exécution du programme en mode pas à pas (commande
step
), en analysant pour chaque instruction quels registres du processeur et quelles cases de la mémoire externe ont été modifiées.
2. Somme des dix premiers entiers
- Saisir le programme de calcul de la somme des dix premiers nombres entiers (Exercice n°5 du TD1). Sauvez le sous le nom
sum10.s
.
- Lancez le simulateur
MARS
, lancez l'assemblage et le chargement du programmesum10.s
, vérifiez que les segmentstext
etdata
sont sont correctement initialisés, puis lancez l'exécution et vérifiez le résultat obtenu.
3. Conversion binaire - hexadécimal ascii
On cherche maintenant à écrire et à exécuter sous MARS
un programme plus compliqué, qui effectue la conversion d'un nombre entier binaire 32 bits vers une chaîne de 10 caractères décrivant la valeur de ce nombre en hexadécimal.
On convertit la valeur entière 'n' stockée en mémoire en une chaîne de 8 caractères ASCII, en extrayant successivement 8 groupes de 4 bits dans le mot de 32 bits représentant 'n'. On stocke cette chaîne de 8 caractères dans un espace mémoire réservé au préalable à l'adresse string
. La conversion est faite en utilisant une table contenant les 16 caractères ASCII représentant les 16 résultats possibles de la conversion d'une valeur sur 4 bits. Les caractères sont ordonnés de telle sorte qu'il suffit d'indexer la table avec la valeur sur 4 bits pour obtenir le code ascii du charactère. En langage C on écrirait :
char table[] = "0123456789ABCDEF"; /* table des caractères ASCII des chiffres hexa */ char string[] = "0x--------"; /* string est la chaine de caractère résultat */ int n = 0x5432ABCD; /* n est le nombre à convertir */ main() { char * ps = &string[2]; /* adresse de la 1ère case de string à remplir */ int q; /* variable contenant le chiffre courant à convertir */ int i = 32; /* numéro du bit de poids faible du chiffre courant dans n */ do /* on boucle sur les groupes de 4 bits dans n */ { i = i - 4; /* du poids fort au poids faible */ q = (n >> i) & 0x0000000F; /* isole dans q le chiffre courant */ *ps = table[q]; /* place dans string le code ASCII de q */ ps++; /* pointe sur la prochaine case de string à remplir */ } while (i > 0); /* tant qu'il reste des chiffres à convertir */ }
Écrire le programme assembleur correspondant au programme C décrit ci-dessus, puis exécutez-le sous le simulateur MARS
.