From ebeaa609baf00a783273eadfd4586fea050d55c9 Mon Sep 17 00:00:00 2001 From: biouman <> Date: Tue, 17 Apr 2001 02:42:06 +0000 Subject: *** empty log message *** --- doc/Makefile.doc | 23 ++++ doc/archi.tex | 4 + doc/bib.tex | 10 ++ doc/compilateur.tex | 157 +++++++++++++++++++++++++++ doc/conclusion.tex | 11 ++ doc/description.tex | 40 +++++++ doc/encodage.tex | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/extensions.tex | 14 +++ doc/intro.tex | 20 ++++ doc/simulateur.tex | 120 +++++++++++++++++++++ doc/source.tex | 7 ++ 11 files changed, 709 insertions(+) create mode 100644 doc/Makefile.doc create mode 100644 doc/bib.tex create mode 100644 doc/compilateur.tex create mode 100644 doc/conclusion.tex create mode 100644 doc/description.tex create mode 100644 doc/encodage.tex create mode 100644 doc/extensions.tex create mode 100644 doc/intro.tex create mode 100644 doc/simulateur.tex create mode 100644 doc/source.tex diff --git a/doc/Makefile.doc b/doc/Makefile.doc new file mode 100644 index 0000000..84673e9 --- /dev/null +++ b/doc/Makefile.doc @@ -0,0 +1,23 @@ +PROJET=archi + +all: $(PROJET).dvi + +$(PROJET).dvi: archi.tex bib.tex compilateur.tex conclusion.tex description.tex encodage.tex extensions.tex intro.tex simulateur.tex Compilo.eps + echo + echo pass1 + echo + latex $(PROJET) + echo + echo pass2 + echo + latex $(PROJET) + +source: for i in `find .. -name "*.c" -or -name "*.h" | grep -v /intl/ | grep -v /po/`; do echo "\paragraph{$i}"; echo "\lstinputlisting{$i}"; done > source.tex + +ps: $(PROJET).ps + +$(PROJET).ps: $(PROJET).dvi + dvips $(PROJET) + +clean: + rm -f *.dvi *.aux *.toc *.ps *.log diff --git a/doc/archi.tex b/doc/archi.tex index d7a8ef4..31ebdd4 100644 --- a/doc/archi.tex +++ b/doc/archi.tex @@ -67,7 +67,11 @@ \input{extensions} \clearemptydoublepage \part{Synthèse} + +\chapter{Code Source} +\lstset{language=C,basicstyle=\small} \input{source} + \clearemptydoublepage \input{conclusion} \clearemptydoublepage diff --git a/doc/bib.tex b/doc/bib.tex new file mode 100644 index 0000000..835771b --- /dev/null +++ b/doc/bib.tex @@ -0,0 +1,10 @@ +\begin{thebibliography}{WWW99} +% pour citer le Tanenbaum : \cite{Tanenbaum} +% pour citer le Tanenbaum page 238 : \cite[page 238]{Tanenbaum} + +\bibitem[TAN1]{Tanenbaum} A. Tanenbaum \textit{Architecture des Ordinateurs}, Dunod. +\bibitem[FAB1]{Asmfacile} B. Fabrot \textit{Assembleur - Théorie, pratique et exercices}, Marabout Informatique. +\bibitem[TIS1]{Biblepc} M. Tischer \textit{La Bible PC - Programmation système}, 5$^{e}$ édition, Micro Application. +\bibitem[PRO1]{Bluebook} R. Hummel \textit{Processeur et Coprocesseur}, Dunod Tech. + +\end{thebibliography} diff --git a/doc/compilateur.tex b/doc/compilateur.tex new file mode 100644 index 0000000..baed25e --- /dev/null +++ b/doc/compilateur.tex @@ -0,0 +1,157 @@ +\chapter{Partie assembleur} + +\section{Assembleur} + +\paragraph{} +L'assembleur que nous avons choisi de concevoir se décrit suivant le modèle ci-dessous: +\\ + +\includegraphics{Compilo.eps} + +\paragraph{} +L'assembleur en lui-même est constitué de quatre parties distinctes: +\begin{itemize} +\item Le parser de code source assembleur. Il va lire le fichier source et effectuer les premiers +traitements nécessaires pour que l'analyseur syntaxique n'ait à traiter que des éléments simples. +\item Le méta parser du métalangage descriptif des instructions. Il sera exécuté au tout début +afin de créer les structures de données nécessaires à l'analyseur syntaxique. +\item L'analyseur syntaxique chargé d'effectuer la première phase de l'assemblage. Il va lire le +fichier source et va produire un premier "flux" binaire. Seules les instructions et les valeurs +immédiates seront encodées. Toutes les adresses seront laissées de coté. +\item Le solveur de symboles qui va effectuer la deuxième phase de l'assemblage. Il va simplement +lire le résultat de l'analyseur syntaxique et tenter de remplir tous les trous laissés par celui-ci. +\end{itemize} +La lecture du fichier est donc effectuée en une seule passe, sans besoin d'une quelconque relecture +ultérieure. Il s'agit donc d'un assembleur une passe. Les machines actuelles n'ont plus la +nécessité d'un assembleur deux passes car la puissance et la mémoire sont telles que le +programme peut être assemblé entièrement en mémoire. De plus, l'abstraction du microprocesseur +que nous simulons est suffisamment simple pour nous éviter les problèmes sur le calcul des adresses +en avant: en effet il n'existe qu'une seule forme d'adressage possible, alors que sur i386 par +exemple, un JMP en avant peut se coder sur 16, 24, 32 ou même 56 bits. + +\paragraph{} +Nous avons choisi d'implémenter un système de métalangage servant à décrire les instructions +assembleur, ceci afin de servir deux buts: +\begin{itemize} +\item Alléger l'analyseur syntaxique. +\item Simplifier le travail d'une éventuelle évolution. +\end{itemize} +\paragraph{} +Ce système est très simple, et a été imaginé à partir du langage de programmation CAML. Il permet de +décrire le langage assembleur par "\textit{pattern}". Le méta langage supporte principalement quatre +types de définitions: +\begin{itemize} +\item la définition d'un champ de bits, +\item la définition d'une \textit{pattern}, +\item la définition d'une instruction, +\item et la définition d'un phonème entre deux instructions. +\end{itemize} +\paragraph{} +L'assembleur en lui-même va lire le fichier texte en entrée, tenter de trouver une instruction qui +correspond à une des instructions décrites dans le méta langage, et créer le champ de bits décrit +dans le méta langage. +\paragraph{} +La sortie de l'assembleur est un fichier objet dont le format est quasiment identique à celui de +l'éditeur de liens, à la différence près qu'une table des symboles internes et externes est présente. +\paragraph{Encodage du fichier objet} +\subparagraph{} +Voici l'encodage du fichier objet:\\ +\begin{center} +\begin{tabular}{|c|c|l|} +\hline +%il faut recentrer la ligne de titre pour la troisième colonne... +\textbf{Emplacement} & \textbf{Taille} & \textbf{Signification} \\ +\hline +0 & 1 & Signature\footnotemark[1]\\ +\hline +1 & 1 & Taille totale du fichier binaire\\ +\hline +2 & 1 & Offset du point d'entrée du programme ($=-1$ si pas de point d'entrée)\\ +\hline +3 & 1 & Taille de la partie \textit{text} $(=nb)$\\ +\hline +4 & 1 & Taille des données statiques $(=ns)$\\ +\hline +5 & 1 & Taille des données non initialisées\\ +\hline +6 & 1 & Taille de la table des symboles $(=nr)$\\ +\hline +7 & $nr$ & Table des symboles\\ +\hline +$7+nr$ & $nb$ & Segment "\textit{text}"\\ +\hline +$7+nr+nb$ & $ns$ & Segment des données statiques\\ +\hline +\end{tabular} +\end{center} +\footnotetext[1]{Nous avons fixé la signature d'un fichier objet a : 0x4f424e4e.} + +\subparagraph{} + + +Organisation de la table des symboles:\\ +\begin{center} +\begin{tabular}{|c|c|l|} +\hline +\textbf{Emplacement} & \textbf{Taille} & \textbf{Signification} \\ +\hline +0 & 1 & Nombre d'entrées\\ +\hline +1 & $nr-1$ & Entrées\\ +\hline +\end{tabular} +\end{center} +\subparagraph{} +Format d'une entrée:\\ +\begin{center} +\begin{tabular}{|c|c|l|} +\hline +\textbf{Emplacement} & \textbf{Taille} & \textbf{Signification} \\ +\hline +0 & 1 & Type du symbole\\ + & & 0 = symbole interne de type \textit{text}\\ + & & 1 = symbole externe de type \textit{text}\\ + & & 2 = symbole interne de type \textit{data}\\ + & & 3 = symbole externe de type \textit{data}\\ + & & 4 = symbole interne de type \textit{bss}\\ +\hline +1 & 1 & Décalage du symbole dans le segment de \textit{text}\\ +\hline +2 & 1 & Taille du nom du symbole $(=st)$\\ +\hline +3 & $st$ & Symbole\\ +\hline +\end{tabular} +\end{center} +\subparagraph{} +Si un symbole est externe, alors le décalage indique l'endroit où il y est +fait référence. Il peut donc y avoir plusieurs symboles externes dans un même +fichier objet. Si un symbole est interne, alors le décalage indique son emplacement +soit dans le segment \textit{text}, soit dans le segment \textit{data}. + +\section{Éditeur de liens} +L'éditeur de liens fonctionne selon un mode simple. Il va cumuler ensemble tous les +fichiers objets, en concaténant tous les segments \textit{text} et segments +\textit{data}, puis en remplaçant tous les symboles externes par leur valeur +correcte. Puis il produira un fichier exécutable comme défini à la +section~\ref{encodage_binaire}, page~\pageref{encodage_binaire}. + +\section{MiniOS} +\paragraph{} +\label{MiniOS} +Pour pouvoir charger un binaire, effectuer le travail de relogement et effectuer +quelques travaux d'entrées/sorties avec le simulateur, nous avons besoin d'un +tout petit "système d'exploitation". Comme il ne s'agit pas de simuler un "vrai" +système d'exploitation, il sera programmé en C et non en langage d'assemblage. +Son utilité étant très limitée, nous n'avons pas besoin de créer quelque chose +de très complexe: quelques appels systèmes très simples seront mis en place pour +permettre les entrées/sorties\footnote{voir l'interface, section~\ref{Interface}, +page~\pageref{Interface}}. Nous aurions pu intégrer directement ces fonctions +dans le code source C du simulateur, mais nous avons décidé de le dissocier du +module simulateur pour une éventuelle extension. +\paragraph{} +\label{relogement} +Le relogement effectué par le MiniOS fonctionne sur un principe très simple: +il va lire la table de relogement présente dans le fichier exécutable et pour +chaque entrée, il va rajouter l'offset auquel l'exécutable aura été chargé. +Ceci aura pour effet de reloger toutes les références absolues dans le code. diff --git a/doc/conclusion.tex b/doc/conclusion.tex new file mode 100644 index 0000000..70bb052 --- /dev/null +++ b/doc/conclusion.tex @@ -0,0 +1,11 @@ +\chapter*{Conclusion} +\addcontentsline{toc}{chapter}{Conclusion} +\markboth{CONCLUSION}{CONCLUSION} + +Nous avons présenté ici nos idées pour la conception du projet. Ce +document constitue donc un premier "cahier des charges". Nous tenterons +de nous y tenir le plus possible afin de mener le projet à bien. Toutefois, nous +serons peut-être (sans doute) amenés à effectuer des modifications au +fil du développement. C'est pourquoi nous rééditerons ce document +ultérieurement, afin d'y reporter les changements éventuels que nous +aurons jugé utile d'effectuer. diff --git a/doc/description.tex b/doc/description.tex new file mode 100644 index 0000000..5def498 --- /dev/null +++ b/doc/description.tex @@ -0,0 +1,40 @@ +\chapter{Description} +\paragraph{} +Ce projet a pour but l'étude d'un microprocesseur en programmant +d'abord un simulateur pour ce microprocesseur, puis un assembleur +correspondant aux instructions définies pour le simulateur. +\paragraph{} +Le processeur que nous nous proposons de simuler est un processeur +du type "\textit{Load \& Store}". Il possède une quantité non +négligeable de registres, mais en contrepartie, toutes les instructions +doivent travailler directement sur ces registres. Il n'existe que deux +instructions permettant de lire ou d'écrire un mot en mémoire: les +instructions LD pour \textit{Load} et ST pour \textit{Store}. +\paragraph{} +Pour l'adressage, nous avons choisi de repérer chaque mot mémoire de 32 bits +par une adresse unique, vu que les instructions ne manipulent que des mots +mémoires sur 32 bits. En clair, même si l'assembleur gère des zones de données +dont les éléments sont de taille inférieur à 32 bits, (comme HALF, BYTE ou ASCII) +ils seront "compactés" en 32 bits et alignés sur des mots mémoires 32 bits. +\paragraph{} +Notre processeur supporte les opérations de base programmées sur une ALU +simplissime: ADD, SUB, MUL, DIV, AND, OR, SHL, SHR. De plus, le contrôleur +est capable d'effectuer des sauts conditionnels simples. +\paragraph{} +L'assembleur est capable de reconnaître les mnémoniques nécessaires à la +création d'un fichier binaire correspondant aux instructions supportées +par le simulateur. De plus, il est capable de gérer quelques pseudo-instructions: +\begin{itemize} +\item START pour définir le point d'entrée du programme. +\item ASCII pour stoker une chaîne ASCIIZ. +\item BYTE pour stoker une série d'octets consécutifs. +\item WORD pour stoker une série de mots 32 bits consécutifs. +\item HALF pour stoker une série de mots 16 bits consécutifs. +\item SPACE pour réserver une série de mots dans le segment \textit{data} +\end{itemize} +L'encodage choisi est le little endian. Cette précision est nécessaire vu que +le simulateur fonctionne sur des mots de 32 bits. Ainsi, la pseudo instruction +\begin{verbatim} +Texte ASCII "ABCDEFG" +\end{verbatim} +va encoder effectivement les deux mots mémoires consécutifs: 0x44434241, 0x474645. diff --git a/doc/encodage.tex b/doc/encodage.tex new file mode 100644 index 0000000..a6daf55 --- /dev/null +++ b/doc/encodage.tex @@ -0,0 +1,303 @@ +\chapter{Encodage} + +\section{Encodage des instructions} + +\paragraph{} +Il nous a semblé primordial de commencer par cette partie afin de pouvoir +commencer à travailler. Le format des instructions est à notre avis la +partie la plus importante puisque son choix est déterminant pour la +programmation des deux parties de ce projet. + +\paragraph{} +Voici donc le fruit de notre réflexion: + + + + + + + + +\subparagraph{} +Les instructions seront codées selon le schéma suivant: + +\begin{center} +\begin{scriptsize} +\begin{tabular}{|c|c|c|c|c|} + +\multicolumn{1}{l}{31 \hfill 26} & \multicolumn{1}{l}{25 \hfill 20} & \multicolumn{1}{l}{19 \hfill 14} & +\multicolumn{1}{l}{13 \hfill 8} & \multicolumn{1}{l}{7 \hfill 0}\\ \cline{1 - 5} +Champ argument 3 & Champ argument 2 & Champ argument 1 & Extension & Opcode\\ \cline{ 1 - 5} +\multicolumn{1}{c}{\bracebits} & \multicolumn{1}{c}{\bracebits} & \multicolumn{1}{c}{\bracebits} & \multicolumn{1}{c}{\bracebits} & \multicolumn{1}{c}{\bracebits} +\\ +\multicolumn{1}{c}{6 bits} & \multicolumn{1}{c}{6 bits} & \multicolumn{1}{c}{6 bits} & \multicolumn{1}{c}{6 bits} & \multicolumn{1}{c}{8 bits} + +\end{tabular} +\end{scriptsize} +\end{center} + + + + + + + + + + + + + + +\subparagraph{Description des différents champs :} + +\begin{itemize} +\item Opcode : code d'opération sur 8 bits soit 256 opérations potentielles. +\item Extension\footnote{Le champ extension sera fréquemment noté par la suite champ Ext, de même les champs arguments seront abrégés en Chp1, Chp2, Chp3 } : champ servant à préciser les options de l'opération. \\ + \uline{ex} : pour une instruction de saut conditionnel, c'est ce champ qui va préciser la nature du test à effectuer sur les arguments (égalité, inférieur à, etc.). \\ + Il est à noter que la signification du champ Ext est spécifique à chaque instruction ou groupe d'instructions. (\uline{ex} : le groupe des instructions ALU) +\item Champs Arguments : Ces champs sont nécessaires à la représentation des différents arguments de l'instruction à exécuter. Ils peuvent désigner un registre ou une adresse mémoire. La différence d'interprétation de l'un de ces champs en tant que registre ou en tant qu'adresse est réalisée par un bit du champ Ext pour les instructions qui le requièrent. + + +\end{itemize} + + + + + + +\clearpage + + + + + + + + +\subparagraph{Encodage d'un champ argument représentant un registre :} + +\begin{center} +\begin{footnotesize} +\begin{tabular}{|c|c|} +\multicolumn{1}{c}{5} & \multicolumn{1}{c}{4 \hfill 0} \\ \hline +S & \hspace{0.5cm}val\hspace{0.5cm} \\ \hline +\end{tabular} +\end{footnotesize} +\end{center} + +Si le bit \emph{S} vaut 0, le registre encodé est un registre classique et \emph{val} vaut le numéro du registre (soit 32 registres encodables, exactement le nombre de registres présents dans le processeur que l'on se propose de simuler). \\ +Si le bit \emph{S} vaut 1, le registre encodé est un registre spécial : \\ +\begin{description} +\item[si val = 00 :] le registre est $R_g$ +\item[si val = 01 :] le registre est $R_d$ +\item[si val = 10 :] le registre est PC +\item[si val = 11 :] le registre est le registre de flags +\end{description} + +On pourra donc étendre le processeur avec 28 registres supplémentaires sans changer l'encodage des instructions. \\ +\uline{NB} : dans le processeur simulé, toute instruction voulant accéder à un registre non existant (si chp* > 0x24) déclenchera une exception. + + + + + + + + + + + +\subparagraph{Encodage d'un champ argument représentant une adresse :} +\begin{center} +\begin{footnotesize} +\begin{tabular}{|c|c|} + \multicolumn{1}{c}{5 \hfill 2} & \multicolumn{1}{c}{1 \hfill 0} \\ \cline{1 - 2} +\hspace{0.5cm}réservé\footnotemark[2] +\hspace{0.5cm} & r/m\\ \cline{1 - 2} +\end{tabular} +\end{footnotesize} +\end{center} +\footnotetext[2]{lorsque des bits sont "réservés", ceux-ci sont pour l'instant à zéro et ils pourront être utilisés ultérieurement.} + +\begin{description} +\item[si r/m = 00 :] le champ argument 3 désigne un champ qui est destination immédiate de l'instruction. +\item[si r/m = 01 :] l'adresse mémoire est une imm32\footnote[3]{valeur immédiate 32 bits} suivant directement l'instruction. +\item[si r/m = 10 :] l'adresse mémoire est contenue dans un registre désigné par le champ argument 3. +\item[si r/m = 11 :] l'adresse mémoire considérée est obtenue comme la somme de l'adresse contenue dans le registre désigné par le champ argument 3 et du décalage donné en imm32 à la suite de l'instruction. +\end{description} + +Cet encodage permet de décrire tous les types d'adressage (registre, direct, indexé). Les adressages faisant intervenir des symboles sont quant à eux gérés par le compilateur et l'éditeur de liens. + + +\uline{NB} : Une instruction peut être suivie au maximum de deux imm32, soit une longueur maximale de l'ensemble d'une instruction et de ses arguments de 3 mots (voir le tableau "Référence des instructions", page \pageref{mov}). + + + + +\pagebreak + +\subparagraph{Référence des instructions} + +\vspace*{0.5cm} +\begin{center} +\begin{tiny} + +\begin{tabular}{|c|c|c|c|c|} +\hline +Type d'instruction & Opcode & Instruction & Extension & Remarques \\ +\hline +\hline +Instructions ALU & \parbox[t]{0.8cm}{% +0x00 \\ 0x01 \\ 0x02 \\ 0x03 \\ 0x04 \\ 0x05 \\ 0x06 \\ 0x07 \\% +} & \parbox[t]{0.8cm}{ % +ADD \\ SUB \\ MUL \\ DIV \\ AND \\ OR \\ SHL \\ SHR \\% +} & \parbox[t]{4cm}{% +Si bit0=0 alors Arg1=Chp1, Arg2=Chp2, Arg3=Chp3, sinon Arg1=Chp1, Arg2=Chp2, Arg3=imm32. \\ Si bit1=1 alors l'instruction est signée.% +} & \parbox[t]{5cm}{% +Les instructions ALU admettent trois arguments : Arg1, Arg2 et Arg3.% +} \\ + +\hline +Instruction mémoire & \parbox[t]{0.8cm}{% +0x08\\% +} & \parbox[t]{0.8cm}{ % +MOV\footnotemark[4] \label{mov}\\% +} & \parbox[t]{4cm}{% +Si bit0=0 alors Arg2=Chp2, sinon Arg2=imm32 et Chp2=0x00. \\ Si bit1=0 MOV Arg1 Arg2, sinon MOV Arg2 Arg1. \\ Bits 2-3 : condition d'exécution de l'instruction suivant l'état des flags, ce test dépend des bits 4-5. 0x00=overflow, 0x01=zéro, 0x02=sign, 0x03=parité. \\ Bit 4 : active le MOV conditionnel. \\ Bit 5 : négation du test du MOV conditionnel.\\% +} & \parbox[t]{5cm}{% +MOV nécessite dans la plupart des cas un champ adresse en argument, si ce champ fait référence à un registre, celui-ci est encodé dans le champ 3. \\ On peut réaliser un MOV conditionnel à l'aide des bits 2-5 de Ext.% +} \\ + + +\hline + +Instruction nulle & \parbox[t]{0.8cm}{% +0x09 \\% +} & \parbox[t]{0.8cm}{ % +NOP \\% +} & \parbox[t]{4cm}{% +Tous les bits sont réservés.% +} & \parbox[t]{5cm}{% +Tous les bits des champs arguments sont réservés.\\% +} \\ + +\hline +Sauts conditionnels directs & \parbox[t]{0.8cm}{% +0x0a \\ 0x0b\\% +} & \parbox[t]{0.8cm}{ % +%JE \\ JNE \\ JL \\ JLE \\ JG \\ JGE \\ JO \\ JZ \\ JS \\ JP \\ JNO \\ JNZ\\ JNS% +%JNP \\ JEO \\ JENO \\% pas beau +J[cond] +} & \parbox[t]{4cm}{% +bits 1-0 : Test1\\ +- 00 $=$\\ +- 01 $\neq$\\ +- 10 $<$\\ +- 11 $\leq$\\ +\vspace{1mm}\\ +bits 3-2 : Test2\\ +- 00 overflow\\ +- 01 zero\\ +- 10 sign\\ +- 11 parity\\ +\vspace{1mm}\\ +Bits 5-4 Test final\\ +- 00 Test1\\ +- 01 Test1 $||$ Test2\\ +- 10 Test1 $\&\&$ $!$Test2\\ +- 11 Test1 $||$ $!$Test2\\ +} & \parbox[t]{5cm}{% +Cette instruction peut gérer un très grand nombre de tests. Il est trivial que les comparaisons de Test1 permettent d'obtenir toutes les comparaisons possibles, sachant que l'on peut changer l'ordre des arguments.\\ En ce qui concerne le test final, il est possible de réaliser uniquement Test2 en faisant $R_0=R_0$, ce test sera câblé et plus rapide que $R_i=R_i, i\ne0$.\\ +Les arguments de Test1 sont Chp1 et Chp2. Si le bit 0 de l'opcode vaut 0 alors le déplacement est absolu, sinon il est relatif. Notons que le déplacement est une imm32 présente après l'instruction.\\% +} \\ + +\hline +Sauts inconditionnels étendus & \parbox[t]{0.8cm}{% +0x0c \\ 0x0d\\% +} & \parbox[t]{0.8cm}{ % +JMP\\ CALL \\ RET \\% +} & \parbox[t]{4cm}{% +Si bit0=0 alors le branchement considéré est RET et Chp1 est une valeur immédiate de dépilement (sortie du cadre de pile) \\ Sinon~: \\ Si bit1=0 le branchement est JMP sinon il s'agit de CALL (avec sauvegarde de l'adresse de retour) \\ Si bit2=0 le branchement est direct (déplacement en imm32 après l'instruction) sinon le branchement est spécifié par Chp1\\% +} & \parbox[t]{5cm}{% +Si le bit 0 de l'opcode vaut 0 alors le déplacement est absolu, sinon il est relatif.% +} \\ + +\hline + +Instructions Pile & \parbox[t]{0.8cm}{% +0x0e \\ 0x0f\\% +} & \parbox[t]{0.8cm}{ % +PUSH \\ POP\\% +} & \parbox[t]{4cm}{% +Pour PUSH, si bit0=1 alors nous faisons le PUSH d'une constante dont l'imm32 est présent à la suite de l'instruction.\\% +} & \parbox[t]{5cm}{% +Chp1 représente le registre sur laquelle agit l'instruction.% +} \\ + +\hline +Instruction Arrêt & \parbox[t]{0.8cm}{% +0x7f\\% +} & \parbox[t]{0.8cm}{ % +HALT \\ RESET\\% +} & \parbox[t]{4cm}{% +Si bit0=0 HALT,\\ sinon RESET.\\ Les autres bits sont réservés.\\% +} & \parbox[t]{5cm}{% + % +} \\ + +\hline + + + + +\end{tabular} +\end{tiny} +\end{center} + +% note de bas de page relative à MOV (bidouille pr faire fonctionnner les +% footnotes dans les tableaux) attention, bidouillage du compteur footnote +\footnotetext[4]{Il se peut que l'instruction MOV nécessite deux imm32 après l'instruction (si r/m vaut 01 ou 11 et bit0 de Ext vaut 1), dans ce cas on les dispose dans cet ordre : instruction, imm32 adresse, imm32 constante.} + +Le jeu d'instructions que nous proposons est un "\textit{superset}" du jeu +d'instructions proposé pour la réalisation du projet: nous avons plus d'instructions +qu'il ne faudrait, mais l'ensemble des instructions demandées sont présentes. + +\clearpage +\section{Encodage du fichier binaire} +\label{encodage_binaire} +\paragraph{} +Tout le projet fonctionnant sur des mots de 32 bits, le fichier binaire est +un "flux" de mots organisé comme suit:\\ +\\ +\begin{center} +\begin{tabular}{|c|c|l|} +\hline +\textbf{Emplacement} & \textbf{Taille} & \multicolumn{1}{c|}{\textbf{Signification}} \\ +\hline +0 & 1 & Signature\footnotemark[5]\\ +\hline +1 & 1 & Taille totale du fichier binaire\\ +\hline +2 & 1 & Offset du point d'entrée du programme (à reloger)\\ +\hline +3 & 1 & Taille de la partie \textit{text} ($=nb$)\\ +\hline +4 & 1 & Taille des données statiques ($=ns$)\\ +\hline +5 & 1 & Taille des données non initialisées\\ +\hline +6 & 1 & Taille de la table de relogements ($=nr$)\\ +\hline +7 & $nr$ & Table des offsets de relogement\\ +\hline +{$7+nr$} & $nb$ & Segment "\textit{text}"\\ +\hline +{$7+nr+nb$} & $ns$ & Segment des données statiques\\ +\hline +\end{tabular} +\end{center} + +\footnotetext[5]{Nous avons fixé la signature d'un fichier executable à 0x58454e4e.} + +\uline{NB}: Nous détaillerons plus loin (voir section~\ref{relogement}, page~\pageref{relogement}) le mécanisme de relogement que nous avons choisi d'implémenter. diff --git a/doc/extensions.tex b/doc/extensions.tex new file mode 100644 index 0000000..7ca4b75 --- /dev/null +++ b/doc/extensions.tex @@ -0,0 +1,14 @@ +\chapter{Extensions possibles} +\section{Débogueur} +Nous tenterons d'implémenter un débogueur simple dans le simulateur, afin de +vérifier l'exécution. Cette extension nous parait nécessaire pour un effectuer +le développement d'un code source assembleur, ainsi que pour vérifier si le +simulateur fonctionne correctement. +\section{FPU} +Le FPU reste totalement à coder. Notre rôle s'arrête à une unité ALU simple. +Toutefois, les bases sont solidement posées pour que quelqu'un reprenne notre +code et effectue une extension FPU dans ce simulateur. +\section{Compilateur} +Une dernière extension possible est la réalisation d'un compilateur (C par exemple) +qui produirait un code assembleur conforme à notre spécification. Cette tâche ne pouvant en aucun cas être réalisée +à notre niveau, nous laissons le champ libre... diff --git a/doc/intro.tex b/doc/intro.tex new file mode 100644 index 0000000..ca6b112 --- /dev/null +++ b/doc/intro.tex @@ -0,0 +1,20 @@ +\chapter*{Introduction} +\addcontentsline{toc}{chapter}{Introduction} +\markboth{INTRODUCTION}{INTRODUCTION} + +\paragraph{} +Ce projet possède deux parties bien distinctes. La première a pour but +la réalisation du simulateur d'un microprocesseur inventé de toutes +pièces, et la seconde pour objectif la réalisation d'un assembleur nous +permettant de créer les binaires pouvant s'exécuter sur notre +microprocesseur. + +\paragraph{} +Ces deux parties ne sont absolument pas indépendantes. Il nous a fallu +dans un premier temps réfléchir à un format d'encodage des instructions, +qui soit en rapport avec le jeu d'instructions demandé. Ensuite, il nous +a fallu réfléchir à un format commun pour le fichier binaire. + +\paragraph{} +Ce présent document va tenter de décrire en totalité la progression de la +mise en forme de ce projet. Nous vous souhaitons bonne lecture. diff --git a/doc/simulateur.tex b/doc/simulateur.tex new file mode 100644 index 0000000..e6152ee --- /dev/null +++ b/doc/simulateur.tex @@ -0,0 +1,120 @@ +\chapter{Partie simulateur} + +\section{Unité arithmétique et logique} +\paragraph{} +L'unité arithmétique et logique (ou ALU) a été programmée de deux manières distinctes: +\begin{itemize} +\item Un premier module de calcul binaire, calculant sur les entiers bits à bits, lent +mais collant à la définition du sujet. +\item Un second module de calcul entier, rapide, mais s'écartant du sujet. +\end{itemize} +Il est possible d'utiliser l'un ou l'autre des modules. Nous désirons écrire le module +de calcul entier fonctionnant à l'aide des routines de calcul du C pour des raisons de +tests. Dans un premier temps, nous pouvons comparer l'exécution d'un code source assembleur +avec l'un ou l'autre des deux modules de calcul, et dans un deuxième temps, nous pouvons +tester si nos codes sources assembleur marchent sans être freinés par la lenteur du module +de calcul binaire. +\paragraph{} +Pour pouvoir être implémenté de manière efficace, nous passons par un tableau de pointeurs +sur fonctions, tableau a double entrées. Les "lignes" du tableau représentant les fonctions +de l'ALU (ADD,~MUL, AND,~...) repérées par un enum\{\} en C, et les colonnes seront au nombre +de deux: la première colonne contiendra les fonctions normales (binaires) et la seconde +contiendra les fonctions rapides (entières). + +\section{Unité de contrôle} +L'unité de contrôle est le c{\oe}ur du simulateur. Elle va s'occuper de lire les instructions +les unes après les autres, de les décoder, et de faire appel aux fonctions adéquates pour +exécuter l'instruction. Les appels aux unités de calculs (ALU et FPU) seront mis en place +par des tableaux de pointeurs sur fonctions, afin de permettre une modularité plus aisée. + +\section{Unité de mémoire} +Cette unité doit uniquement lire ou écrire un mot dans la mémoire. Une coupe de fonctions +Init/Deinit permet d'initialiser la mémoire au début et à la fin de la simulation, afin +de réserver la quantité de mémoire demandée. Elle doit aussi vérifier si les décalages +demandés ne dépassent pas la quantité de mémoire présente. Elle servira aussi à l'extension +pour l'interface décrit plus bas. + +\section{Unité de registres} +Cette unité doit uniquement lire ou écrire un registre. Cette unité est présente +pour bien dissocier les différents rôles des différents composants de notre microprocesseur. + +\section{Unité FPU} +Cette unité ne possède qu'une seule fonction: celle de "planter" avec l'erreur +"FPU not present". Elle est présente uniquement pour permettre une évolution future. + +\section{Interface} +\label{Interface} +\newcommand{\calcultaille}{$= 2^{32} * 4 \approx 16^9$} +Nous nous proposons d'effectuer une interface simple entre le simulateur et le monde +extérieur, via le \textit{MiniOS}\footnote{Voir section~\ref{MiniOS}, page~\pageref{MiniOS}}. +Des zones mémoires seront réservées pour l'interaction avec le MiniOS. C'est l'Unité de +mémoire qui va intercepter ces lectures/écritures et interfacer avec le MiniOS. Comme nous +n'avons aucune chance d'avoir 16Go\footnote{32 bits d'adressage sur des mots de 32 bits \calcultaille octets} +de mémoire sur notre machine virtuelle, nous allons utiliser des mots mémoire situés à de très hautes adresses.\\ +\begin{footnotesize} +\begin{center} +\begin{tabular}{|c|c|l|} +\hline +\textbf{Adresse} & \textbf{Accès} & \textbf{Signification}\\ +\hline +0xffffff00 & +Lecture & +\parbox[t]{14cm}{Ce mot passe à 1 si une touche est enfoncée. Il repasse à zéro après une lecture s'il n'y a plus de touches +disponibles dans le buffer.\\}\\ +\hline +0xffffff01 & +Lecture & +\parbox[t]{14cm}{Ce mot contient le premier caractère disponible sur le buffer clavier du MiniOS.\\}\\ +\hline +0xffffff02 & +Écriture & +\parbox[t]{14cm}{Ce mot correspond à l'adresse d'une zone de mémoire libre. +Lors de l'écriture de ce mot, le MiniOS lira une chaîne au clavier jusqu'au +caractère entrée, et placera la chaîne à l'adresse indiquée. Il y rajoutera un zéro terminal. +\\}\\ +\hline +0xffffff03 & +Ecriture & +\parbox[t]{14cm}{Lors de l'écriture de ce mot, le MiniOS affichera le caractère ASCII correspondant.\\}\\ +\hline +0xffffff04 & +Écriture & +\parbox[t]{14cm}{Ce mot correspond à l'adresse d'une chaîne ASCIIZ qui doit être affichée par le MiniOS. L'affichage +se fait dès l'écriture de ce mot.\\}\\ +\hline +0xffffff05 & +Lecture & +\parbox[t]{14cm}{Lors d'une lecture de ce mot, le MiniOS tentera de lire un nombre sur le clavier, et de +le transcrire en binaire. Le résultat lu par le simulateur sera donc ce nombre lu par le MiniOS.\\}\\ +\hline +0xffffff06 & +Écriture & +\parbox[t]{14cm}{Lors de l'écriture de ce mot, le MiniOS affichera sa valeur en décimal.\\}\\ +\hline +0xffffff07 & +Écriture & +\parbox[t]{14cm}{Lors de l'écriture de ce mot, le MiniOS affichera sa valeur en hexadécimal.\\}\\ +\hline +0xffffff08 & +Écriture & +\parbox[t]{14cm}{Lors de l'écriture de ce mot, le MiniOS affichera sa valeur en octal.\\}\\ +\hline +0xffffff09 & +Écriture & +\parbox[t]{14cm}{Lors de l'écriture de ce mot, le MiniOS affichera sa valeur en binaire.\\}\\ +\hline +0xffffff0a & +Écriture & +\parbox[t]{14cm}{Ce mot correspond à l'adresse d'une chaîne ASCIIZ. Elle indique le nom +d'un autre exécutable à charger en mémoire. Le MiniOS chargera le deuxième programme indiqué, +en le relogeant à la fin du segment non initialisé du programme appelant. Le deuxième programme +s'exécutera, puis l'exécution reviendra au programme appelant dès que le deuxième programme +aura terminé.\\}\\ +\hline +\end{tabular} +\end{center} +\end{footnotesize} +\subparagraph{} +La colonne accès est très importante. En effet, les accès ne sont autorisés que dans le mode indiqué. +Si il y a par exemple un accès en lecture sur le mot d'adresse 0xffffff07, alors l'Unité mémoire +considérera qu'il y a une erreur d'adressage. diff --git a/doc/source.tex b/doc/source.tex new file mode 100644 index 0000000..372c43b --- /dev/null +++ b/doc/source.tex @@ -0,0 +1,7 @@ +\chapter{Code Source} + +\lstset{language=C,basicstyle=\small} + + +\lstinputlisting{/home/biouman/projets/Projet-Archi/lib/simulator.c} + -- cgit v1.2.3