L’assembleur y86 est un langage assembleur simplifié basé sur l’architecture des processeurs x86. Le y86 comporte 8 registres de 32 bits (4 octets) chacun. Certains de ces registres ont un rôle particulier :

Comme le x86, le y86 utilise la convention little endian : lorsqu’on stocke un nombre de 32 bits en mémoire, les octets constituant ce nombre sont inversés. Par exemple, le nombre hexadécimal sur 32 bits suivant : 0xabcd1234 est représenté en mémoire par les octets successifs suivant : 0x34, 0x12, 0xcd et 0xab.
Pour programmer en y86, on utilise le simulateur en ligne : https://dept-info.labri.fr/ENSEIGNEMENT/archi/y86js_v2/index.html.
Il se présente comme ceci (si l'aspect est différent, notamment au niveau de la langue ou du thème d'affichage, vous pouvez accéder aux réglages en cliquant sur l'icône en haut à droite) :

Le jeu d’instructions du y86 est très réduit. Les instructions occupent de 1 à 6 octets en mémoire.

Il existe d’autres instructions que nous ne détaillerons pas ici. Pour ceux qui voudraient plus d’informations, vous pouvez consulter la page : https://dept-info.labri.fr/ENSEIGNEMENT/archi/CSAPP/class1b-ISA.pdf (document en anglais).
Exemple 1 : un compteur simple :
Dans la fenêtre « EDITEUR - CODE SOURCE », taper le programme suivant :
.pos 0 irmovl 1, %eax irmovl 1, %ebx loop: addl %ebx, %eax jmp loop
Appuyer ensuite sur le bouton « ASSEMBLER ». Que remarque-t-on dans les fenêtres « EXECUTION - CODE OBJET » et « MEMOIRE » ?
Appuyer ensuite sur le bouton « PAS A PAS » pour exécuter le programme pas à pas. A chaque pas, regarder le contenu des registres, les drapeaux et le compteur ordinal. Le compteur ordinal contient l’adresse de la prochaine instruction à exécuter. Modifier les valeurs aux lignes 2 et 3, et relancer le programme pour tester (bien penser à faire « ASSEMBLER » après chaque modification).
Remarques :
- « loop » est un label. C’est un nom qui désigne une adresse, et qui simplifie le code assembleur. On peut utiliser n’importe quel mot qui ne soit pas une instruction assembleur.
- « .pos 0 » permet de définir l’adresse mémoire des instructions qui suivent.
Exemple 2 : un compteur à rebours :
Taper et exécuter le code suivant.
.pos 0 irmovl 10, %eax irmovl 1, %ebx loop: subl %ebx, %eax jmp loop
Regarder bien la valeur des drapeaux lorsque la valeur de %eax arrive à zéro puis passe dans les négatifs. Modifier les valeurs aux lignes 2 et 3, et relancer le programme pour tester (bien penser à faire « ASSEMBLER » après chaque modification).
Exemple 3 : compteur à rebours version 2 :
On modifie le code précédent en remplaçant « jmp » par « jne » et en rajoutant « halt » à la fin du programme. Relancer l’exécution.
.pos 0 irmovl 10, %eax irmovl 1, %ebx loop: subl %ebx, %eax jne loop halt
Modifier les valeurs des lignes 2 et 3 et relancer l’exécution.
Exemple 4 : un programme mystérieux :
.pos 0 irmovl 8, %eax irmovl original, %ecx irmovl copie, %edx loop: mrmovl (%ecx), %ebx rmmovl %ebx, (%edx) iaddl 4, %ecx iaddl 4, %edx isubl 1, %eax jne loop halt .pos 0x0040 original: .long 0x01234567 .long 0x89abcdef .long 0x11111111 .long 0x22222222 .long 0x33445566 .long 0x31415926 .long 0x27182818 .long 0xbaffe000 .pos 0x0080 copie: .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000
Taper et lancer ce programme, en l’exécutant pas à pas. Quel est son rôle ? On regardera notamment le contenu de la mémoire avant et après son exécution.
Exemple 5 : calcul des carrés des N premiers nombres entiers :
- On peut remarquer que : 12 = 1, 22 = 2 + 2, 32 = 3 + 3 + 3, 42 = 4 + 4 + 4 + 4, etc… On va se servir de cette propriété pour calculer le carré d'un nombre.
- La valeur (N + 1) doit être indiquée en argument de la fonction isubl de l’antépénultième ligne de code (ligne 15). Dans notre exemple, la valeur est de 11, donc le programme calculera le carré des 10 premiers nombres entiers.
- Les carrés des différents nombres sont stockés à partir de l’adresse 0x0050 sur 4 octets.
.pos 0 irmovl 0x0050, %ecx irmovl 1, %eax label1: rrmovl %eax, %ebx irmovl 0, %edx label2: addl %eax, %edx isubl 1, %ebx jne label2 rmmovl %edx, (%ecx) iaddl 4, %ecx iaddl 1, %eax rrmovl %eax, %edi isubl 11, %edi jne label1 halt

