Differences

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

Link to this comparison view

alf:laboratoare:10 [2021/04/15 11:33]
diana.ghindaoanu [TP 10 - Génération de code 2]
alf:laboratoare:10 [2021/05/16 21:26] (current)
diana.ghindaoanu
Line 1: Line 1:
-====== TP 10 - Génération de code 2 ======+====== TP 10 - Assambleur ​======
  
-Dans le domaine informatique, le code de trois adresses (three address code) représente un code intermédiaire utilisé pour les compilateurs en tant que moyen d'écrire des instructionsChaque instruction consiste en:+Dans ce laboratoirenous utiliserons ​le simulateur ​de langage ​d'assemblage [[https://​schweigi.github.io/​assembler-simulator/​]]. Il simule un processeur avec les fonctionnalités suivantes: 
 +  * 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)
  
-   * maximum trois adresses (variables, numéro, étiquette, …) +La description de simulateur este disponible [[https://​www.mschweighauser.com/​make-your-own-assembler-simulator-in-javascript-part1/​]].
-   * opérateur +
-   * résultat+
  
 +===== L'​ensemble d'​instructions ​ =====
  
-Contrairement au TP précédent où la transformation ​été implémentée ​l'aide des //variables temporaires//,​ l'​objectif ​de ce travail est de représenter le ''​Three Address Code''​ en simulant une **pile**.+L'​ensemble d'​instructions représente les commandes qu'un processeur peut exécuter. Ce processeur connaît les instructions suivantes: ​  
 +  * mov - attribution de données 
 +  * 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 ​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
  
  
-===== Exemple =====+L'​ensemble d'​instructions avec sa description est disponible sur le site Web du simulateur [[https://​schweigi.github.io/​assembler-simulator/​instruction-set.html]].
  
-<​code>​ 
-/* Expression */ 
-(5-3)*7; 
  
-/Three Address Code */ +==== Exercises ==== 
-push 5 +  - Exécutez le programme initial. Changez le nom de la variable et essayez de comprendre comment écrire votre nom sur la sortie (**2p**) 
-push +  - Écrivez un programme qui place les nombres 0, 2, 4, 6 dans les registres A, B, C et D.(**1p**) 
-sub +  - Écrivez le code pour calculer le reste de la division de la valeur du registre A par la valeur du registre B. Retournez la valeur de l'​oppération ''​17%3''​. Expliquez qu'​est-ce qui se passe. (**1p**) 
-push +  - É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**) 
-mul +  - Écrivez un programme qui comprend une fonction qui fait le //swap// entre deux variables. Envoyer les paramètres de fonction à l'aide des registres. Retournez le swap entre les registres A et B. (**2p**). 
-</​code>​+  - É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''​. (**1.5p**). 
 +  - É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 programme. La fonction doit être rappelable de l'​intérieur et vous devez retourner la dimension de la chaîne dans le registre B. (**2p**)
  
  
  
-===== Expression Parser ​=====+<​hidden>​ 
 +==== Solutions ​==== 
 +  - **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**) 
 +[[https://​github.com/​alexandruradovici/​alf2018/​tree/​master/​TP/​TP11|Solutions]] 
 +</​hidden>​
  
-<code jison alf.l> 
-Ws                    [ \t] 
-Number ​               [0-9]+("​."​[0-9]+)?​ 
-String_value ​         \"​[^\"​]*\"​ 
-Identifier ​           [A-Za-z][A-Za-z0-9]* 
-Newline ​              \r?\n 
-  
-%% 
-  
-  
-"​def" ​                { return '​DEF';​ } 
-"​int" ​                { return '​INT';​ } 
-"​float" ​              { return '​FLOAT';​ } 
-"​string" ​             { return '​STRING';​ } 
-"​function" ​           { return '​FUNCTION';​ } 
-"​end" ​                { return '​END';​ } 
-"​="​  ​     { return '​=';​ } 
-"​-" ​                  { return '​-';​ } 
-"​+" ​                  { return '​+';​ } 
-"​*" ​                  { return '​*';​ } 
-"/" ​                  { return '/';​ } 
-"​(" ​                  { return '​LP';​ } 
-"​)"​  ​                 { return '​RP';​ } 
-','​  ​     { return ',';​ } 
-  
-{Ws}                  { /*skip whitespace*/​ } 
-{Newline} ​            { return '​NEWLINE';​ } 
-{Number} ​             { return '​NUMBER';​ } 
-{String_value} ​       { return '​STRING_VALUE';​ } 
-{Identifier} ​         { return '​IDENTIFIER';​ } 
-</​code>​ 
  
-<code jison alf.y> 
-%left '​+'​ '​-'​ 
-// * and / have higher priority 
-%left '​*'​ '/' ​ 
-  
-%%  
-  
-%left '​+'​ '​-'​ 
-// * and / have higher priority 
-%left '​*'​ '/' ​ 
-  
-%%  
-  
-start: statements { ​ 
- $$ =  { 
- type:'​module',​ 
- statements:​ $1 
- };​ 
- return $$;  
- };​ 
-  
-statements 
-: statement NEWLINE statements { 
-                                                $3.splice (0, 0, $1); 
-                                                $$ = $3; 
- } 
-| statement NEWLINE { 
- $$ = [$1]; 
- } 
-| statement { 
- $$ = [$1]; 
- } 
- ; 
-  
-statement 
-: expression ​ {} 
-| assign {} 
-| function_call {} 
-; 
-  
-  
-expression 
-: LP expression RP { $$ = $2; } 
-| expression '​+'​ expression { ​ 
- $$ = { 
- type:​ '​expression',​ 
- operator:​ '​+',​ 
- left:​ $1, 
- right:​ $3 
- };​ 
- } 
-| expression '​-'​ expression { 
- $$ = { 
- type:​ '​expression',​ 
- operator:​ '​-',​ 
- left:​ $1, 
- right:​ $3 
- };​ 
- } 
-| expression '​*'​ expression { ​ 
- $$ = { 
- type:​ '​expression',​ 
- operator:​ '​*',​ 
- left:​ $1, 
- right:​ $3 
- };​ 
- } 
-| expression '/'​ expression { 
- $$ = { 
- type:​ '​expression',​ 
- operator:​ '/',​ 
- left:​ $1, 
- right:​ $3 
- };​ 
- } 
-| IDENTIFIER { 
- $$ = { 
- type:​ '​identifier',​ 
- value:​ $1 
- };​ 
- } 
-| NUMBER { ​ 
- $$ = { 
- type:​ '​number',​ 
- value:​ parseFloat ($1) 
- };​ 
- } 
-| STRING_VALUE { 
- $$ = { 
- type:​ '​string',​ 
- value:​ $1.substring (1, $1.length-2) 
- };​ 
- } 
-; 
-  
-  
-assign 
-: IDENTIFIER '​='​ expression { 
- $$ = { 
- type:​ '​assign',​ 
- to:​ $1, 
- from:​ $3 
- };​ 
- } 
-| IDENTIFIER '​='​ function_call { 
- $$ = { 
- type:​ '​assign',​ 
- to:​ $1, 
- from:​ $3 
- };​ 
- } 
-; 
-  
-function_call 
-: IDENTIFIER LP parameters_run RP  { 
- $$ = { 
- type:​ '​function_call',​ 
- function:​ $1, 
- parameters:​ $3 
- };​ 
- };​ 
-  
-parameters_run 
-: expression ','​ parameters_run { 
- $3.splice (0, 0, $1); 
- $$ = $3; 
- } 
-| expression { 
- $$ = [$1]; 
- } 
-| { 
- $$ = []; 
- } 
-; 
-</​code>​ 
- 
-<code javascript index.js>​ 
-"use strict";​ 
-  
-// import fs for reading ​ 
-var fs = require ('​fs'​);​ 
-  
-// import the generated Parser 
-var parser = require ('​./​alf.js'​).parser;​ 
-  
-var str = fs.readFileSync (process.argv[2],​ '​UTF-8'​);​ 
-  
-var variable_id = 0; 
-  
-  
-// get a new temporary variable 
-function nextVar () 
-{ 
-    return '​var'​ + variable_id++;​ 
-} 
-  
-  
-function writeThreeAddressCode (node) 
-{ 
-    if (node.type === '​module'​) 
-    { 
-        for (var statement of node.statements) 
-        { 
-            writeThreeAddressCode(statement);​ 
-        } 
-    } 
-    else 
-    if (node.type === '​function_call'​) 
-    { 
-        ​ 
-    } 
-    else 
-    if (node.type === '​number'​) 
-    { 
-        ​ 
-    } 
-    else 
-    if (node.type === '​assign'​) 
-    { 
-        
-    } 
-    else 
-    if (node.type === '​identifier'​) 
-    { 
- 
-    } 
-    else 
-    if (node.type === '​expression'​) 
-    { 
-        if (node.left !== undefined && node.right !== undefined) 
-        { 
-            ​ 
-        } 
-    } 
-} 
-  
-var ast = parser.parse (str); 
-console.log (JSON.stringify(ast,​ null, 4)); 
-  
-writeThreeAddressCode(ast);​ 
-</​code>​ 
- 
- 
-===== Exercises ===== 
- 
-  - Dans un fichier texte **ex1.txt**,​ écrivez le code de trois adresses avec une pile pour les expressions suivantes (**1p**) 
-    * (5-3)*7+(2+4) 
-    * a = (5-3)*7+(2+4) 
-    * e = (a+5)/(a-2) 
-  - Dans un fichier texte **ex2.txt**,​ écrivez le code de trois adresses avec une pile pour le programme suivant (**1p**) <code javascript>​ 
-if (a > 0) 
-{ 
-  result = '​positive';​ 
-} 
-else 
-{ 
-  result = '​negative';​ 
-} 
-</​code>​ 
-  -  Dans un fichier texte **ex3.txt**,​ écrivez le code de trois adresses avec une pile pour le programme suivant (**1p**) <code javascript>​ 
-function double (nr) 
-{ 
-    return nr*2; 
-} 
-  
-double (7/2); 
-</​code>​ 
-  - Téléchargez [[https://​github.com/​UPB-FILS/​alf/​tree/​master/​TP/​TP10|la structure]] du TP. Exécutez le parser du laboratoire et écrivez un programme qui écrit le three address code pour les noeuds //​expression//​ avec une pile (**2p**) 
-  - Modifiez la grammaire (le fichier //alf.y//) pour que les appels de fonction puissent être à l'​intérieur des expressions. (Exemple: ''​2 + 3 / double(a)''​). Testez la validité de la grammaire avec le fichier **ex5.txt** et vérifiez que le programme ne retourne aucune erreur. (**1p**) 
-  - Ecrivez un programme qui écrit le three address code avec une pile pour le noeud //assign//. Testez avec le fichier **ex6.txt**. (**1p**) 
-  - Écrivez un programme qui écrit le three address code avec une pile pour les noeds //​function_call//​. Testez avec le fichier **ex7.txt**. (**2p**) 
-  - Écrivez un programme qui écrit le three address code avec une pile pour les noeuds //​function//​. Tout d'​abord,​ il faut modifier la grammaire afin qu'​elle accepte la déclaration des fonctions <​code>​ 
-    function function_name(param1,​ param2, ...) 
-    { 
-       ​statement1 
-       ​statement2 
-       ... 
-    } 
-    </​code>​ 
-    Suivez les lignes marquées par TODO8 afin de générer le Three Address Code pour les fonctions. (**2p**) 
- 
- 
-===== Solutions ===== 
- 
-[[https://​github.com/​UPB-FILS/​alf/​tree/​master/​TP/​TP10|Solutions]] 
  
  
alf/laboratoare/10.1618475604.txt.gz · Last modified: 2021/04/15 11:33 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