Programmes assembleur avec AQA

L'assembleur est le langage de programmation le plus bas niveau que sait directement executer un processeur. Le but d'un compilateur, comme GCC pour le langage C par exemple, est de traduire du code de haut-niveau en du code assembleur exécutable par un processeur.

Un langage d'assembleur est spécifique à chaque architecture de processeur mais ils ont tous des caractéristiques assez similaires :

Nous utiliserons dans ce TP le simulateur AQA : http://www.peterhigginson.co.uk/AQA/ dont la documentation est ici.

Jeu d'instruction

Le jeu d'instruction est précisé dans la documentation et se limite globalement à des :

Exemples

Si l'on voulait exécuter le programme suivant écrit en pseudo-code :

lire la valeur de A
lire la valeur de B
si A > B alors afficher A
sinon afficher B
fin

On utilisera les registres R0 et R1 pour lire A et B et le code assembleur sera le suivant :

INP R0,2
INP R1,2
// on compare R0 et R1
CMP R0,R1
// si R0 > R1 on fait
// le saut à plugrand
BGT plusgrand
// saut non fait
// donc R0 <= R1
// on affiche R1
OUT R1,4
// on saute à la fin
B fin
plusgrand:
// branche R0 > R1
// on affiche R0
OUT R0,4
fin:
// fin du programme
HALT

La partie droite de la fenêtre est le contenu de la mémoire qui contient à la fois le code des instructions et des données placées en mémoire. Par défaut, les instructions sont codées à partir de l'adresse 0. Pour placer des données traitées par un programme, le plus simple est de les placer au début de la mémoire avec l'instruction DAT. Mais pour éviter que ce contennu soit confondu avec des instructions, il faudra dire au programme que le code commence après la séquence de données.

Le code ci-dessous place une séquence d'entiers (exprimés en héxadécimal) au début de la mémoire (à partir de l'adresse 1). Cette séquence se termine par la valeur particulière 0. Le programme ensuite fait la somme des entiers de la séquence :

// donnees
// debut = @1
B code
dat 0x12
dat 0x20
dat 0x3
dat 0x11
dat 0x0
code:
// R0: adresse à lire
// R1: valeur courante
// R2: sommme
MOV R0,#1
MOV R2,#0
boucle:
LDR R1,[R0]
ADD R2, R2, R1
ADD R0, R0, #1
CMP R1, #0
BNE boucle
OUT R2,4
HALT

Détail de l'interface

L'interface représente le chemin de données d'un pseudo-processeur et simule de manière simplifiée l'exécution d'un programme assembleur :

Travail à réaliser

Après avoir testé les deux programmes ci-dessus en observant les données transitant entre les différents éléments du pseudo-processeur, vous implémenterez trois programmes en assembleur :

  1. Un programme qui demande un nombre en entrée et calcule la somme des nombres de 1 à ce nombre (ex pour 5 : 5 + 4 + 3 + 2 + 1)
  2. Un programme qui affiche la valeur maximum d'une série d'entiers placés en mémoire
  3. Pour les plus sportifs : un programme qui trie en mémoire une série d'entiers par un tri à bulles par exemple