Differences

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

Link to this comparison view

alf:laboratoare:11 [2021/05/13 17:34]
diana.ghindaoanu [Exercises]
alf:laboratoare:11 [2021/05/25 00:37] (current)
diana.ghindaoanu
Line 1: Line 1:
-====== TP 11 - Assambleur ​======+====== TP 11 - WebAssembly ​======
  
-Dans ce laboratoire,​ nous utiliserons le simulateur de langage d'​assemblage [[https://​schweigi.github.io/​assembler-simulator/​]]. Il simule un processeur avec les fonctionnalités suivantes:​ +===== Syntax ​forme text =====
-  * 4 Hz +
-  * 4 registres à usage général A, B, C si D +
-  * un registre pour l'​instruction IP actuelle +
-  * un registre pour le sommet de la pile SP +
-  * 256 B RAM +
-  * 24 B mémoire vidéo (derniers octets de RAM)+
  
-La description ​de simulateur este disponible ​[[https://www.mschweighauser.com/make-your-own-assembler-simulator-in-javascript-part1/]].+Avant de commencer le TP, lisez le tutoriel suivant: ​[[https://developer.mozilla.org/en-US/​docs/​WebAssembly/Understanding_the_text_format|Mozilla Web Assembly Tutorial]].
  
-===== L'​ensemble ​d'​instructions ​ =====+Pour plus d'informations,​ la documentation de Web Assembly est disponible ici: [[https://​webassembly.github.io/​spec/​core/​index.html|WebAssembly Specification]] et [[https://​webassembly.github.io/​spec/​core/​appendix/​index-instructions.html|Index of Instructions]]
  
-L'​ensemble d'​instructions représente les commandes qu'un processeur peut exécuter. Ce processeur connaît les instructions suivantes: ​  +===== Utilisation ​de Web Assembly ===== 
-  * mov - attribution ​de données +Pour tester ​les exemples présentés dans ce TP, on va utiliser ​la page destinée ​Web Assembly: [[https://​webassembly.studio/|Web Assembly Studio]]
-  * add - addition +
-  * sub - soustraction +
-  * inc - incrémentation +
-  * dec - decrémentation +
-  * mul - multiplication +
-  * div - division +
-  * and - et sur les bits +
-  * or - ou sur les bits +
-  * xor - xor  +
-  * not - negation des bits +
-  * shl - décaler vers la gauche (équivalent ​la multiplication par 2) +
-  * shr 0 siftare la dreapta (équivalent a la division par 2) +
-  * cmp - comparaison +
-  * jmp - saut +
-  * j.. - saut (plusieurs informations) +
-  * call - appel de fonction +
-  * ret - retour de la fonction +
-  * hlt - arrêt du processeur +
-  * push - ajouter dans la pile +
-  * pop - supprimer de la pile at ajouter dans un registre+
  
 +Si vous voulez commencer votre travail a partir d'un programme deja créé, vous pouvez accéder a ce [[https://​webassembly.studio/?​f=9o45ipku27|lien]]
  
-L'​ensemble ​d'instructions avec sa description est disponible sur le site Web du simulateur [[https://​schweigi.github.io/​assembler-simulator/​instruction-set.html]].+Si vous choisissez de créer votre propre projet, tout d'abour vous devez suivre ces étapes:
  
 +Sélectionnez l’option **Empty Wat Project** et appuyez sur **Create**:
 +{{ :​alf:​laboratoare:​tp12-1.jpg?​500&​nolink }}
 +     
 +Dans la nouvelle fenetre ouverte, vous pouvez modifier les fichiers qui se trouvent dans le dossier //src//. Pour la partie JavaScript, vous allez modifier le code source du fichier ''​main.js'',​ en le remplacant comme dans l'​exemple suivant :
 +{{ :​alf:​laboratoare:​tp12-2.jpg?​500&​nolink }}
 +
 +Dans le fichier ''​main.wat'',​ vous allez trouver le code suivant :
 +{{ :​alf:​laboratoare:​tp12-3.jpg?​500&​nolink }}
 +     
 +Ici, on a créé une fonction qui réalise l’opération d’addition entre 2 numéros donnés comme paramètres et qui retourne le résultat (la somme). L’appel de cette fonction a été realisé précédemment dans le fichier ''​main.js''​
 +
 +
 +<​note>​
 +Après avoir modifié le contenu d’un fichier, vous devez sauvegarder les changements (Ctrl+S ou le bouton **Save**).
 +</​note>​
 +
 +Pour exécuter le programme, vous devez appuyer sur le bouton **Build&​Run** et le résultat de votre programme sera affiché dans la section **Output**.
 +
 +===== Translation de code en Web Assembly ====
 +
 +==== Program Principal ====
 +
 +<code c>
 +int main ()
 +{
 +  return 0;
 +}
 +</​code>​
 +
 +<code wat>
 +(module
 +  (func $start ​
 +    )
 +  (start $start)
 +)
 +</​code>​
 +
 +==== Fonction ====
 +
 +<code c>
 +int sum (int a, int b)
 +{
 +}
 +</​code>​
 +
 +<code wat>
 +(module
 +  (func $sum (param $a i32) (param $b i32) (result i32)
 +    local.get $a
 +    local.get $b
 +    i32.add
 +    return
 +    )
 +)
 +</​code>​
 +
 +==== Attribution de variable local ====
 +
 +<code c>
 +int name ()
 +{
 +  int a;
 +  a = 0;
 +  return a;
 +}
 +</​code>​
 +
 +<code wat>
 +(module
 +  (func $name (local $a i32) (result i32)
 +    i32.const 0;
 +    local.set $a
 +    local.get $a
 +    return
 +    )
 +)
 +</​code>​
 +
 +==== Import function ====
 +
 +<code wat>
 +(module
 +  (import "​io"​ "​print"​ (func $print (param i32)))
 +  (func $start
 +    i32.const 120
 +    call $print)
 +  (export "​start"​ (func $start))
 +)
 +</​code>​
 +
 +=== Structure du fichier Javascript pour afficher la valeur sur l'​ecran===
 +
 +<code javascript>​
 +fetch('​../​out/​main.wasm'​).then(response =>
 +  response.arrayBuffer()
 +).then(bytes => WebAssembly.instantiate(bytes,​ {
 +  io: {
 +    print: console.log
 +  }
 +})).then(results => {
 +  let instance = results.instance;​
 +  // instance is your webassembly module
 +  let asm = instance.exports;​
 +  // asm is an object with all the items that you exported
 +  console.log (asm.start());​
 +}).catch(console.error);​
 +
 +</​code>​
 +
 +==== if ====
 +
 +<code c>
 +if (a>b)
 +{
 +   print (a);
 +}
 +else
 +{
 +   print (b);
 +}
 +</​code>​
 +
 +<code wat>
 +;; import the print function
 +local.get $a
 +local.get $b
 +i32.gt
 +if 
 +   ​local.get $a
 +   call $print
 +else
 +   ​local.get $b
 +   call $print
 +end
 +</​code>​
 +
 +==== while ====
 +
 +<code c>
 +a=1;
 +while (a<120)
 +{
 +   print (a);
 +   a=a+1
 +}
 +</​code>​
 +
 +<code wat>
 +;; import the print function
 +i32.const 1
 +set_local $a
 +block $endwhile
 +  loop $while
 +    local.get $a
 +    i32.const 120
 +    i32.gt
 +    br_if $endwhile
 +    local.get $a
 +    call $print ​
 +    local.get $a
 +    i32.const 1
 +    i32.add
 +    local.set $a
 +    br $while
 +  end $while
 +end $endwhile
 +</​code>​
 +
 +==== for ====
 +
 +<code c>
 +for (i=1; i<120; i++)
 +{
 +   print (a);
 +}
 +</​code>​
 +
 +<code wat>
 +;; import the print function
 +i32.const 1
 +local.set $i
 +block $endfor
 +  loop $for
 +    local.get $i
 +    i32.const 120
 +    i32.gt
 +    br_if $endfor
 +    local.get $i
 +    call $print ​
 +    local.get $i
 +    i32.const 1
 +    i32.add
 +    local.set $i
 +    br $for
 +  end $for
 +end $endfor
 +</​code>​
 +
 +==== do-while ====
 +
 +<code c>
 +a=1;
 +do 
 +{
 +   print (a);
 +   a=a+1
 +} while (a<​=120);​
 +</​code>​
 +
 +<code wat>
 +;; import the print function
 +i32.const 1
 +local.set $a
 +loop $dowhile
 +  local.get $a
 +  call $print ​
 +  local.get $a
 +  i32.const 1
 +  i32.add
 +  local.set $a
 +  local.get $a
 +  i32.const 120
 +  i32.le
 +  br_if $dowhile
 +end $dowhile
 +</​code>​
  
 ==== Exercises ==== ==== Exercises ====
-  - Exécutez le programme initial. Changez le nom de la variable et essayez de comprendre comment écrire votre nom sur la sortie (**2p**) +Pour les exercices suivantsvous pouvez écrire et envoyer le code source ​dans des fichiers texteVous devez ajouter aussi le code WAT, que le code JavaScriptPour tester ​la validité ​de vos programmes, vous devez utiliser [[https://webassembly.studio/?​f=9o45ipku27|le project]]. 
-  - Écrivez un programme qui place les nombres 02, 4, 6 dans les registres A, B, C et D.(**1p**) + 
-  - Écrivez ​le code pour calculer ​le reste de la division de la valeur du registre A par la valeur du registre BRetournez ​la valeur ​de l'​oppération ''​17%3''​. Expliquez qu'​est-ce qui se passe. (**1p**) +<note info>​Veuillez utiliser Firefox ou Chrome.</​note>​ 
-  - Écrivez un programme qui affiche 0 en sortie autant de fois que la valeur du registre C. Affichez dans la sortie 4 chiffres de 0. (**2p**) + 
-  - Écrivez un programme qui comprend une fonction qui fait le //swap// entre deux variables. Envoyer les paramètres de fonction à l'aide de registres. Retournez ​le swap entre les registres A et B(**1p**)+<note important>​ 
-  - Écrivez un programme ​et une fonction qui calcule le reste de la division de deux variables. Envoyer les paramètres de fonction à l'aide de la pile. Verifiez pour ''​7%3''​. (**1p**). +Pour ces exercices que vous allez résoudre en Web Assembly Studio, vous allez utiliser ''​get_local'' ​et ''​set_local''​ au lieu de ''​local.get''​ et ''​local.set''. 
-  - Écrivez un programme ​et une fonction qui calcule la taille d'une chaîne stockée en tant que variable. Vous pouvez partir de l'exemple du premier programmeLa fonction doit être rappelable de l'intérieur et vous devez retourner la dimension de la chaîne dans le registre B(**2p**) +</​note>​
-  - **Bonus** Écrivez un programme et une fonction qui calcule la chaîne a (n) = a (n-1) * a (n-2), a (0) est 1 et a (1) est 2. (**2p**)+
  
 +  - Ecrivez dans un fichier **ex1.txt** le code WebAssembly pour le calcul de l'​expression 5-4*2/​(1+3).(**1.5p**)
 +  - Ecrivez un programme (//wat// et //js//) qui a une fonction de démarrage //start// et affiche sur l'​écran le numéro correspondant a votre date de naissance. Utilisez ​ [[https://​webassembly.studio/?​f=lmyi28gq7it|l'​exemple]]. (**1p**)
 +  - Ecrivez un programme qui initialise 3 variables **locales** avec les valeurs 4, 5 et 6 dans la fonction //start// et calcule le résultat de l'​expression ''​a+b%c''​. (**1p**)
 +  - Ecrivez un programme avec qui inclut la déclaration d'une fonction qui calcule et affiche la moyenne arithmétique des 3 numéros donnés comme parametres. Appelez la fonction dans la fonction //start//. (**1.5p**)
 +  - Ecrivez une fonction qui calcule de reste de la disivion de son parametre par 5. Dans la fonction //start//, appelez la fonction //​is_divisible//​ avec le parametre 25. (**1p**)
 +  - Ecrivez une fonction qui affiche sur l'​ecran le cube de chaque nombre de l'​intervalle [1, 10]. (**2p**)
 +  - Ecrivez une fonction //sq_sum// qui calcule la somme des racines carrées des nombres //pairs// d'un intervalle donné. La fonction reçoit deux paramètres qui représentent les limites de l'​intervalle et affiche sur l'​écran le résultat. Dans la fonction //start//, appelez la fonction //sq_sum// avec les parametres 0 et 3. (**2p**)
 +  - Ecrivez une fonction qui vérifie si un nombre est premier et affichez 1 si le nombre est premier et 0 dans le cas contraire. (**2p**)
  
 <​hidden>​ <​hidden>​
alf/laboratoare/11.1620916482.txt.gz · Last modified: 2021/05/13 17:34 by diana.ghindaoanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0