Browse Source

Version fonctionnelle processeur sécurisé

Paul Faure 2 years ago
commit
bff261fa01
7 changed files with 501 additions and 0 deletions
  1. 6
    0
      .gitignore
  2. 51
    0
      Lex_Yacc/al.lex
  3. 83
    0
      Lex_Yacc/as.y
  4. 54
    0
      Makefile
  5. 45
    0
      ReadMe.md
  6. 248
    0
      Tables/tables.c
  7. 14
    0
      Tables/tables.h

+ 6
- 0
.gitignore View File

1
+rondoudou_interpreter_registres
2
+Tables/*.o
3
+Lex_Yacc/as.output 
4
+Lex_Yacc/as.tab.* 
5
+Lex_Yacc/lex.yy.*
6
+Lex_Yacc/as.dot

+ 51
- 0
Lex_Yacc/al.lex View File

1
+%{
2
+#include "as.tab.h"
3
+int yywrap(void){return 1;}
4
+void
5
+yyerror (char const *s)
6
+{
7
+
8
+  fprintf (stderr, "%s\n", s);
9
+}
10
+
11
+%}
12
+
13
+%%
14
+
15
+"ADD"     { return tADD ;} 
16
+"SUB"     { return tSUB;}
17
+"MUL"     { return tMUL; }
18
+"DIV"			{ return tDIV; }
19
+"INF"			{ return tINF; }
20
+"SUP"     { return tSUP; }
21
+"EQU"     { return tEQU; }
22
+
23
+"AFC"    	{ return tAFC; }
24
+"CPY"     { return tCPY; }
25
+
26
+"LOAD"    	{ return tLOAD; }
27
+"STORE"     { return tSTORE; }
28
+"LOADI"    	{ return tLOADI; }
29
+"STOREI"     { return tSTOREI; }
30
+"STOREA"     { return tSTOREA; }
31
+
32
+"JMP"     { return tJMP; }
33
+"JMZ"     { return tJMZ; }
34
+
35
+"GET"     { return tGET; }
36
+"PRI"     { return tPRI; }
37
+
38
+"CALL"    { return tCALL; }
39
+"RET"     { return tRET; }
40
+
41
+"STOP"     { return tSTOP; }
42
+
43
+[0-9]+	  { yylval.nombre = atoi(yytext); return tNB; }
44
+
45
+"\n"	{}
46
+" "		{}
47
+"\t"	{}
48
+
49
+%%
50
+
51
+

+ 83
- 0
Lex_Yacc/as.y View File

1
+%union {
2
+	int nombre;
3
+}
4
+
5
+%{
6
+#include "../Tables/tables.h"
7
+#include <stdlib.h>
8
+%}
9
+
10
+%token tMUL tDIV tADD tSUB tINF tSUP tEQU
11
+%token tAFC tCPY 
12
+%token tLOAD tSTORE tLOADI tSTOREI tSTOREA
13
+%token tJMP tJMZ
14
+%token tGET tPRI
15
+%token tCALL tRET
16
+%token tSTOP
17
+%token<nombre> tNB
18
+
19
+%%
20
+
21
+// Un programme est une suite d'au moins une instruction
22
+Programme : Instruction Programme;
23
+Programme : Instruction;
24
+
25
+
26
+// Liste de toutes les instructions et conversion
27
+
28
+// MUL, ADD, DIV....
29
+Instruction : tMUL tNB tNB tNB {add_instruction(MUL, $2, $3, $4);};           
30
+Instruction : tADD tNB tNB tNB {add_instruction(ADD, $2, $3, $4);};
31
+Instruction : tDIV tNB tNB tNB {add_instruction(DIV, $2, $3, $4);};
32
+Instruction : tSUB tNB tNB tNB {add_instruction(SUB, $2, $3, $4);};
33
+Instruction : tINF tNB tNB tNB {add_instruction(INF, $2, $3, $4);};
34
+Instruction : tSUP tNB tNB tNB {add_instruction(SUP, $2, $3, $4);};
35
+Instruction : tEQU tNB tNB tNB {add_instruction(EQU, $2, $3, $4);};
36
+
37
+// AFC R val
38
+Instruction : tAFC tNB tNB     {add_instruction(AFC, $2, $3, 0);};            
39
+// CPY R1 R2
40
+Instruction : tCPY tNB tNB     {add_instruction(CPY, $2, $3, 0);};
41
+
42
+// LOAD R @ 
43
+Instruction : tLOAD tNB tNB    {add_instruction(LOAD, $2, $3, 0);};
44
+// STORE @ R 
45
+Instruction : tSTORE tNB tNB   {add_instruction(STORE, $2, $3, 0);};
46
+// LOADI R R 
47
+Instruction : tLOADI tNB tNB    {add_instruction(LOADI, $2, $3, 0);};
48
+// STOREI R R 
49
+Instruction : tSTOREI tNB tNB   {add_instruction(STOREI, $2, $3, 0);};
50
+// STOREA @ R 
51
+Instruction : tSTOREA tNB tNB   {add_instruction(STORE, $2, $3, 0);};
52
+
53
+// JMP Ins 
54
+Instruction : tJMP tNB         {add_instruction(JMP, $2, 0, 0);};
55
+// JMF @ Ins 
56
+Instruction : tJMZ tNB         {add_instruction(JMZ, $2, 0, 0);};
57
+
58
+// GET @ 
59
+Instruction : tGET tNB         {add_instruction(GET, $2, 0, 0);};
60
+// PRI @ 
61
+Instruction : tPRI tNB         {add_instruction(PRI, $2, 0, 0);};
62
+
63
+// CALL Ins Val  
64
+Instruction : tCALL tNB tNB    {add_instruction(CALL, $2, $3, 0);};
65
+// RET
66
+Instruction : tRET             {add_instruction(RET, 0, 0, 0);};
67
+
68
+// STOP Val
69
+Instruction : tSTOP tNB        {add_instruction(STOP, $2, 0, 0);};
70
+
71
+%%
72
+
73
+int main(int argc, char * argv[]) {
74
+	if (argc != 2) {
75
+		printf("Specifiez le fichier à interpreter");
76
+		exit(2);
77
+	}
78
+	extern FILE * yyin; 
79
+	yyin = fopen(argv[1], "r");
80
+	yyparse();
81
+	execute();
82
+	return 0;
83
+}

+ 54
- 0
Makefile View File

1
+default : 
2
+	@echo "Spécifiez une cible"
3
+
4
+
5
+
6
+###########################
7
+###      NETTOYAGE      ###
8
+###########################
9
+clean_all : clean clean_Inputs clean_Outputs
10
+
11
+clean: clean_Lex_Yacc clean_Tables
12
+	@rm -f rondoudou_interpreter_registres
13
+
14
+clean_Tables:
15
+	@rm -f Tables/*.o
16
+
17
+clean_Lex_Yacc:
18
+	@rm -f Lex_Yacc/as.output Lex_Yacc/as.tab.* Lex_Yacc/lex.yy.* Lex_Yacc/as.dot
19
+
20
+clean_Inputs:
21
+	@rm -f Inputs/*
22
+
23
+clean_Outputs:
24
+	@rm -f Outputs/*
25
+
26
+
27
+
28
+###########################
29
+###     COMPILATION     ###
30
+###########################
31
+build : clean build_Tables build_Lex_Yacc
32
+	gcc Lex_Yacc/as.tab.o Lex_Yacc/lex.yy.o Tables/tables.o -ll -o rondoudou_interpreter_registres
33
+
34
+build_Tables: clean_Tables
35
+	gcc -c Tables/tables.c -o Tables/tables.o
36
+
37
+build_Lex_Yacc: clean_Lex_Yacc
38
+	bison -g -v -d -t -b Lex_Yacc/as Lex_Yacc/as.y
39
+	flex -o Lex_Yacc/lex.yy.c Lex_Yacc/al.lex
40
+	gcc -c Lex_Yacc/as.tab.c -o Lex_Yacc/as.tab.o
41
+	gcc -c Lex_Yacc/lex.yy.c -o Lex_Yacc/lex.yy.o
42
+
43
+
44
+
45
+###########################
46
+###       EDITION       ###
47
+###########################
48
+edit_Lex_Yacc: 
49
+	pluma Lex_Yacc/al.lex Lex_Yacc/as.y &
50
+
51
+edit_Tables: 
52
+	pluma Tables/tables.c Tables/tables.h &
53
+
54
+edit: edit_Lex_Yacc edit_Tables

+ 45
- 0
ReadMe.md View File

1
+# Processeur sécurisé - Interpreteur
2
+
3
+
4
+
5
+Afin de pouvoir tester le code que nous avons compilé depuis le C avec notre compilateur, nous avons crée un interpreteur pour simuler l'execution du code assembleur
6
+
7
+# Utilisation du cross assembleur
8
+
9
+Un Makefile a été inclus au sous module Interpreteur afin de simplifier son utilisation. Ainsi, afin de compiler tout l'Interpreteur, il suffit de de rentrer la commande.
10
+``` bash
11
+make build
12
+```
13
+Pour lancer l'Interpretation du code qui aura été préalablement généré avec notre compilateur, il suffit de lancer la commande 
14
+``` bash
15
+cat FicherASM | ./rondoudou_interpreter
16
+```
17
+Les prints et gets du programme auront lieu dans le terminal. 
18
+
19
+
20
+
21
+NB : Il est possible de rester au niveau du projet général. Un Makefile est aussi présent. Pour compiler l'Interpreteur uniquement : 
22
+``` bash
23
+make compile QUOI="interpreteur"
24
+```
25
+Pour compiler le projet en entier :
26
+``` bash
27
+make compile QUOI="all"
28
+```
29
+
30
+Pour interpreter le fichier ***file_name.memasm*** :
31
+``` bash
32
+make exec SOURCE="file_name" QUOI="interprete"
33
+```
34
+Pour compiler, cross assembler et interpreter 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*** :
35
+``` bash
36
+make exec SOURCE="file_name" QUOI="all"
37
+```
38
+
39
+# Implémentation
40
+
41
+L'implémentation a été réalisée grâce à Lex/Yacc. Le parseur charge le programme dans un buffer, puis une méthode d'execution est lancée.
42
+
43
+
44
+
45
+

+ 248
- 0
Tables/tables.c View File

1
+#include "tables.h"
2
+#include <stdio.h>
3
+#include <stdlib.h>
4
+
5
+#define TAILLE_BUFFER_INSTRUCTIONS (1024)
6
+#define TAILLE_MEMOIRE (32)
7
+#define TAILLE_PILE_APPELS (16)
8
+#define TAILLE_BANC_REGISTRES (16)
9
+
10
+
11
+/**************************************************/
12
+/**************************************************/
13
+/************ Variables et structures *************/
14
+/**************************************************/
15
+/**************************************************/
16
+
17
+// Structure coding an instruction
18
+struct str_instruction {
19
+	enum instruction_t instruction;
20
+	int param1;
21
+	int param2;
22
+	int param3;
23
+};
24
+
25
+// Buffer stockant le programme
26
+struct str_instruction programme[TAILLE_BUFFER_INSTRUCTIONS * sizeof(struct str_instruction)];
27
+
28
+// Pointeur d'instruction
29
+int eip = 0;
30
+
31
+// Banc de registre
32
+int registres[TAILLE_BANC_REGISTRES];
33
+
34
+// Memoire du programme
35
+int mem[TAILLE_MEMOIRE];
36
+
37
+// Pointeur de base dans la mémoire
38
+int ebp = 0;
39
+
40
+// Memoire du programme
41
+int pile[TAILLE_PILE_APPELS];
42
+
43
+// Pointeur de sommet dans la pile d'appel
44
+int esp = 0;
45
+
46
+// Flag Z
47
+int Z = 0;
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+/**************************************************/
62
+/**************************************************/
63
+/******* Fonctions internes de verification *******/
64
+/**************************************************/
65
+/**************************************************/
66
+
67
+// Verifie qu'une adresse est bien en mémoire (renvoi l'adresse si oui, leve une exception si non)
68
+int check_adresse(int adresse) {
69
+	if (adresse >= TAILLE_MEMOIRE || adresse < 0) {
70
+		printf("\033[31;01m ERROR : \033[00m Segmentation fault de %d avec eip = %d et ebp = %d\n", adresse, eip, ebp);
71
+		exit(2);
72
+	} 
73
+	return adresse;
74
+}
75
+
76
+// Verifie qu'un numéro de registre est valide
77
+int check_registre(int registre) {
78
+	if (registre >= TAILLE_BANC_REGISTRES || registre < 0) {
79
+		printf("\033[31;01m ERROR : \033[00m Register error\n");
80
+		exit(2);
81
+	} 
82
+	return registre;
83
+}
84
+
85
+// Verifie que les limites de la mémoire d'appels ne sont pas franchies
86
+int check_adresse_pile(int adresse) {
87
+	if (adresse >= TAILLE_PILE_APPELS || adresse < 0) {
88
+		printf("\033[31;01m ERROR : \033[00m Stack error\n");
89
+		exit(2);
90
+	} 
91
+	return adresse;
92
+}
93
+
94
+// Verifie que eip ne depasse pas la taille du buffer
95
+int check_eip(int eip) {
96
+	if (eip >= TAILLE_BUFFER_INSTRUCTIONS) {
97
+		printf("\033[31;01m ERROR : \033[00m Taille du buffer insuffisante pour charger le programme\n");
98
+		exit(2);
99
+	} else if (eip < 0) {
100
+		printf("\033[31;01m ERROR : \033[00m EIP < 0\n");
101
+		exit(2);
102
+	} 
103
+	return eip;
104
+}
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+/**************************************************/
117
+/**************************************************/
118
+/********** Fonction interne d'affichage **********/
119
+/**************************************************/
120
+/**************************************************/
121
+
122
+// Affiche la mémoire
123
+void print() {
124
+	int i;
125
+	printf("EBP : %d\n", ebp);
126
+	for (i=0; i<TAILLE_MEMOIRE; i++) {
127
+		printf("mem[%d] = %d\n", i, mem[i]);
128
+	} 
129
+}
130
+
131
+// Affiche les registres
132
+void print_reg() {
133
+	int i;
134
+	for (i=0; i<TAILLE_BANC_REGISTRES; i++) {
135
+		printf("registres[%d] = %d\n", i, registres[i]);
136
+	} 
137
+}
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+/**************************************************/
146
+/**************************************************/
147
+/************** Instructions Writing **************/
148
+/**************************************************/
149
+/**************************************************/
150
+
151
+// Add a new instruction
152
+void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
153
+	struct str_instruction my_instruction = {inst, param1, param2, param3};
154
+	programme[check_eip(eip)] = my_instruction;
155
+	eip++;
156
+}
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+/**************************************************/
167
+/**************************************************/
168
+/************* Execution du programme *************/
169
+/**************************************************/
170
+/**************************************************/
171
+
172
+// execute le programme
173
+void execute() {
174
+	printf("Debut de l'interpretation\n");
175
+	eip = 0;
176
+	int continuer = 1;
177
+	while (continuer) {
178
+		       if (programme[eip].instruction == ADD) {
179
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] + registres[check_registre(programme[eip].param3)];
180
+		} else if (programme[eip].instruction == SUB) {
181
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] - registres[check_registre(programme[eip].param3)];
182
+			Z = !registres[check_registre(programme[eip].param1)];
183
+		} else if (programme[eip].instruction == MUL) {
184
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] * registres[check_registre(programme[eip].param3)];
185
+		} else if (programme[eip].instruction == DIV) {
186
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] / registres[check_registre(programme[eip].param3)];
187
+		} else if (programme[eip].instruction == INF) {
188
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] < registres[check_registre(programme[eip].param3)];
189
+		} else if (programme[eip].instruction == SUP) {
190
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] > registres[check_registre(programme[eip].param3)];
191
+		} else if (programme[eip].instruction == EQU) {
192
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)] == registres[check_registre(programme[eip].param3)];
193
+
194
+
195
+		} else if (programme[eip].instruction == AFC) {
196
+			registres[check_registre(programme[eip].param1)] = programme[eip].param2;
197
+		} else if (programme[eip].instruction == CPY) {
198
+			registres[check_registre(programme[eip].param1)] = registres[check_registre(programme[eip].param2)];
199
+
200
+		} else if (programme[eip].instruction == LOAD) {
201
+			registres[check_registre(programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)];
202
+		} else if (programme[eip].instruction == STORE) {
203
+			mem[check_adresse(ebp + programme[eip].param1)] = registres[check_registre(programme[eip].param2)];
204
+		} else if (programme[eip].instruction == LOADI) {
205
+			registres[check_registre(programme[eip].param1)] = mem[check_adresse(registres[check_registre(programme[eip].param2)])];
206
+		} else if (programme[eip].instruction == STOREI) {
207
+			mem[check_adresse(registres[check_registre(programme[eip].param1)])] = registres[check_registre(programme[eip].param2)];
208
+		} else if (programme[eip].instruction == STOREA) {
209
+			mem[check_adresse(ebp + programme[eip].param1)] = registres[check_registre(programme[eip].param2)] + ebp;
210
+
211
+		} else if (programme[eip].instruction == JMP) {
212
+			eip = programme[eip].param1 - 1;
213
+		} else if (programme[eip].instruction == JMZ) {
214
+			if (Z) {
215
+				eip = programme[eip].param1 - 1;
216
+			}
217
+
218
+		} else if (programme[eip].instruction == GET) {
219
+			printf("Veuillez saisir un nombre : \n");
220
+			scanf("%d", &(registres[check_registre(programme[eip].param1)]));
221
+		} else if (programme[eip].instruction == PRI) {
222
+			printf("%d@%d\n", registres[check_registre(programme[eip].param1)], programme[eip].param1);
223
+
224
+		} else if (programme[eip].instruction == CALL) {
225
+			pile[check_adresse_pile(esp)] = ebp;
226
+			esp++;
227
+			pile[check_adresse_pile(esp)] = eip + 1;
228
+			esp++;
229
+			ebp = ebp + programme[eip].param2;
230
+			eip = programme[eip].param1 - 1;	
231
+			
232
+		} else if (programme[eip].instruction == RET) {
233
+			esp--;
234
+			eip = pile[check_adresse_pile(esp)] - 1;
235
+			esp--;
236
+			ebp = pile[check_adresse_pile(esp)];
237
+			
238
+		} else if (programme[eip].instruction == STOP) {
239
+			if (programme[eip].param1 == 0) {
240
+				continuer = 0;
241
+				print();
242
+				print_reg();
243
+			}
244
+		} 
245
+		eip = (eip + 1) % TAILLE_BUFFER_INSTRUCTIONS;
246
+		//printf("EIP : %d ; Z : %d\n", eip, Z);
247
+	}
248
+}

+ 14
- 0
Tables/tables.h View File

1
+#ifndef TABLE_H
2
+#define TABLE_H
3
+
4
+
5
+// Enum of the instruction
6
+enum instruction_t {ADD, MUL, SUB, DIV, INF, SUP, EQU, CPY, AFC, LOAD, STORE, LOADI, STOREI, STOREA, JMP, JMZ, PRI, GET, CALL, RET, STOP};
7
+
8
+// Add a new instruction
9
+void add_instruction(enum instruction_t inst, int param1, int param2, int param3);
10
+
11
+// Execute the program
12
+void execute();
13
+
14
+#endif

Loading…
Cancel
Save