Differences

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

Link to this comparison view

alf:laboratoare:10 [2018/05/03 00:00]
alexandru.radovici
alf:laboratoare:10 [2021/05/16 21:26] (current)
diana.ghindaoanu
Line 1: Line 1:
-====== TP 10 - Generation du code 2 ======+====== TP 10 - Assambleur ​======
  
-===== Three Address Code ===== +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
-Le code de trois adresses est un moyen d'écrire des instructionsChaque instruction consiste en+  * 4 Hz 
-  * maximum trois adresses (variablesnumeroétiquette, ...) +  * 4 registres à usage général ABC si D 
-  * operateur +  * un registre pour l'​instruction IP actuelle 
-  * resultat+  * un registre pour le sommet de la pile SP 
 +  * 256 B RAM 
 +  * 24 B mémoire vidéo (derniers octets de RAM)
  
-===== Expression Parser =====+La description de simulateur este disponible [[https://​www.mschweighauser.com/​make-your-own-assembler-simulator-in-javascript-part1/​]].
  
-<code jison program.jison>​ +===== L'ensemble d'instructions  ​=====
-/* Jison example file */ +
-  +
-/* Tokens part */ +
-%lex +
-  +
-%% +
-  +
-/* RegEx */ +
-  +
-// add newline for Windows (\r\n) and Linux/​Unix/​Mac (\n) +
-\r?​\n return '​NEWLINE';​ +
-// \s includes \n space and tab, we need the NEWLINE token, so we put space and tab in white spacve +
-[ \t]                   /* skip whitespace */  +
-function return '​FUNCTION';​ +
-endfunction ​                ​return '​END_FUNCTION';​ +
-[0-9]+("​."​[0-9]+)? ​ return '​NUMBER';​  +
-\"​[^\"​]*\"​ return '​STRING_VALUE';​ +
-// add the token for the variable +
-[A-Za-z][A-Za-z0-9]* ​ return '​IDENTIFIER';​ +
-'='​  ​         return '='; +
-"​-" ​                  ​return '​-';​ +
-"​+" ​                  ​return '​+';​ +
-"​*" ​                  ​return '​*';​ +
-"/" ​                  ​return '/';​ +
-"​(" ​                  ​return '​(';​ +
-"​)"​  ​                 return '​)';​ +
-','​  ​         return ',';​ +
-  +
-  +
-  +
-/lex +
-  +
-/* Grammar part, for this lab */ +
-  +
-// when it is ambiguous, derive the left part +
-%left '​+'​ '​-'​ +
-// * and / have higher priority +
-%left '​*'​ '/'​  +
-  +
-%%  +
-  +
-start: expressions {  +
- $$ ​ +
-+
-     type:'​script',​ +
-     statements: $1 +
- }; +
-                 ​return $$;  +
-            }; +
-  +
-expressions:​ statement NEWLINE expressions { +
-                                                $3.splice (0, 0, $1); +
-                                                $$ $3; +
-+
- | statement NEWLINE { +
- $$ ​[$1]; +
-+
- | statement { +
- $$ = [$1]; +
- }; +
-  +
-statement: ​ expr  { +
-                     +
-                } +
-            | assign { +
-                        +
-                    } +
-            | function_run { +
-             +
-            }; +
-  +
-  +
-expr: '(' ​expr '​)'​ { +
- $$ ​$2;  +
-+
-   | expr '​+'​ expr {  +
- $$ ​+
-     type: '​expr',​ +
-     op: '​+',​ +
-     left: $1, +
-     right: $3 +
- }; +
-+
-      | expr '​-'​ expr { +
-        $$ ​+
-        type: '​expr',​ +
-        op: '​-',​ +
-        left: $1, +
-        right: $3 +
-    }; +
-      } +
-      | expr '​*'​ expr {  +
-    $$ +
-     type: '​expr',​ +
-     op: '​*',​ +
-     left: $1, +
-     right: $3 +
- }; +
-+
-      | expr '/'​ expr { +
-    $$ ​+
-        type: '​expr',​ +
-        op: '/',​ +
-        left: $1, +
-        right: $3 +
-    }; +
-      } +
-      | IDENTIFIER +
-                { +
-                    $$ = { +
-              type: '​id',​ +
-              value: $1 +
-          }; +
-                } +
-      | NUMBER {  +
-   $$ = { +
-       type: '​number',​ +
-       value: parseFloat ($1) +
-   }; +
-   } +
-    | STRING_VALUE { +
- $$ = { +
-       type: '​string',​ +
-       value: $1.substring (1, $1.length-2) +
-   }; +
- }; +
-  +
-assign: IDENTIFIER '​='​ expr +
-            { +
-                $$ = { +
-                    type: '​assign',​ +
-                    to: $1, +
-                    from: $3 +
-                }; +
-            } +
-        | IDENTIFIER '​='​ function_run  +
-        { +
-            $$ = { +
-                    type: '​assign',​ +
-                    to: $1, +
-                    from: $3 +
-                }; +
-        }; +
-  +
-function_run:​ IDENTIFIER '​('​ parameters_run '​)'​ { +
- $$ = { +
-  ​   type: '​function_run',​ +
-  ​   id: $1, +
-  ​   parameters: $3 +
- };​ +
- };​ +
-  +
-parameters_run:​ expr ','​ parameters_run +
-+
-     $3.splice (0, 0, $1); +
- $$ = $3; +
-+
- | expr +
-+
- $$ = [$1]; +
-+
- | { +
- $$ = []; +
- }; +
-function: '​function'​ IDENTIFIER '​('​ parameters '​)'​ '​{'​ expressions '​}'​ { +
-    $$ = { +
-        type: '​function',​ +
-        parameters: $4, +
-        statements: $7 +
-    }; +
-};+
  
-parameters: IDENTIFIER ​',' ​parameters +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 
-     $3.splice ​(0, 0, $1); +  * add - addition 
- $$ = $3; +  * sub - soustraction 
- } +  * inc - incrémentation 
- | IDENTIFIER +  * dec - decrémentation 
-+  * mul - multiplication 
- $$ = [$1]; +  * div - division 
- } +  * and - et sur les bits 
- | { +  * or - ou sur les bits 
- $$ = []; +  * xor - xor  
- }; +  * not - negation des bits 
-</​code>​+  * shl - décaler vers la gauche ​(équivalent a la multiplication par 2) 
 +  * shr 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
  
