forked from pfaure/CrossAssembleur
Compare commits
13 commits
Author | SHA1 | Date | |
---|---|---|---|
|
a1f0a5cc5a | ||
|
475fb8dbba | ||
712e317901 | |||
96a7569291 | |||
74647c41de | |||
c6f56e2bb6 | |||
d6429be89e | |||
80d702514d | |||
985bd00388 | |||
11bddf8e22 | |||
0288b38c67 | |||
712e686699 | |||
5f88839a5b |
21 changed files with 762 additions and 4328 deletions
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Lex_Yacc/as.tab*
|
||||||
|
Lex_Yacc/as.dot
|
||||||
|
Lex_Yacc/as.output
|
||||||
|
Lex_Yacc/lex.yy.*
|
||||||
|
Tables/tables.o
|
||||||
|
rondoudou_cross_assembleur
|
||||||
|
Inputs/*
|
||||||
|
Outputs/*
|
51
Lex_Yacc/al.lex
Normal file
51
Lex_Yacc/al.lex
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
%{
|
||||||
|
#include "as.tab.h"
|
||||||
|
int yywrap(void){return 1;}
|
||||||
|
void
|
||||||
|
yyerror (char const *s)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf (stderr, "%s\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
"ADD" { return tADD; }
|
||||||
|
"SOU" { return tSUB; }
|
||||||
|
"MUL" { return tMUL; }
|
||||||
|
"DIV" { return tDIV; }
|
||||||
|
"INF" { return tINF; }
|
||||||
|
"SUP" { return tSUP; }
|
||||||
|
"EQU" { return tEQU; }
|
||||||
|
|
||||||
|
"AFC" { return tAFC; }
|
||||||
|
"COP" { return tCPY; }
|
||||||
|
"AFCA" { return tAFCA; }
|
||||||
|
|
||||||
|
|
||||||
|
"READ" { return tREAD; }
|
||||||
|
"WR" { return tWR; }
|
||||||
|
|
||||||
|
"JMP" { return tJMP; }
|
||||||
|
"JMF" { return tJMF; }
|
||||||
|
|
||||||
|
"GET" { return tGET; }
|
||||||
|
"PRI" { return tPRI; }
|
||||||
|
"PRIC" { return tPRIC; }
|
||||||
|
|
||||||
|
"CALL" { return tCALL; }
|
||||||
|
"RET" { return tRET; }
|
||||||
|
|
||||||
|
"STOP" { return tSTOP; }
|
||||||
|
|
||||||
|
[0-9]+ { yylval.nombre = atoi(yytext); return tNB; }
|
||||||
|
|
||||||
|
"\n" {}
|
||||||
|
" " {}
|
||||||
|
"\t" {}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
|
236
Lex_Yacc/as.y
Normal file
236
Lex_Yacc/as.y
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
%union {
|
||||||
|
int nombre;
|
||||||
|
}
|
||||||
|
%{
|
||||||
|
#include "../Tables/tables.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
FILE * file;
|
||||||
|
FILE * file2;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%token tMUL tDIV tADD tSUB tINF tSUP tEQU
|
||||||
|
%token tAFC tCPY tAFCA
|
||||||
|
%token tREAD tWR
|
||||||
|
%token tJMP tJMF
|
||||||
|
%token tGET tPRI tPRIC
|
||||||
|
%token tCALL tRET
|
||||||
|
%token tSTOP
|
||||||
|
%token<nombre> tNB
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
// Un programme est une suite d'au moins une instruction
|
||||||
|
Programme : Instruction Programme;
|
||||||
|
Programme : Instruction;
|
||||||
|
|
||||||
|
|
||||||
|
// Liste de toutes les instructions et conversion
|
||||||
|
|
||||||
|
// MUL, ADD, DIV.... -> 3 arguments
|
||||||
|
Instruction : tMUL tNB tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse)
|
||||||
|
// On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction); // On demande un registre en lecture pour l'argument C de l'instruction (adresse)
|
||||||
|
// On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
|
||||||
|
// On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE
|
||||||
|
add_instruction(MUL, reg_dest, reg_src1, reg_src2); // On ajoute la traduction de l'instruction MUL
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
Instruction : tADD tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(ADD, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
Instruction : tDIV tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(DIV, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
Instruction : tSUB tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(SUB, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
Instruction : tINF tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(INF, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
Instruction : tSUP tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(SUP, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
Instruction : tEQU tNB tNB tNB {increment_time();
|
||||||
|
int added_instruction = 0;
|
||||||
|
int reg_src1 = get_reg_read($3, &added_instruction);
|
||||||
|
int reg_src2 = get_reg_read($4, &added_instruction);
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction);
|
||||||
|
add_instruction(EQU, reg_dest, reg_src1, reg_src2);
|
||||||
|
new_instruction(added_instruction + 1);};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// AFC @ val -> AFC Ri val
|
||||||
|
Instruction : tAFC tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
|
||||||
|
add_instruction(AFC, reg_dest, $3, 0); // On ajoute la traduction de l'instruction AFC
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// CPY @ @ -> CPY Ri Rj
|
||||||
|
Instruction : tCPY tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_src = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse)
|
||||||
|
// On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
|
||||||
|
// On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE
|
||||||
|
add_instruction(CPY, reg_dest, reg_src, 0); // On ajoute la traduction de l'instruction CPY
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// AFCA @ val -> AFC Rlamda val; STOREA @ Rlamda
|
||||||
|
Instruction : tAFCA tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture
|
||||||
|
// On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1
|
||||||
|
add_instruction(AFC, reg_aux, $3, 0); // On affecte la valeur dans un registre lamda, elle sera tout de suite enregistré en mémoire
|
||||||
|
add_instruction(STOREA, $2, reg_aux, 0); // On store la valeur en mémoire (avec un STOREA car AFCA, nous sommes donc obligé de le faire tout de suite)
|
||||||
|
unlink($2); // On casse l'eventuel lien entre l'adresse et un registre
|
||||||
|
// Si un registre était déjà associé a cette adresse, la valeur qu'il contient est obsolète, on le libère
|
||||||
|
new_instruction(added_instruction + 2);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// JMP Ins -> JMP Ins
|
||||||
|
Instruction : tJMP tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
add_instruction(JMP, $2, 0, 0); // On traduit le JMP sans rien changer
|
||||||
|
new_instruction(1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// JMF @ Ins -> AFC Rlamda 0; SUB Rlamda Rlamda Ri; JMZ Ins
|
||||||
|
Instruction : tJMF tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'argument A de l'instruction (adresse)
|
||||||
|
int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture
|
||||||
|
// On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1
|
||||||
|
add_instruction(AFC, reg_aux, 0, 0); // On affecte 0 à un registre
|
||||||
|
add_instruction(SUB, reg_aux, reg_aux, reg_src); // On Soustrait la valeur à 0, flag 0 levé si la valeur vallait 0 donc condition fausse
|
||||||
|
add_instruction(JMZ, $3, 0, 0); // On ajoute le JMZ
|
||||||
|
new_instruction(added_instruction + 3);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// READ @1 @2 -> LOADI @1 @2
|
||||||
|
Instruction : tREAD tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_addr = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'adresse de la lecture en mémore
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour loader la valeur depuis la mémoire
|
||||||
|
add_instruction(LOADI, reg_dest, reg_addr, 0); // On traduit le READ
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// WR @1 @2 -> STOREI @1 @2
|
||||||
|
Instruction : tWR tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_addr = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'adresse de l'écriture en mémore
|
||||||
|
int reg_value = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour la valeur à écrire en mémoire
|
||||||
|
add_instruction(STOREI, reg_addr, reg_value, 0); // On traduit le WR
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// GET @ -> GET Ri
|
||||||
|
Instruction : tGET tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en ecriture pour écrire la valeur lue
|
||||||
|
add_instruction(GET, reg_dest, 0, 0); // On traduit le GET
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// PRI @ -> PRI Ri
|
||||||
|
Instruction : tPRI tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour sortir la valeur à afficher
|
||||||
|
add_instruction(PRI, reg_src, 0, 0); // On traduit le PRI
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
// PRIC @ -> PRIC Ri
|
||||||
|
Instruction : tPRIC tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
|
||||||
|
int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour sortir la valeur à afficher
|
||||||
|
add_instruction(PRIC, reg_src, 0, 0); // On traduit le PRIC
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CALL Ins Val -> CALL Ins Val
|
||||||
|
Instruction : tCALL tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances
|
||||||
|
add_instruction(CALL, $2, $3, 0); // On traduit le CALL
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
// RET -> RET
|
||||||
|
Instruction : tRET {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances
|
||||||
|
add_instruction(RET, 0, 0, 0); // On traduit le RET
|
||||||
|
new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// STOP Val -> STOP -> Val
|
||||||
|
Instruction : tSTOP tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
|
||||||
|
add_instruction(STOP, $2, 0, 0); // On traduit le STOP
|
||||||
|
new_instruction(1);}; // On déclare le nombre d'instruction ajoutées
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
file = fopen("output.asm", "w");
|
||||||
|
file2 = fopen("output.bin", "w");
|
||||||
|
init();
|
||||||
|
yyparse();
|
||||||
|
write_asm(file);
|
||||||
|
write_code_machine(file2, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
61
Makefile
61
Makefile
|
@ -1,7 +1,54 @@
|
||||||
build :
|
default :
|
||||||
gcc -Wall -c tables.c -o tables.o
|
@echo "Spécifiez une cible"
|
||||||
bison -d -t as.y
|
|
||||||
flex -o lex.yy.c al.lex
|
|
||||||
gcc -Wall -c as.tab.c -o as.tab.o
|
|
||||||
gcc -Wall -c lex.yy.c -o lex.yy.o
|
###########################
|
||||||
gcc as.tab.o lex.yy.o tables.o -ll -o rondoudou_cross_assembleur
|
### NETTOYAGE ###
|
||||||
|
###########################
|
||||||
|
clean_all : clean clean_Inputs clean_Outputs
|
||||||
|
|
||||||
|
clean: clean_Lex_Yacc clean_Tables
|
||||||
|
@rm -f cross_assembler
|
||||||
|
|
||||||
|
clean_Tables:
|
||||||
|
@rm -f Tables/*.o
|
||||||
|
|
||||||
|
clean_Lex_Yacc:
|
||||||
|
@rm -f Lex_Yacc/as.output Lex_Yacc/as.tab.* Lex_Yacc/lex.yy.* Lex_Yacc/as.dot
|
||||||
|
|
||||||
|
clean_Inputs:
|
||||||
|
@rm -f Inputs/*
|
||||||
|
|
||||||
|
clean_Outputs:
|
||||||
|
@rm -f Outputs/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### COMPILATION ###
|
||||||
|
###########################
|
||||||
|
build : clean build_Tables build_Lex_Yacc
|
||||||
|
gcc Lex_Yacc/as.tab.o Lex_Yacc/lex.yy.o Tables/tables.o -o cross_assembler
|
||||||
|
|
||||||
|
build_Tables: clean_Tables
|
||||||
|
gcc -c Tables/tables.c -o Tables/tables.o
|
||||||
|
|
||||||
|
build_Lex_Yacc: clean_Lex_Yacc
|
||||||
|
bison -g -v -d -t -b Lex_Yacc/as Lex_Yacc/as.y
|
||||||
|
flex -o Lex_Yacc/lex.yy.c Lex_Yacc/al.lex
|
||||||
|
gcc -c Lex_Yacc/as.tab.c -o Lex_Yacc/as.tab.o
|
||||||
|
gcc -c Lex_Yacc/lex.yy.c -o Lex_Yacc/lex.yy.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################
|
||||||
|
### EDITION ###
|
||||||
|
###########################
|
||||||
|
edit_Lex_Yacc:
|
||||||
|
pluma Lex_Yacc/al.lex Lex_Yacc/as.y &
|
||||||
|
|
||||||
|
edit_Tables:
|
||||||
|
pluma Tables/tables.c Tables/tables.h &
|
||||||
|
|
||||||
|
edit: edit_Lex_Yacc edit_Tables
|
||||||
|
|
0
ReadMe
0
ReadMe
51
ReadMe.md
Normal file
51
ReadMe.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Processeur sécurisé - CrossAssembleur
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Afin de pouvoir utiliser le code que nous avons compilé depuis le C avec notre compilateur sur notre processeur, il faut d'abord cross assembler le code assembleur orienté mémoire vers un langage d'assemblage orienté registres. Il faut au final refaire un autre compilateur.
|
||||||
|
|
||||||
|
# Utilisation du cross assembleur
|
||||||
|
|
||||||
|
Un Makefile a été inclus au sous module CrossAssembleur afin de simplifier son utilisation. Ainsi, afin de compiler tout le CrossAssembleur, il suffit de de rentrer la commande.
|
||||||
|
``` bash
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
Pour lancer le CrossAssemblage du code qui aura été préalablement généré avec notre compilateur, il suffit de lancer la commande
|
||||||
|
``` bash
|
||||||
|
cat FicherASM | ./rondoudou_cross_assembleur
|
||||||
|
```
|
||||||
|
Le résultat se trouvera dans les fichiers ***output.asm*** et ***output.bin***.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NB : Il est possible de rester au niveau du projet général. Un Makefile est aussi présent. Pour compiler le CrossAssembleur uniquement :
|
||||||
|
``` bash
|
||||||
|
make compile QUOI="cross_assembleur"
|
||||||
|
```
|
||||||
|
Pour compiler le projet en entier :
|
||||||
|
``` bash
|
||||||
|
make compile QUOI="all"
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour cross assembler le fichier ***file_name.memasm*** en ***file_name.regasm*** et ***file_name.bin*** :
|
||||||
|
``` bash
|
||||||
|
make exec SOURCE="file_name" QUOI="cross_assemble"
|
||||||
|
```
|
||||||
|
Pour compiler et cross assembler le fichier ***file_name.c*** et générer les fichiers ***file_name.memasm***, ***file_name.regasm***, ***file_name.bin***, et, copier le code binaire dans le fichier ***../Processeur/Processeur.srcs/sources1/new/MemoireInstructions.vhd*** :
|
||||||
|
``` bash
|
||||||
|
make exec SOURCE="file_name" QUOI="all"
|
||||||
|
```
|
||||||
|
|
||||||
|
# Implémentation
|
||||||
|
|
||||||
|
L'implémentation a été réalisée grâce à Lex/Yacc. La gestion des registres est faite avec une politique de priorité LRU.
|
||||||
|
|
||||||
|
# Points clés
|
||||||
|
|
||||||
|
|
||||||
|
- Gestion des registres : Un tableau associe à chaque adresse un registre (-1 si aucun registre n'est affecté) et enregistre si la valeur en mémoire est à jour. Il existe deux fonctions permettant de demander des registres, une en lecture une en écriture. Ces deux fonctions renvoient le numéro du registre disponible et modifie la table comme il se doit. Si le registre était déjà associé à une adresse donc la valeur a été modifiée, elle est STORE en mémoire. Si la demande a été faite en lecture, on LOAD la valeur, en écriture non puisqu'elle sera écrasée. **TOUJOURS DEMANDER EN LECTURE AVANT DE DEMANDER EN ECRITURE**.
|
||||||
|
|
||||||
|
- Gestion des sauts : L'ajout des STORE et LOAD relatifs à la gestion des registre modifie les adresse des sauts. Pour chaque instruction orienté mémoire, on compte le nombre d'instructions orienté registre. Ainsi, on garde une table qui à chaque numéro d'instruction orienté mémoire associe le numéro d'instruction orienté registre correspondant. Lors de l'écriture du code orienté registre, on remplace les adresses des sauts grâce a cette table.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,24 @@
|
||||||
|
|
||||||
/*
|
|
||||||
----------------------------------------
|
|
||||||
| Adresse | Registre | Modifié |
|
|
||||||
----------------------------------------
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| i | 0x777756b8 | int |
|
|
||||||
| size | 0x777756b8 | int |
|
|
||||||
----------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
#define NB_REG 4
|
#define NB_REG 16 // Nombre de registre dans le processeur
|
||||||
#define MEM_SIZE 16
|
#define MEM_SIZE 64 // Taille de la mémoire de données
|
||||||
#define NB_INSTRUCTIONS 128
|
#define MEM_INST_SIZE 512 // Taille de la mémoire d'instruction
|
||||||
#define MEM_INST_SIZE 128
|
#define NB_BITS_INSTRUCTION 5 // Nombres de bits codant une instruction
|
||||||
#define NB_BITS_INSTRUCTION 5
|
#define NB_BITS 16 // Taille d'un mot du processeur
|
||||||
#define NB_BITS 8
|
|
||||||
|
|
||||||
int traduction_JMP[NB_INSTRUCTIONS];
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
/***************** Initialisation *****************/
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
// Buffer to patch Jumps difference due to adding LOAD and STORE
|
||||||
|
int traduction_JMP[MEM_INST_SIZE];
|
||||||
|
// Index of the buffer
|
||||||
|
int last_instruction = 0;
|
||||||
|
|
||||||
|
// Structure coding an instruction
|
||||||
struct str_instruction {
|
struct str_instruction {
|
||||||
enum instruction_t instruction;
|
enum instruction_t instruction;
|
||||||
int param1;
|
int param1;
|
||||||
|
@ -28,15 +26,255 @@ struct str_instruction {
|
||||||
int param3;
|
int param3;
|
||||||
};
|
};
|
||||||
|
|
||||||
int last_instruction = 0;
|
// Buffer to store registers oriented instructions
|
||||||
struct str_instruction buffer[3*NB_INSTRUCTIONS];
|
struct str_instruction buffer[3*MEM_INST_SIZE];
|
||||||
|
|
||||||
|
// Structure coding an address and the correpondance with a register
|
||||||
|
struct case_adresse {
|
||||||
|
int adresse;
|
||||||
|
int registre;
|
||||||
|
char modifie;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Buffer of addresses (Memory)
|
||||||
|
struct case_adresse tableau[MEM_SIZE];
|
||||||
|
|
||||||
|
// Buffer to manage priority policy
|
||||||
|
int registres[NB_REG];
|
||||||
|
|
||||||
|
// Initialise all : the addresses-registers association table, the registers priority table, the instructions buffer, the instruction address association table
|
||||||
|
void init (void) {
|
||||||
|
int i;
|
||||||
|
struct case_adresse case_courante = {0, -1, 0};
|
||||||
|
for (i=0; i<MEM_SIZE; i++) {
|
||||||
|
case_courante.adresse = i;
|
||||||
|
tableau[i] = case_courante;
|
||||||
|
}
|
||||||
|
for (i=0; i<NB_REG; i++) {
|
||||||
|
registres[i] = 0;
|
||||||
|
}
|
||||||
|
struct str_instruction nop = {NOP, 0, 0, 0};
|
||||||
|
for (i=0; i<MEM_INST_SIZE; i++) {
|
||||||
|
buffer[i] = nop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
/************** Registers Management **************/
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Print a case address
|
||||||
|
void print_case_adresse(struct case_adresse case_courante) {
|
||||||
|
printf("{addr : %d ; reg : %d ; modi : %d}\n", case_courante.adresse, case_courante.registre, (int)case_courante.modifie);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the adresses-registers correspondance table
|
||||||
|
void print() {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<MEM_SIZE; i++) {
|
||||||
|
print_case_adresse(tableau[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// return the case corresponding to the given address
|
||||||
|
struct case_adresse get_info(int adresse) {
|
||||||
|
return tableau[adresse];
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// return the address corresponding to the given register
|
||||||
|
int get_adresse (int registre) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < MEM_SIZE && tableau[i].registre != registre) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == MEM_SIZE) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return tableau[i].adresse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Set the given register to the given address
|
||||||
|
void set_registre(int adresse, int registre) {
|
||||||
|
tableau[adresse].registre = registre;
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Set modifie to the address (0 the value in the memory is up to date, 1 the value in the register is more recent)
|
||||||
|
void set_modifie(int adresse, char modifie) {
|
||||||
|
tableau[adresse].modifie = modifie;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the register priority policy buffer
|
||||||
|
void increment_time() {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<NB_REG; i++) {
|
||||||
|
registres[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Specifie that the given register have been used
|
||||||
|
void refresh_registre(int registre) {
|
||||||
|
registres[registre] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Return the LRU register
|
||||||
|
int get_register() {
|
||||||
|
int i;
|
||||||
|
int index_max = 0;
|
||||||
|
for (i=0; i<NB_REG; i++) {
|
||||||
|
if (registres[index_max] < registres[i]) {
|
||||||
|
index_max = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ask for a register to read the value
|
||||||
|
|
||||||
|
@param :
|
||||||
|
- adresse : The address of value wanted
|
||||||
|
- added_instruction : Address of an int storing the number of added_instructions
|
||||||
|
@return : The number of the register corresponding to the given address
|
||||||
|
*/
|
||||||
|
int get_reg_read(int adresse, int * added_instruction) {
|
||||||
|
struct case_adresse ma_case = get_info(adresse);
|
||||||
|
if (ma_case.registre == -1) {
|
||||||
|
int dispo = get_register();
|
||||||
|
int previous_addr = get_adresse(dispo);
|
||||||
|
if (previous_addr != -1) {
|
||||||
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
||||||
|
if (ancienne_case.modifie == 1) {
|
||||||
|
*added_instruction = (*added_instruction) + 1;
|
||||||
|
add_instruction(STORE, previous_addr, dispo, 0);
|
||||||
|
set_modifie(previous_addr, 0);
|
||||||
|
}
|
||||||
|
set_registre(previous_addr, -1);
|
||||||
|
}
|
||||||
|
*added_instruction = (*added_instruction) + 1;
|
||||||
|
add_instruction(LOAD, dispo, adresse, 0);
|
||||||
|
set_registre(adresse, dispo);
|
||||||
|
refresh_registre(dispo);
|
||||||
|
return dispo;
|
||||||
|
} else {
|
||||||
|
refresh_registre(ma_case.registre);
|
||||||
|
return ma_case.registre;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ask for a register to write the value
|
||||||
|
|
||||||
|
@param :
|
||||||
|
- adresse : The address of value (if -1 return a free register without associating it to any address)
|
||||||
|
- added_instruction : Address of an int storing the number of added_instructions
|
||||||
|
@return : The number of the register corresponding to the given address
|
||||||
|
|
||||||
|
WARNING : The value of the address will not be LOADED in the register
|
||||||
|
Always ask READ registers before the WRITE register
|
||||||
|
*/
|
||||||
|
int get_reg_write(int adresse, int * added_instruction) {
|
||||||
|
if (adresse == -1) {
|
||||||
|
int dispo = get_register();
|
||||||
|
int previous_addr = get_adresse(dispo);
|
||||||
|
if (previous_addr != -1) {
|
||||||
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
||||||
|
if (ancienne_case.modifie == 1) {
|
||||||
|
add_instruction(STORE, previous_addr, dispo, 0);
|
||||||
|
*added_instruction = (*added_instruction) + 1;
|
||||||
|
set_modifie(previous_addr, 0);
|
||||||
|
}
|
||||||
|
set_registre(previous_addr, -1);
|
||||||
|
}
|
||||||
|
return dispo;
|
||||||
|
} else {
|
||||||
|
set_modifie(adresse, 1);
|
||||||
|
struct case_adresse ma_case = get_info(adresse);
|
||||||
|
if (ma_case.registre == -1) {
|
||||||
|
int dispo = get_register();
|
||||||
|
int previous_addr = get_adresse(dispo);
|
||||||
|
if (previous_addr != -1) {
|
||||||
|
struct case_adresse ancienne_case = get_info(previous_addr);
|
||||||
|
if (ancienne_case.modifie == 1) {
|
||||||
|
*added_instruction = (*added_instruction) + 1;
|
||||||
|
add_instruction(STORE, previous_addr, dispo, 0);
|
||||||
|
set_modifie(previous_addr, 0);
|
||||||
|
}
|
||||||
|
set_registre(previous_addr, -1);
|
||||||
|
}
|
||||||
|
set_registre(adresse, dispo);
|
||||||
|
refresh_registre(dispo);
|
||||||
|
return dispo;
|
||||||
|
} else {
|
||||||
|
refresh_registre(ma_case.registre);
|
||||||
|
return ma_case.registre;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broke the association between adresse and its corresponding register
|
||||||
|
void unlink(int adresse) {
|
||||||
|
set_registre(adresse, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store used register, init the association table between addresses and registers
|
||||||
|
int flush_and_init() {
|
||||||
|
int i;
|
||||||
|
int added_instruction = 0;
|
||||||
|
for (i = 0; i<MEM_SIZE; i++) {
|
||||||
|
if (tableau[i].registre != -1) {
|
||||||
|
if (tableau[i].modifie == 0) {
|
||||||
|
tableau[i].registre = -1;
|
||||||
|
} else {
|
||||||
|
add_instruction(STORE, i, tableau[i].registre, 0);
|
||||||
|
added_instruction++;
|
||||||
|
tableau[i].registre = -1;
|
||||||
|
tableau[i].modifie = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i=0; i<NB_REG; i++) {
|
||||||
|
registres[i] = 0;
|
||||||
|
}
|
||||||
|
return added_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
/************** Instructions Writing **************/
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
// Add a new Registers oriented instruction
|
||||||
void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
|
void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
|
||||||
struct str_instruction my_instruction = {inst, param1, param2, param3};
|
struct str_instruction my_instruction = {inst, param1, param2, param3};
|
||||||
buffer[last_instruction] = my_instruction;
|
buffer[last_instruction] = my_instruction;
|
||||||
last_instruction++;
|
last_instruction++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specifie the number of Register oriented instructions corresponding to the memory oriented instruction
|
||||||
|
void new_instruction(int nb_inst) {
|
||||||
|
static int last_intruction_adresse = 0;
|
||||||
|
static int current_instruction = 0;
|
||||||
|
traduction_JMP[current_instruction] = last_intruction_adresse;
|
||||||
|
current_instruction++;
|
||||||
|
last_intruction_adresse += nb_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the new assembly in the given file
|
||||||
void write_asm(FILE * file) {
|
void write_asm(FILE * file) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i<MEM_INST_SIZE) {
|
while (i<MEM_INST_SIZE) {
|
||||||
|
@ -79,6 +317,8 @@ void write_asm(FILE * file) {
|
||||||
fprintf(file, "GET %d\n", buffer[i].param1);
|
fprintf(file, "GET %d\n", buffer[i].param1);
|
||||||
} else if (buffer[i].instruction == PRI) {
|
} else if (buffer[i].instruction == PRI) {
|
||||||
fprintf(file, "PRI %d\n", buffer[i].param1);
|
fprintf(file, "PRI %d\n", buffer[i].param1);
|
||||||
|
} else if (buffer[i].instruction == PRIC) {
|
||||||
|
fprintf(file, "PRIC %d\n", buffer[i].param1);
|
||||||
|
|
||||||
} else if (buffer[i].instruction == CALL) {
|
} else if (buffer[i].instruction == CALL) {
|
||||||
fprintf(file, "CALL %d %d\n", traduction_JMP[buffer[i].param1], buffer[i].param2);
|
fprintf(file, "CALL %d %d\n", traduction_JMP[buffer[i].param1], buffer[i].param2);
|
||||||
|
@ -91,6 +331,8 @@ void write_asm(FILE * file) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Write binary value of n in buff
|
||||||
void int_2_bin(char * buff, int n) {
|
void int_2_bin(char * buff, int n) {
|
||||||
int _m = n;
|
int _m = n;
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
|
@ -99,6 +341,8 @@ void int_2_bin(char * buff, int n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Write binary value of value in buff on N bits
|
||||||
void convert_to_binary_on_N(int value, int N, char * buff) {
|
void convert_to_binary_on_N(int value, int N, char * buff) {
|
||||||
char tampon[33];
|
char tampon[33];
|
||||||
int_2_bin(tampon, value);
|
int_2_bin(tampon, value);
|
||||||
|
@ -109,6 +353,9 @@ void convert_to_binary_on_N(int value, int N, char * buff) {
|
||||||
buff[N] = '\0';
|
buff[N] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// INTERN FUNCTION
|
||||||
|
// Write a binary instruction in the given file
|
||||||
|
// If not compact ("010..10" & ) else only (010..10)
|
||||||
void write_instruction_binary(FILE * file, struct str_instruction instr, char compact) {
|
void write_instruction_binary(FILE * file, struct str_instruction instr, char compact) {
|
||||||
char buff1[33];
|
char buff1[33];
|
||||||
char buff2[33];
|
char buff2[33];
|
||||||
|
@ -129,220 +376,21 @@ void write_instruction_binary(FILE * file, struct str_instruction instr, char co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the binary code in the given file
|
||||||
void write_code_machine(FILE * file) {
|
void write_code_machine(FILE * file, char compact) {
|
||||||
int i = MEM_INST_SIZE - 1;
|
if (compact) {
|
||||||
while (i>=0) {
|
int i = MEM_INST_SIZE - 1;
|
||||||
write_instruction_binary(file, buffer[i], 0);
|
while (i>=0) {
|
||||||
i--;
|
write_instruction_binary(file, buffer[i], 0);
|
||||||
}
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_code_machine_compact(FILE * file) {
|
|
||||||
printf(file, "\"");
|
|
||||||
int i = MEM_INST_SIZE - 1;
|
|
||||||
while (i>=0) {
|
|
||||||
write_instruction_binary(file, buffer[i], 1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
printf(file, "\"\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct case_adresse {
|
|
||||||
int adresse;
|
|
||||||
int registre;
|
|
||||||
char modifie;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct case_adresse tableau[MEM_SIZE];
|
|
||||||
int registres[NB_REG];
|
|
||||||
|
|
||||||
void init (void) {
|
|
||||||
int i;
|
|
||||||
struct case_adresse case_courante = {0, -1, 0};
|
|
||||||
for (i=0; i<MEM_SIZE; i++) {
|
|
||||||
case_courante.adresse = i;
|
|
||||||
tableau[i] = case_courante;
|
|
||||||
}
|
|
||||||
for (i=0; i<NB_REG; i++) {
|
|
||||||
registres[i] = 0;
|
|
||||||
}
|
|
||||||
struct str_instruction nop = {NOP, 0, 0, 0};
|
|
||||||
for (i=0; i<MEM_INST_SIZE; i++) {
|
|
||||||
buffer[i] = nop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_case_adresse(struct case_adresse case_courante) {
|
|
||||||
printf("{addr : %d ; reg : %d ; modi : %d}\n", case_courante.adresse, case_courante.registre, (int)case_courante.modifie);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print() {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<MEM_SIZE; i++) {
|
|
||||||
print_case_adresse(tableau[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct case_adresse get_info(int adresse) {
|
|
||||||
return tableau[adresse];
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_adresse (int registre) {
|
|
||||||
int i = 0;
|
|
||||||
while (i < MEM_SIZE && tableau[i].registre != registre) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (i == MEM_SIZE) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
return tableau[i].adresse;
|
fprintf(file, "\"");
|
||||||
}
|
int i = MEM_INST_SIZE - 1;
|
||||||
}
|
while (i>=0) {
|
||||||
|
write_instruction_binary(file, buffer[i], 1);
|
||||||
void set_registre(int adresse, int registre) {
|
i--;
|
||||||
tableau[adresse].registre = registre;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_modifie(int adresse, char modifie) {
|
|
||||||
tableau[adresse].modifie = modifie;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment_time() {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<NB_REG; i++) {
|
|
||||||
registres[i]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void refresh_registre(int registre) {
|
|
||||||
registres[registre] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_register() {
|
|
||||||
int i;
|
|
||||||
int index_max = 0;
|
|
||||||
for (i=0; i<NB_REG; i++) {
|
|
||||||
if (registres[index_max] < registres[i]) {
|
|
||||||
index_max = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_reg_write(int adresse, int * added_instruction) {
|
|
||||||
if (adresse == -1) {
|
|
||||||
int dispo = get_register();
|
|
||||||
int previous_addr = get_adresse(dispo);
|
|
||||||
if (previous_addr != -1) {
|
|
||||||
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
||||||
if (ancienne_case.modifie == 1) {
|
|
||||||
add_instruction(STORE, previous_addr, dispo, 0);
|
|
||||||
*added_instruction = (*added_instruction) + 1;
|
|
||||||
set_modifie(previous_addr, 0);
|
|
||||||
}
|
|
||||||
set_registre(previous_addr, -1);
|
|
||||||
}
|
|
||||||
return dispo;
|
|
||||||
} else {
|
|
||||||
set_modifie(adresse, 1);
|
|
||||||
struct case_adresse ma_case = get_info(adresse);
|
|
||||||
if (ma_case.registre == -1) {
|
|
||||||
int dispo = get_register();
|
|
||||||
int previous_addr = get_adresse(dispo);
|
|
||||||
if (previous_addr != -1) {
|
|
||||||
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
||||||
if (ancienne_case.modifie == 1) {
|
|
||||||
*added_instruction = (*added_instruction) + 1;
|
|
||||||
add_instruction(STORE, previous_addr, dispo, 0);
|
|
||||||
set_modifie(previous_addr, 0);
|
|
||||||
}
|
|
||||||
set_registre(previous_addr, -1);
|
|
||||||
}
|
|
||||||
set_registre(adresse, dispo);
|
|
||||||
refresh_registre(dispo);
|
|
||||||
return dispo;
|
|
||||||
} else {
|
|
||||||
refresh_registre(ma_case.registre);
|
|
||||||
return ma_case.registre;
|
|
||||||
}
|
}
|
||||||
|
fprintf(file, "\"\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_reg_read(int adresse, int * added_instruction) {
|
|
||||||
struct case_adresse ma_case = get_info(adresse);
|
|
||||||
if (ma_case.registre == -1) {
|
|
||||||
int dispo = get_register();
|
|
||||||
int previous_addr = get_adresse(dispo);
|
|
||||||
if (previous_addr != -1) {
|
|
||||||
struct case_adresse ancienne_case = get_info(previous_addr);
|
|
||||||
if (ancienne_case.modifie == 1) {
|
|
||||||
*added_instruction = (*added_instruction) + 1;
|
|
||||||
add_instruction(STORE, previous_addr, dispo, 0);
|
|
||||||
set_modifie(previous_addr, 0);
|
|
||||||
}
|
|
||||||
set_registre(previous_addr, -1);
|
|
||||||
}
|
|
||||||
*added_instruction = (*added_instruction) + 1;
|
|
||||||
add_instruction(LOAD, dispo, adresse, 0);
|
|
||||||
set_registre(adresse, dispo);
|
|
||||||
refresh_registre(dispo);
|
|
||||||
return dispo;
|
|
||||||
} else {
|
|
||||||
refresh_registre(ma_case.registre);
|
|
||||||
return ma_case.registre;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlink(int adresse) {
|
|
||||||
set_registre(adresse, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int flush_and_init() {
|
|
||||||
int i;
|
|
||||||
int added_instruction = 0;
|
|
||||||
for (i = 0; i<MEM_SIZE; i++) {
|
|
||||||
if (tableau[i].registre != -1) {
|
|
||||||
if (tableau[i].modifie == 0) {
|
|
||||||
tableau[i].registre = -1;
|
|
||||||
} else {
|
|
||||||
add_instruction(STORE, i, tableau[i].registre, 0);
|
|
||||||
added_instruction++;
|
|
||||||
tableau[i].registre = -1;
|
|
||||||
tableau[i].modifie = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i=0; i<NB_REG; i++) {
|
|
||||||
registres[i] = 0;
|
|
||||||
}
|
|
||||||
return added_instruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void new_instruction(int nb_inst) {
|
|
||||||
static int last_intruction_adresse = 0;
|
|
||||||
static int current_instruction = 0;
|
|
||||||
traduction_JMP[current_instruction] = last_intruction_adresse;
|
|
||||||
current_instruction++;
|
|
||||||
last_intruction_adresse += nb_inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
79
Tables/tables.h
Normal file
79
Tables/tables.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef TABLE_H
|
||||||
|
#define TABLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Initialise all : the addresses-registers association table, the registers priority table, the instructions buffer, the instruction address association table
|
||||||
|
void init(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
/************** Registers Management **************/
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
// Print the addresses-registers association table
|
||||||
|
void print();
|
||||||
|
|
||||||
|
// Increment the input instruction counter
|
||||||
|
void increment_time();
|
||||||
|
|
||||||
|
/* Ask for a register to read the value
|
||||||
|
|
||||||
|
@param :
|
||||||
|
- adresse : The address of value wanted
|
||||||
|
- added_instruction : Address of an int storing the number of added_instructions
|
||||||
|
@return : The number of the register corresponding to the given address
|
||||||
|
*/
|
||||||
|
int get_reg_read(int adresse, int * added_instruction);
|
||||||
|
|
||||||
|
/* Ask for a register to write the value
|
||||||
|
|
||||||
|
@param :
|
||||||
|
- adresse : The address of value (if -1 return a free register without associating it to any address)
|
||||||
|
- added_instruction : Address of an int storing the number of added_instructions
|
||||||
|
@return : The number of the register corresponding to the given address
|
||||||
|
|
||||||
|
WARNING : The value of the address will not be LOADED in the register
|
||||||
|
Always ask READ registers before the WRITE register
|
||||||
|
*/
|
||||||
|
int get_reg_write(int adresse, int * added_instruction);
|
||||||
|
|
||||||
|
// Broke the association between adresse and its corresponding register
|
||||||
|
void unlink(int adresse);
|
||||||
|
|
||||||
|
// Store used register, init the association table between addresses and registers
|
||||||
|
int flush_and_init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
/************** Instructions Writing **************/
|
||||||
|
/**************************************************/
|
||||||
|
/**************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Enum of the register oriented instruction (warning order correspond to the binary code)
|
||||||
|
enum instruction_t {NOP, ADD, MUL, SUB, DIV, INF, SUP, EQU, CPY, AFC, LOAD, STORE, LOADI, STOREI, STOREA, JMP, JMZ, PRI, PRIC, GET, CALL, RET, STOP};
|
||||||
|
|
||||||
|
// Add a new Registers oriented instruction
|
||||||
|
void add_instruction(enum instruction_t inst, int param1, int param2, int param3);
|
||||||
|
|
||||||
|
// Specifie the number of Register oriented instructions corresponding to the memory oriented instruction
|
||||||
|
void new_instruction(int nb_inst);
|
||||||
|
|
||||||
|
// Write the new assembly in the given file
|
||||||
|
void write_asm(FILE * file);
|
||||||
|
|
||||||
|
// Write the binary code in the given file
|
||||||
|
void write_code_machine(FILE * file, char compact);
|
||||||
|
|
||||||
|
#endif
|
50
al.lex
50
al.lex
|
@ -1,50 +0,0 @@
|
||||||
%{
|
|
||||||
#include "as.tab.h"
|
|
||||||
int yywrap(void){return 1;}
|
|
||||||
void
|
|
||||||
yyerror (char const *s)
|
|
||||||
{
|
|
||||||
|
|
||||||
fprintf (stderr, "%s\n", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
"ADD" { return tADD ;}
|
|
||||||
"SOU" { return tSUB;}
|
|
||||||
"MUL" { return tMUL; }
|
|
||||||
"DIV" { return tDIV; }
|
|
||||||
"INF" { return tINF; }
|
|
||||||
"SUP" { return tSUP; }
|
|
||||||
"EQU" { return tEQU; }
|
|
||||||
|
|
||||||
"AFC" { return tAFC; }
|
|
||||||
"COP" { return tCPY; }
|
|
||||||
"AFCA" { return tAFCA; }
|
|
||||||
|
|
||||||
|
|
||||||
"READ" { return tREAD; }
|
|
||||||
"WR" { return tWR; }
|
|
||||||
|
|
||||||
"JMP" { return tJMP; }
|
|
||||||
"JMF" { return tJMF; }
|
|
||||||
|
|
||||||
"GET" { return tGET; }
|
|
||||||
"PRI" { return tPRI; }
|
|
||||||
|
|
||||||
"CALL" { return tCALL; }
|
|
||||||
"RET" { return tRET; }
|
|
||||||
|
|
||||||
"STOP" { return tSTOP; }
|
|
||||||
|
|
||||||
[0-9]+ { yylval.nombre = atoi(yytext); return tNB; }
|
|
||||||
|
|
||||||
"\n" {}
|
|
||||||
" " {}
|
|
||||||
"\t" {}
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
|
|
93
as.tab.h
93
as.tab.h
|
@ -1,93 +0,0 @@
|
||||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* As a special exception, you may create a larger work that contains
|
|
||||||
part or all of the Bison parser skeleton and distribute that work
|
|
||||||
under terms of your choice, so long as that work isn't itself a
|
|
||||||
parser generator using the skeleton or a modified version thereof
|
|
||||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
|
||||||
the parser skeleton itself, you may (at your option) remove this
|
|
||||||
special exception, which will cause the skeleton and the resulting
|
|
||||||
Bison output files to be licensed under the GNU General Public
|
|
||||||
License without this special exception.
|
|
||||||
|
|
||||||
This special exception was added by the Free Software Foundation in
|
|
||||||
version 2.2 of Bison. */
|
|
||||||
|
|
||||||
#ifndef YY_YY_AS_TAB_H_INCLUDED
|
|
||||||
# define YY_YY_AS_TAB_H_INCLUDED
|
|
||||||
/* Debug traces. */
|
|
||||||
#ifndef YYDEBUG
|
|
||||||
# define YYDEBUG 1
|
|
||||||
#endif
|
|
||||||
#if YYDEBUG
|
|
||||||
extern int yydebug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Token type. */
|
|
||||||
#ifndef YYTOKENTYPE
|
|
||||||
# define YYTOKENTYPE
|
|
||||||
enum yytokentype
|
|
||||||
{
|
|
||||||
tMUL = 258,
|
|
||||||
tDIV = 259,
|
|
||||||
tADD = 260,
|
|
||||||
tSUB = 261,
|
|
||||||
tINF = 262,
|
|
||||||
tSUP = 263,
|
|
||||||
tEQU = 264,
|
|
||||||
tAFC = 265,
|
|
||||||
tCPY = 266,
|
|
||||||
tAFCA = 267,
|
|
||||||
tREAD = 268,
|
|
||||||
tWR = 269,
|
|
||||||
tJMP = 270,
|
|
||||||
tJMF = 271,
|
|
||||||
tGET = 272,
|
|
||||||
tPRI = 273,
|
|
||||||
tCALL = 274,
|
|
||||||
tRET = 275,
|
|
||||||
tSTOP = 276,
|
|
||||||
tNB = 277
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Value type. */
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
|
||||||
|
|
||||||
union YYSTYPE
|
|
||||||
{
|
|
||||||
#line 1 "as.y" /* yacc.c:1909 */
|
|
||||||
|
|
||||||
int nombre;
|
|
||||||
|
|
||||||
#line 81 "as.tab.h" /* yacc.c:1909 */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
|
||||||
|
|
||||||
int yyparse (void);
|
|
||||||
|
|
||||||
#endif /* !YY_YY_AS_TAB_H_INCLUDED */
|
|
BIN
as.tab.o
BIN
as.tab.o
Binary file not shown.
158
as.y
158
as.y
|
@ -1,158 +0,0 @@
|
||||||
%union {
|
|
||||||
int nombre;
|
|
||||||
}
|
|
||||||
%{
|
|
||||||
#include "tables.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
FILE * file;
|
|
||||||
FILE * file2;
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%token tMUL tDIV tADD tSUB tINF tSUP tEQU
|
|
||||||
%token tAFC tCPY tAFCA
|
|
||||||
%token tREAD tWR
|
|
||||||
%token tJMP tJMF
|
|
||||||
%token tGET tPRI
|
|
||||||
%token tCALL tRET
|
|
||||||
%token tSTOP
|
|
||||||
%token<nombre> tNB
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
Programme : Instruction Programme;
|
|
||||||
Programme : Instruction;
|
|
||||||
|
|
||||||
Instruction : tMUL tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(MUL, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tADD tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(ADD, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tDIV tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(DIV, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tSUB tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(SUB, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tINF tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(INF, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tSUP tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(SUP, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tEQU tNB tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src1 = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_src2 = get_reg_read($4, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(EQU, reg_dest, reg_src1, reg_src2);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
|
|
||||||
|
|
||||||
Instruction : tAFC tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(AFC, reg_dest, $3, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tCPY tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(CPY, reg_dest, reg_src, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tAFCA tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_aux = get_reg_write(-1, &added_instruction);
|
|
||||||
add_instruction(AFC, reg_aux, $3, 0);
|
|
||||||
add_instruction(STOREA, $2, reg_aux, 0);
|
|
||||||
unlink($2);
|
|
||||||
new_instruction(added_instruction + 2);};
|
|
||||||
|
|
||||||
|
|
||||||
Instruction : tJMP tNB {increment_time();
|
|
||||||
add_instruction(JMP, $2, 0, 0);
|
|
||||||
new_instruction(1);};
|
|
||||||
Instruction : tJMF tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src = get_reg_read($2, &added_instruction);
|
|
||||||
int reg_aux = get_reg_write(-1, &added_instruction);
|
|
||||||
add_instruction(SUB, reg_aux, reg_aux, reg_src);
|
|
||||||
add_instruction(JMZ, $3, 0, 0);
|
|
||||||
new_instruction(added_instruction + 2);};
|
|
||||||
|
|
||||||
Instruction : tREAD tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_addr = get_reg_read($3, &added_instruction);
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(LOADI, reg_dest, reg_addr, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tWR tNB tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_addr = get_reg_read($2, &added_instruction);
|
|
||||||
int reg_value = get_reg_read($3, &added_instruction);
|
|
||||||
add_instruction(STOREI, reg_addr, reg_value, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
|
|
||||||
|
|
||||||
Instruction : tGET tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_dest = get_reg_write($2, &added_instruction);
|
|
||||||
add_instruction(GET, reg_dest, 0, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tPRI tNB {increment_time();
|
|
||||||
int added_instruction = 0;
|
|
||||||
int reg_src = get_reg_read($2, &added_instruction);
|
|
||||||
add_instruction(PRI, reg_src, 0, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
|
|
||||||
|
|
||||||
Instruction : tCALL tNB tNB {increment_time();
|
|
||||||
int added_instruction = flush_and_init(file);
|
|
||||||
add_instruction(CALL, $2, $3, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
Instruction : tRET {increment_time();
|
|
||||||
int added_instruction = flush_and_init(file);
|
|
||||||
add_instruction(RET, 0, 0, 0);
|
|
||||||
new_instruction(added_instruction + 1);};
|
|
||||||
|
|
||||||
Instruction : tSTOP tNB {increment_time();
|
|
||||||
add_instruction(STOP, $2, 0, 0);
|
|
||||||
new_instruction(1);};
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
file = fopen("output.asm", "w");
|
|
||||||
file2 = fopen("output.bin", "w");
|
|
||||||
init();
|
|
||||||
yyparse();
|
|
||||||
write_asm(file);
|
|
||||||
write_code_machine_compact(file2);
|
|
||||||
return 0;
|
|
||||||
}
|
|
BIN
lex.yy.o
BIN
lex.yy.o
Binary file not shown.
84
output.asm
84
output.asm
|
@ -1,84 +0,0 @@
|
||||||
JMP 48
|
|
||||||
AFC 0 1
|
|
||||||
LOAD 1 0
|
|
||||||
CPY 2 1
|
|
||||||
AFC 3 1
|
|
||||||
MUL 0 3 0
|
|
||||||
ADD 0 2 0
|
|
||||||
LOADI 0 0
|
|
||||||
PRI 0
|
|
||||||
AFC 0 0
|
|
||||||
CPY 2 1
|
|
||||||
AFC 3 1
|
|
||||||
MUL 0 3 0
|
|
||||||
ADD 0 2 0
|
|
||||||
AFC 2 14
|
|
||||||
STOREI 0 2
|
|
||||||
AFC 0 2
|
|
||||||
CPY 1 0
|
|
||||||
STORE 0 1
|
|
||||||
STORE 1 0
|
|
||||||
STORE 2 2
|
|
||||||
STORE 3 3
|
|
||||||
RET
|
|
||||||
AFC 0 0
|
|
||||||
LOAD 1 0
|
|
||||||
CPY 2 1
|
|
||||||
AFC 3 1
|
|
||||||
MUL 0 3 0
|
|
||||||
ADD 0 2 0
|
|
||||||
LOADI 0 0
|
|
||||||
PRI 0
|
|
||||||
AFC 0 1
|
|
||||||
CPY 2 1
|
|
||||||
AFC 3 1
|
|
||||||
MUL 0 3 0
|
|
||||||
ADD 0 2 0
|
|
||||||
AFC 2 10
|
|
||||||
STOREI 0 2
|
|
||||||
CPY 0 1
|
|
||||||
STORE 1 0
|
|
||||||
STORE 2 2
|
|
||||||
STORE 3 3
|
|
||||||
CALL 1 1
|
|
||||||
AFC 0 1
|
|
||||||
CPY 1 0
|
|
||||||
STORE 0 1
|
|
||||||
STORE 1 0
|
|
||||||
RET
|
|
||||||
AFC 0 0
|
|
||||||
AFC 1 0
|
|
||||||
STOREA 3 1
|
|
||||||
AFC 1 1
|
|
||||||
MUL 0 1 0
|
|
||||||
LOAD 2 3
|
|
||||||
ADD 0 2 0
|
|
||||||
AFC 3 1
|
|
||||||
STOREI 0 3
|
|
||||||
AFC 2 1
|
|
||||||
STORE 5 1
|
|
||||||
AFC 1 0
|
|
||||||
STOREA 4 1
|
|
||||||
AFC 1 1
|
|
||||||
MUL 2 1 2
|
|
||||||
STORE 2 0
|
|
||||||
LOAD 0 4
|
|
||||||
ADD 2 0 2
|
|
||||||
AFC 3 12
|
|
||||||
STOREI 2 3
|
|
||||||
STORE 6 1
|
|
||||||
AFC 1 0
|
|
||||||
STOREA 4 1
|
|
||||||
STORE 3 2
|
|
||||||
STORE 5 3
|
|
||||||
CALL 23 4
|
|
||||||
AFC 0 0
|
|
||||||
AFC 1 0
|
|
||||||
STOREA 5 1
|
|
||||||
AFC 1 1
|
|
||||||
MUL 0 1 0
|
|
||||||
LOAD 2 5
|
|
||||||
ADD 0 2 0
|
|
||||||
LOADI 0 0
|
|
||||||
PRI 0
|
|
||||||
STOP 0
|
|
|
@ -1 +0,0 @@
|
||||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101010000000000000000000000001000100000000000000000000000001100000000000000000000000000000010000000000000010000000000101000000010000001010000000000010000000000000000100000000010010000000100000001000000000111000000101000000010000000001001000000010000000000000000010010000000000000000000000001001100010111000001000000000001011000001010000001100000000010110000001100000010000000000111000000100000000010000000001001000000010000000000000000010110000011000000001000000000110100000010000000110000000001001000000110000110000000000000010000001000000000000000100101000000000000001000000000001011000000100000000000000000000100000001000000001000000100100100000001000000010000000001110000001000000000100000000010010000000100000000000000000101100000101000000010000000001001000000100000000100000000011010000000000000011000000000100100000011000000010000000000001000000000000001000000000010100000001000000011000000000001000000000000000010000000001001000000010000000100000000011100000001100000001000000000100100000001000000000000000001001000000000000000000000000101000000000000000000000000000101100000001000000000000000001011000000000000000100000000010000000000100000000000000000100100000000000000010000000010011000000010000000100000000010110000001100000011000000000101100000010000000100000000001011000000010000000000000000010000000000000000001000000000110100000000000000100000000001001000000100000101000000000000010000000000000010000000000001000000000000000110000000001001000000110000000100000000010000000001000000001000000000100100000000000000010000000010001000000000000000000000000011000000000000000000000000000000100000000000000100000000000010000000000000001100000000010010000001100000001000000000100000000010000000010000000001010000000010000000000000000010010000000000000000000000001010000000000000000000000000001011000000110000001100000000010110000001000000010000000000101100000001000000000000000001011000000000000000100000000010000000000100000000000000000100100000000000000100000000001101000000000000001000000000010010000001000001110000000000000100000000000000100000000000010000000000000001100000000010010000001100000001000000000100000000010000000010000000001001000000000000000000000000100010000000000000000000000000110000000000000000000000000000001000000000000001000000000000100000000000000011000000000100100000011000000010000000001000000000100000000100000000010100000000100000000000000000100100000000000000010000000001111001100000000000000000000
|
|
Binary file not shown.
35
tables.h
35
tables.h
|
@ -1,35 +0,0 @@
|
||||||
#ifndef TABLE_H
|
|
||||||
#define TABLE_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
----------------------------------------
|
|
||||||
| Adresse | Registre | Modifié |
|
|
||||||
----------------------------------------
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| i | 0x777756b8 | int |
|
|
||||||
| size | 0x777756b8 | int |
|
|
||||||
----------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
enum instruction_t {NOP, ADD, MUL, SUB, DIV, INF, SUP, EQU, CPY, AFC, LOAD, STORE, LOADI, STOREI, STOREA, JMP, JMZ, PRI, GET, CALL, RET, STOP};
|
|
||||||
|
|
||||||
void init(void);
|
|
||||||
void print();
|
|
||||||
void increment_time();
|
|
||||||
int get_reg_read(int adresse, int * added_instruction);
|
|
||||||
int get_reg_write(int adresse, int * added_instruction);
|
|
||||||
void unlink(int adresse);
|
|
||||||
int flush_and_init();
|
|
||||||
void new_instruction(int nb_inst);
|
|
||||||
void write_asm(FILE * file);
|
|
||||||
void write_code_machine(FILE * file);
|
|
||||||
void add_instruction(enum instruction_t inst, int param1, int param2, int param3);
|
|
||||||
|
|
||||||
#endif
|
|
BIN
tables.o
BIN
tables.o
Binary file not shown.
62
toto.asm
62
toto.asm
|
@ -1,62 +0,0 @@
|
||||||
JMP 37
|
|
||||||
AFC 1 1
|
|
||||||
COP 2 0
|
|
||||||
AFC 3 1
|
|
||||||
MUL 1 3 1
|
|
||||||
ADD 1 2 1
|
|
||||||
READ 1 1
|
|
||||||
PRI 1
|
|
||||||
AFC 1 0
|
|
||||||
COP 2 0
|
|
||||||
AFC 3 1
|
|
||||||
MUL 1 3 1
|
|
||||||
ADD 1 2 1
|
|
||||||
AFC 2 14
|
|
||||||
WR 1 2
|
|
||||||
AFC 1 2
|
|
||||||
COP 0 1
|
|
||||||
RET
|
|
||||||
AFC 1 0
|
|
||||||
COP 2 0
|
|
||||||
AFC 3 1
|
|
||||||
MUL 1 3 1
|
|
||||||
ADD 1 2 1
|
|
||||||
READ 1 1
|
|
||||||
PRI 1
|
|
||||||
AFC 1 1
|
|
||||||
COP 2 0
|
|
||||||
AFC 3 1
|
|
||||||
MUL 1 3 1
|
|
||||||
ADD 1 2 1
|
|
||||||
AFC 2 10
|
|
||||||
WR 1 2
|
|
||||||
COP 1 0
|
|
||||||
CALL 1 1
|
|
||||||
AFC 1 1
|
|
||||||
COP 0 1
|
|
||||||
RET
|
|
||||||
AFC 2 0
|
|
||||||
AFCA 3 0
|
|
||||||
AFC 5 1
|
|
||||||
MUL 2 5 2
|
|
||||||
ADD 2 3 2
|
|
||||||
AFC 4 1
|
|
||||||
WR 2 4
|
|
||||||
AFC 3 1
|
|
||||||
AFCA 4 0
|
|
||||||
AFC 6 1
|
|
||||||
MUL 3 6 3
|
|
||||||
ADD 3 4 3
|
|
||||||
AFC 5 12
|
|
||||||
WR 3 5
|
|
||||||
AFCA 4 0
|
|
||||||
CALL 18 4
|
|
||||||
AFC 4 0
|
|
||||||
AFCA 5 0
|
|
||||||
AFC 6 1
|
|
||||||
MUL 4 6 4
|
|
||||||
ADD 4 5 4
|
|
||||||
READ 4 4
|
|
||||||
PRI 4
|
|
||||||
STOP 0
|
|
||||||
|
|
Loading…
Reference in a new issue