diff options
Diffstat (limited to 'doc/probs.tex')
-rw-r--r-- | doc/probs.tex | 112 |
1 files changed, 104 insertions, 8 deletions
diff --git a/doc/probs.tex b/doc/probs.tex index 220edad..5b7a640 100644 --- a/doc/probs.tex +++ b/doc/probs.tex @@ -1,17 +1,109 @@ \chapter{Description des solutions technologiques} -\section{Parseur et Meta-Parseur} - - -\section{Assembleur} +\section{Meta-Parseur} %description du meta langage %format du fichier instructions.txt %description du langage asm... +Le meta langage a été développé comme nous l'avons proposé dans notre analyse, et voici sa decription complète\\ +Le fichier écrit en méta langage doit être écrit et analysé ligne par ligne, chaque ligne ayant une signification +discincte suivant son premier caractère: +\begin{itemize} +\item F sert à décrire un champ de bits. Le champ appelé 'I' est le champ d'instruction principal et sera utilisé pour +créer les instructions finales. Sa syntaxe est la suivante:// +\begin{verbatim} +Fnom:champ1,taille1;champ2;taille2;... +\end{verbatim} +Par exemple, notre FI:c3,6;c2,6;c1,6;e,6;op,8 nous sert à décrire parfaitement le champ d'opcode général tel que décrit +dans notre analyse. c1, c2, et c3 sont les noms des trois champs arguments, e est le nom du champ d'extension, et op est +le nom du champ d'opcode. +\item P sert à décrire une "pattern". Toute instruction va suivre un schéma particulier, et nous pouvons le quantifier grâce +à ce système de partition. La variable générée par l'évaluation d'une pattern sera égale à l'indice de la chaîne trouvée +dans la pattern. Voici la syntaxe d'une telle ligne: +\begin{verbatim} +Pnom:pattern1;pattern2;pattern3;... +\end{verbatim} +Chaque pattern possède elle même une syntaxe propre pouvant se classifier en 5 groupes principaux: +\begin{itemize} +\item Une chaîne de caractères qui sera reconnue telle quelle. +\item Une autre pattern qui sera stoquée dans une variable suivant la syntaxe: nomvar=.Pnom +\item Une déclaration d'adresse stoquée dans une valeur immédiate suivant la syntaxe: .I=.O +\item Une déclaration de décalage (utilisant l'opérateur [) qui peut se faire soit par une pattern immédiate sous la syntaxe [nomvar=.Pnom +soit par le décalage d'une autre adresse sous la syntaxe .I=.O[nomvar=.Pnom +\end{itemize} +Ainsi nous avons une pattern pour les registres (Pr:R0;R1;R2;...) et une pattern pour toutes les adresses (Pm::regop=.Pr;.I=.O;[regop=.Pr;.I=.O[regop=.Pr) +et les numéros d'indices de chaque élément correspond bien aux spécifications données dans notre analyse. +\item I sert à décrire une instruction. Une ligne I est décomposée en deux partie. La ligne ne suit pas de syntaxe particulière dans sa première partie, +car nous devons pouvoir décrire n'importe quelle style d'instruction. Par exemple, nous avons I:ADD c1=.Pr,c2=.Pr,c3=.Pr; qui signifie que nous décrivons +l'instruction ADD suivie de trois registres dont les indices correspondants seront mis dans les variables c1, c2 et c3 respectivement. La deuxième partie +de la ligne (après le ;) sert à donner la listes des variables implicites. Dans l'exemple de notre ADD, nous avons ceci: op=0x0;e=0x0 ce qui signifie que les +variable op et e doivent être mises à zéro. Ainsi, chaque ligne sera évaluée récursivement en fonction des différentes variables et des différents champs spécifiés. +Dans notre cas, comme nous avons FI qui déclare les variables c1, c2, c3, e, et op, il nous faut obligatoirement ces 5 variables pour chaque instruction. +Enfin, chaque élément de l'instruction peut suivre aussi des formes différentes. En voici la liste: +\begin{itemize} +\item Nous pouvons avoir une chaîne toute seule (comme ADD dans notre cas) pour dire qu'il faut que cette chaîne soit présente dans +le code source assembleur. +\item Nous pouvons avoir comme nous l'avons vu la syntaxe variable=.Pnom. Cela signifie qu'à cet endroit de la ligne source assembleur +doit se trouver un mot pouvant évaluer la pattern, et qu'il faut placer l'indice évalué dans la variable spécifiée. +\item Nous pouvois avoir .I=.C ce qui signifie qu`à cet endroit là doit se trouver une constante, qui sera placée immédiatement après +l'opcode de l'instruction. +\item Nous pouvons enfin avoir .I=.O ce qui signifie qu'à cet endroit là doit se trouver une adresse directe. +\end{itemize} +Dans la liste des instructions de la seconde partie, nous pouvons avoir aussi la déclaration variable=.Fnom, ce qui signifie que la variable +indiquée sera évaluée par le champ de bit spécifié. Enfin nous pouvons aussi avoir la déclaration variable1=variable2. +\end{itemize} +Ce meta langage nous a permi de décrire une grande partie des instructions dont nous avons parlé dans l'analyse. Voici ce fichier: +\verbatiminput{../samples/instructions.txt} + +\section{Parseur} +Le parseur est un morceau de code relativement simple. Il va lire une ligne en entrée et va la décomposer en deux catégorie d'éléments: +\begin{itemize} +\item Des symboles +\item Des opérateurs +\end{itemize} +Tout est traité suivant une pile polonaise inversée. Par exemple, l'expression 1 + 2 * 3 + 4 sera traitée comme suit: +\begin{verbatim} +PushSymbol(1) +PushSymbol(2) +PushSymbol(3) +ActPile(*) +ActPile(+) +PushSymbol(4) +ActPile(+) +\end{verbatim} +Les fonctions PushSymbol et ActPile sont des symboles globaux et sont définis dans l'assembleur. +\section{Assembleur} +L'assembleur, s'il a l'air complexe par la taille de son code source, est en fait relativement simple aussi. Il est articulé sur un mécanisme +très simple: tout symbole provenant du parseur sera encapsulé dans des bulles qui seront évaluées au fur et à mesure de la progression de +l'assemblage du code source. Au pire, au stade final de l'assemblage, lors de la génération du fichier objet, nous aurons des symboles +que l'éditeur de liens se fera une joie de résoudre et de compléter. Dans tous les cas, l'analyse du fichier se fait sur quatre niveaux: +\begin{itemize} +\item Lors de l'ajout d'un symbole par le parseur. +\item Lors de l'ajout d'un opérateur par le parseur. +\item Lors d'une fin de ligne. +\item Lors de la fin du fichier source. +\end{itemize} +A chacun de ces quatre niveaux se trouve des paliers d'évaluations. Si un symbole, une expression ou une ligne ne peut pas +passer ce palier, une erreur sera générée. Ces paliers deviennent de plus en plus stricts suivant les niveaux passés. Ainsi, comme décrit +plus haut, le dernier palier ne peut que laisser passer des valeurs immédiates ou bien des symboles à reloger par l'éditeur de liens.\\ +L'assembleur possède aussi quelques symboles prédéfinis: +\begin{itemize} +\item .text pour déclarer l'écriture dans le segment de text +\item .data pour déclarer l'écriture dans le segment de data +\item .bss pour déclarer l'écriture dans le segment bss +\item .start pour déclarer le point d'entrée +\item DB, DW et DD pour enregistrer un ou plusieurs mots mémoires +\item DS pour enregistrer une chaîne de caractères +\item DR pour enregistrer un tableau de mots non initialisés. +\end{itemize} \section{Editeur de liens} -%mecanisme de relocation +Les fichiers objets générés par l'assembleur ont une struture suffisamment simple pour que l'éditeur de liens ait un travail très simplifié: +il charge d'affilé tous les fichiers objets à lier, et va créer une table de tous les symboles internes. Puis il va concaténer tous les +segments de text ensemble, tous les segments de data ensemble, et va reloger les références croisées suivant la table des symboles internes. +Le fichier de sortie est un binaire qui suit les spécification de notre analyse. La table de relogement nous sert à indiquer toutes +les références à des symboles absolus, de sorte à pouvoir placer le binaire n'importe où dans la mémoire de notre CPU virtuel. \section{Operations ALU} %algos ALU lente @@ -38,11 +130,15 @@ Pour la division, nous utilisons comme pour la multiplication deux registres, un division et pour ce faire on utilise l'algorithme de notre jeunesse. Pour les deux fonctions de décalage, nous décalons les bits du nombre demandé et on remplace les bits manquants par 0. +\section{MiniOS} +Notre MiniOS n'a qu'un role très restreint: celui de charger un binaire et le reloger correctement en mémoire, et d'effectuer +des petits travaux d'interfaces homme/machine. Toutes les fonctions d'interface pensées pendant l'analyse ont été implémentées. +Lors du chargement d'un binaire, il va initialiser correctement toutes les informations nécessaires au bon déroulement du programme. \section{Contrôleur} -%decodage, execution, gestion de la ram - -\section{MiniOS} +Le contrôleur va prendre la main dès qu'un binaire aura été chargé en mémoire. Il va décoder le binaire instructions par instructions, +et va activer les différents composants de notre CPU: les registres, l'alu et la mémoire. L'accès à la mémoire fait l'objet d'un code +très spécifique, car c'est en écrivant à certains offsets mémoire que nous pouvons récupérer des informations devant aller vers le MiniOS. |