-<code javascript main.js> 
-"use strict";​ 
-  
-// import fs for reading ​ 
-var fs = require ('​fs'​);​ 
-  
-// import the generated Parser 
-var parser = require ('​./​program.js'​).parser;​ 
-  
-var str = fs.readFileSync (process.argv[2],​ '​UTF-8'​);​ 
  
-  +L'ensemble d'instructions avec sa description est disponible sur le site Web du simulateur [[https://schweigi.github.io/assembler-simulator/instruction-set.html]].
-function writeThreeAddressCode (node) +
-+
-    if (node.type === 'script'+
-    { +
-        for (var statementIndex in node.statements) +
-        { +
-            writeThreeAddressCode(node.statements[statementIndex]);​ +
-        } +
-    } +
-    else +
-    if (node.type === '​expr'​) +
-    { +
-        if (node.left !== undefined && node.right !== undefined) +
-        { +
-            writeThreeAddressCode (node.left);​ +
-            writeThreeAddressCode (node.right);​ +
-            ​// node.left is the result of node.left +
-            ​// node.right is the result of node.right +
-            // write the three address code here +
-        } +
-    } +
-    else +
-    if (node.type === '​number'​) +
-    { +
-        // the result for a number is the number itself +
-        console.log ('push '​+node.value);​ +
-    } +
-    else +
-    if (node.type === '​id'​) +
-    { +
-         +
-    } +
-    else +
-    if (node.type === '​function_run'​) +
-    { +
-         +
-    } +
-    else +
-    if (node.type === '​function'​) +
-    { +
-         +
-    } +
-}+
  
-var ast = parser.parse (str); 
-console.log (JSON.stringify(ast,​ null, 4)); 
  
-writeThreeAddressCode(ast); +==== Exercises ==== 
-  +  - Exécutez le programme initial. Changez le nom de la variable et essayez de comprendre comment écrire votre nom sur la sortie ​(**2p**
-</code>+  - Écrivez un programme qui place les nombres 0, 2, 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 B. Retournez la valeur de l'​oppération ''​17%3''​. Expliquez qu'​est-ce qui se passe. (**1p**) 
 +  - É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 des registres. Retournez le swap entre les registres A et B. (**2p**). 
 +  - É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**)
  
-===== Objectif ===== 
- 
-Nous voulons transformer l'AST suivant en une liste de Three Address Code avec une pile. 
- 
-===== Exercises ===== 
- 
-  - Ecrivez le code de trois adresses avec une pile pour les expressions suivantes (**1p**) 
-    * 2+3*(5+6) 
-    * s = 2+3*(5+6) 
-    * e = (s+3)-(s+4) 
-  - Ecrivez le code de trois adresses avec une pile pour le programme suivant (**1p**) <code javascript>​ 
-if (x < 0) 
-{ 
-  r = 'unde zero'; 
-} 
-else 
-{ 
-  r = 'above zero'; 
-} 
-</​code>​ 
-  - Ecrivez le code de trois adresses avec une pile pour le programme suivant (**1p**) <code javascript>​ 
-function square (x) 
-{ 
-    return x*x; 
-} 
- 
-square (5+6); 
-</​code>​ 
-  - Exécutez le parser du laboratoire et écrivez un programme qui écrit le three address code pour les noeds //expr// (indice: pour nommer les variables temporaires,​ vous pouvez prendre un compteur global que vous incrémentez chaque fois que vous avez besoin d'une autre variable) <spoiler AST><​code javascript>​ 
-{ 
-    "​type":​ "​script",​ 
-    "​statements":​ [ 
-        { 
-            "​type":​ "​expr",​ 
-            "​op":​ "​+",​ 
-            "​left":​ { 
-                "​type":​ "​expr",​ 
-                "​op":​ "​+",​ 
-                "​left":​ { 
-                    "​type":​ "​expr",​ 
-                    "​op":​ "​+",​ 
-                    "​left":​ { 
-                        "​type":​ "​number",​ 
-                        "​value":​ 2 
-                    }, 
-                    "​right":​ { 
-                        "​type":​ "​number",​ 
-                        "​value":​ 3 
-                    } 
-                }, 
-                "​right":​ { 
-                    "​type":​ "​number",​ 
-                    "​value":​ 5 
-                } 
-            }, 
-            "​right":​ { 
-                "​type":​ "​expr",​ 
-                "​op":​ "​*",​ 
-                "​left":​ { 
-                    "​type":​ "​id",​ 
-                    "​value":​ "​a"​ 
-                }, 
-                "​right":​ { 
-                    "​type":​ "​number",​ 
-                    "​value":​ 5 
-                } 
-            } 
-        }, 
-        { 
-            "​type":​ "​assign",​ 
-            "​to":​ "​a",​ 
-            "​from":​ { 
-                "​type":​ "​function_run",​ 
-                "​id":​ "​print",​ 
-                "​parameters":​ [ 
-                    { 
-                        "​type":​ "​expr",​ 
-                        "​op":​ "​+",​ 
-                        "​left":​ { 
-                            "​type":​ "​number",​ 
-                            "​value":​ 2 
-                        }, 
-                        "​right":​ { 
-                            "​type":​ "​number",​ 
-                            "​value":​ 3 
-                        } 
-                    }, 
-                    { 
-                        "​type":​ "​id",​ 
-                        "​value":​ "​a"​ 
-                    } 
-                ] 
-            } 
-        } 
-    ] 
-} 
-</​code></​spoiler>​(**2p**) 
-  - Modifiez la grammaire pour que les appels de fonction puissent être à l'​intérieur des expressions. (**1p**) 
-  - Ecrire un programme qui écrit le three address code avec une pile pour les noeds //assign// (**1p**) 
-  - Écrivez un programme qui écrit le three address code avec une pile pour les noeds //​function_run//​ (**2p**) 
-  - Écrivez un programme qui écrit le three address code avec une pile pour les noeds //​function//​. Un paramètre est lu dans la fonction en utilisant l'​instruction '​index'​ suivie de la position du paramètre. (**1p**) 
- 
- 
-===== Solutions ===== 
  
  
 +<​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>​
  
  
  
  
alf/laboratoare/10.1525294821.txt.gz · Last modified: 2018/05/03 00:00 by alexandru.radovici
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