User Tools

Site Tools


archi:y86

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
archi:y86 [2016/09/29 13:55] – [Simulateur Y86 en JS] orelarchi:y86 [2024/03/18 15:06] (current) – external edit 127.0.0.1
Line 13: Line 13:
   * %edi : le registre //destination index// utilisé lors des copies de suite d'octets   * %edi : le registre //destination index// utilisé lors des copies de suite d'octets
  
-En outre, le registre %eip (//instruction pointer//) pointe sur l'adresse de la prochaîne instruction à exécuter. Ce registre est modifié automatiquement à chaque exécution et peut être manipulé par des instruction du type jmp, call, ret.+En outre, le registre %eip (//instruction pointer//) pointe sur l'adresse de la prochaîne instruction à exécuter. On ne manipule pas ce registre directement. En revanche, il est modifié automatiquement lors de l'exécution ou par des instructions du type jmp, call, ret.
  
 y86 propose un jeu d'instructions réduit :  y86 propose un jeu d'instructions réduit : 
Line 38: Line 38:
 L'interface graphique dispose d'un mode //instruction par instruction// très pratique pour suivre le déroulement de son programme. L'interface graphique dispose d'un mode //instruction par instruction// très pratique pour suivre le déroulement de son programme.
  
-==== Simulateur Y86 en JS ====+==== Simulateur web y86 en JS ====
  
-Voici un simulateur Y86 écrit en JavaScript et disponible en ligne : [[http://dept-info.labri.fr/ENSEIGNEMENT/archi/js-y86/ | Simulateur Y86 UBX]]+Voici un simulateur y86 écrit en JavaScript et disponible en ligne : 
  
-Cette version "Université de Bordeaux" respecte la syntaxe étudiée en cours.+[[http://dept-info.labri.fr/ENSEIGNEMENT/archi/js-y86/ | Simulateur y86]]
  
-Attention, la version originale du simulateur (disponible [[https://xsznix.github.io/js-y86/ | ici]]) présente quelques différences de syntaxe non négligeables avec le Y86 "standard" (celui que nous utilisons).+Attention, cette version disponible sur https://github.com/orel33/js-y86/ a été modifiée par rapport à la version originale pour respecter la syntaxe étudiée dans ce cours. 
 + 
 +A vous de jouer ;-)
  
-  * Les instructions //mrmovl// et //rmmovl// ne supportent pas l'adressage immédiat avec une constante (ou une étiquette). Il faut par conséquent passer par un registre intermédiaire et utiliser un adressage indirect. Par exemple, considérons une variable d'étiquette //x// : il faut remplacer //mrmovl x,%eax// par les instructions //irmovl x,%ebx// et //mrmovl (%ebx),%eax//. 
-  * Par ailleurs, les instructions suivantes (non standards, mais pratiques) ne sont pas disponibles : //iaddl, isubl, iandl, ixorl//. 
-  * D'autres instructions de la forme //cmovl// (conditional move) ont été ajoutés, ainsi que des instructions //brk// (breakpoints). 
-  * Utilisation optionnelle du symbole %%$%% devant les constantes numériques. 
  
  
Line 60: Line 58:
 long a = 2, b = 3, c; long a = 2, b = 3, c;
 if (a < b) c = 1; if (a < b) c = 1;
 +</code>
 +
 +Afin de se rapprocher du code assembleur à écrire, il peut être utile de réécrire le code C de la façon suivante en utilisant //une condition d'évitement// :
 +
 +<code c>
 + long a = 2, b = 3, c;
 + // (a < b) <=> (a-b < 0) <=> ! (a-b >= 0)
 + long tmp = a-b;            // calcul de la condition d'évitement
 + if (tmp >= 0) goto _endif; // test de la condition d'évitement
 + c = 1;
 +_endif:
 +
 </code> </code>
  
Line 89: Line 99:
 if (b <= a) c = 1; else c = 2; if (b <= a) c = 1; else c = 2;
 </code> </code>
 +
 +Un peu de réécriture du code C :
 +
 +<code c>
 + long a = 2, b = 3, c;
 + long tmp = b - a;
 + if (tmp > 0) goto _else;
 + c = 1;  // tmp <= 0, donc la condition b <= a est vraie
 + goto _endif;
 +_else:
 + c = 2;  // tmp > 0, donc la condition b <= a est fausse
 +_endif:
 +</code>
 +
 +Avant de traduire cela en assembleur :
  
 <code - ifthenelse.ys> <code - ifthenelse.ys>
Line 429: Line 454:
  .pos 0x200  .pos 0x200
 stack:  stack:
 +</code>
 +
 +Attention, cette fonction ne respecte pas la convention //callee-saved// car elle utilise %ebx ! Deux solutions sont possibles : 
 +
 +1) sauvegarder / restaurer le registre %ebx dans la fonction pour respecter la convention (attention au décalage de la pile) :
 +
 +<code - swap1.ys>
 +swap: pushl %ebx
 +        mrmovl 8(%esp),%eax # param pa=&a
 + mrmovl 12(%esp),%ebx # param pb=&b
 + mrmovl (%eax),%ecx # valeur a=*pa
 + mrmovl (%ebx),%edx # valeur b=*pb
 + rmmovl %ecx,(%ebx) # swap *pb = a
 + rmmovl %edx,(%eax) # swap *pa = b
 +        popl %ebx
 + ret
 +</code>
 +
 +2) essayer si possible de se limiter aux seuls registres %eax, %ecx et %edx en essayant de se passer de %ebx (ce qui impose de faire des va-et-vient avec la mémoire) : 
 +
 +<code - swap2.ys>
 +swap: mrmovl 4(%esp),%eax # &a
 + mrmovl (%eax),%ecx # a (sauvegarde)
 + mrmovl 8(%esp),%edx # &b
 + mrmovl (%edx),%edx # b
 + rmmovl %edx,(%eax) # maj a
 + mrmovl 8(%esp),%edx # &b
 + rmmovl %ecx,(%edx) # maj b à partir sauvgarde
 + ret
 </code> </code>
  
Line 628: Line 682:
  
  
 +==== En vrac ====
  
 +<code - td04_exo1.ys>
 +.pos 0
 +
 +irmovl stack, %esp
 +jmp main
 +
 +# f(long *x, long y)
 +f:
 +mrmovl 4(%esp),%eax   # x
 +mrmovl 8(%esp),%ecx   # y
 +rmmovl %ecx,(%eax)    # *x = y
 +ret
 +
 +# main
 +main:
 +
 +mrmovl u, %eax
 +pushl %eax          # empiler 2eme arg (u)
 +irmovl t, %eax
 +pushl %eax          # empiler 1er arg (&t)
 +call f
 +iaddl 8,%esp        # depiler les args
 +
 +halt
 +
 +.pos 0x100
 +t: .long 0
 +u: .long 2
 +
 +.pos 0x200
 +stack:
 +</code>
 +
 +<code - td04_exo2.ys>
 +.pos 0
 +
 +irmovl stack, %esp
 +jmp main
 +
 +# f(long n, long * t)
 +f:
 +mrmovl 4(%esp),%ecx   # n
 +mrmovl 8(%esp),%eax   # t
 +
 +loop:
 +isubl 1, %ecx
 +jl end
 +mrmovl (%eax),%edx    # load *t
 +iaddl 1, %edx         # inc
 +rmmovl %edx, (%eax)   # store *t 
 +iaddl 4,%eax          # t++
 +jmp loop
 +
 +end:
 +ret
 +
 +# main
 +main:
 +irmovl t, %eax
 +pushl %eax          # empiler 2eme arg (adresse t)
 +mrmovl n, %eax
 +pushl %eax          # empiler 1er arg (valeur n)
 +call f
 +iaddl 8,%esp        # depiler les args
 +
 +halt
 +
 +.pos 0x100
 +n: .long 4
 +t: 
 +.long 1
 +.long 2
 +.long 3
 +.long 4
 +
 +
 +.pos 0x200
 +stack:
 +</code>
 +
 +<code - td04_exo3.ys>
 +.pos 0
 +
 +irmovl stack, %esp
 +jmp main
 +
 +# sommme(long n, long v[0], long v[1], ...)
 +f:
 +pushl %ebx            # save callee-saved registry
 +xorl %eax,%eax        # sum = 0
 +mrmovl 8(%esp),%ecx   # n
 +rrmovl %esp,%ebx
 +iaddl 12, %ebx         # v
 +
 +loop:
 +isubl 1, %ecx
 +jl end
 +mrmovl (%ebx),%edx    # load *v
 +addl %edx,%eax        # sum += *v
 +rmmovl %edx, (%ebx)   # store *v
 +iaddl 4,%ebx          # v++
 +jmp loop
 +end:
 +popl %ebx             # restore callee-saved registry
 +ret  # %eax
 +
 +# main
 +main:
 +irmovl 3, %eax
 +pushl %eax          # empiler v2
 +irmovl 2, %eax
 +pushl %eax          # empiler v1
 +irmovl 1, %eax
 +pushl %eax          # empiler v0
 +irmovl 3, %eax
 +pushl %eax          # empiler n
 +call f
 +iaddl 16,%esp        # depiler les args
 +
 +halt
 +
 +.pos 0x100
 +n: .long 4
 +
 +
 +.pos 0x200
 +stack:
 +</code>
archi/y86.1475157312.txt.gz · Last modified: 2024/03/18 15:05 (external edit)