197 lines
6.3 KiB
C
197 lines
6.3 KiB
C
#include "tables.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define TAILLE_BUFFER_INSTRUCTIONS (1024)
|
|
#define TAILLE_MEMOIRE (64)
|
|
|
|
|
|
/**************************************************/
|
|
/**************************************************/
|
|
/************ Variables et structures *************/
|
|
/**************************************************/
|
|
/**************************************************/
|
|
|
|
// Structure coding an instruction
|
|
struct str_instruction {
|
|
enum instruction_t instruction;
|
|
int param1;
|
|
int param2;
|
|
int param3;
|
|
};
|
|
|
|
// Buffer stockant le programme
|
|
struct str_instruction programme[TAILLE_BUFFER_INSTRUCTIONS * sizeof(struct str_instruction)];
|
|
|
|
// Pointeur d'instruction
|
|
int eip = 0;
|
|
|
|
// Memoire du programme
|
|
int mem[TAILLE_MEMOIRE];
|
|
|
|
// Pointeur de base dans la mémoire
|
|
int ebp = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************/
|
|
/**************************************************/
|
|
/******* Fonctions internes de verification *******/
|
|
/**************************************************/
|
|
/**************************************************/
|
|
|
|
// Verifie qu'une adresse est bien en mémoire (renvoi l'adresse si oui, leve une exception si non)
|
|
int check_adresse(int adresse) {
|
|
if (adresse >= TAILLE_MEMOIRE || adresse < 0) {
|
|
printf("\033[31;01m ERROR : \033[00m Segmentation fault\n");
|
|
exit(2);
|
|
}
|
|
return adresse;
|
|
}
|
|
|
|
// Verifie que eip ne depasse pas la taille du buffer
|
|
int check_eip(int eip) {
|
|
if (eip >= TAILLE_BUFFER_INSTRUCTIONS) {
|
|
printf("\033[31;01m ERROR : \033[00m Taille du buffer insuffisante pour charger le programme\n");
|
|
exit(2);
|
|
} else if (eip < 0) {
|
|
printf("\033[31;01m ERROR : \033[00m EIP < 0\n");
|
|
exit(2);
|
|
}
|
|
return eip;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************/
|
|
/**************************************************/
|
|
/********** Fonction interne d'affichage **********/
|
|
/**************************************************/
|
|
/**************************************************/
|
|
|
|
// Affiche la mémoire
|
|
void print() {
|
|
int i;
|
|
printf("EBP : %d\n", ebp);
|
|
for (i=0; i<TAILLE_MEMOIRE; i++) {
|
|
printf("mem[%d] = %d\n", i, mem[i]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************/
|
|
/**************************************************/
|
|
/************** Instructions Writing **************/
|
|
/**************************************************/
|
|
/**************************************************/
|
|
|
|
// Add a new instruction
|
|
void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
|
|
struct str_instruction my_instruction = {inst, param1, param2, param3};
|
|
programme[check_eip(eip)] = my_instruction;
|
|
eip++;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************/
|
|
/**************************************************/
|
|
/************* Execution du programme *************/
|
|
/**************************************************/
|
|
/**************************************************/
|
|
|
|
// execute le programme
|
|
void execute() {
|
|
printf("Debut de l'interpretation\n");
|
|
eip = 0;
|
|
int continuer = 1;
|
|
while (continuer) {
|
|
if (programme[eip].instruction == ADD) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] + mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == SUB) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] - mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == MUL) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] * mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == DIV) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] / mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == INF) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] < mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == SUP) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] > mem[check_adresse(ebp + programme[eip].param3)];
|
|
} else if (programme[eip].instruction == EQU) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] == mem[check_adresse(ebp + programme[eip].param3)];
|
|
|
|
|
|
} else if (programme[eip].instruction == AFC) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = programme[eip].param2;
|
|
} else if (programme[eip].instruction == CPY) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)];
|
|
} else if (programme[eip].instruction == AFCA) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = ebp + programme[eip].param2;
|
|
|
|
} else if (programme[eip].instruction == READ) {
|
|
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(mem[check_adresse(ebp + programme[eip].param2)])];
|
|
} else if (programme[eip].instruction == WRITE) {
|
|
mem[check_adresse(mem[check_adresse(ebp + programme[eip].param1)])] = mem[check_adresse(ebp + programme[eip].param2)];
|
|
|
|
} else if (programme[eip].instruction == JMP) {
|
|
eip = programme[eip].param1 - 1;
|
|
} else if (programme[eip].instruction == JMF) {
|
|
if (!mem[check_adresse(ebp + programme[eip].param1)]) {
|
|
eip = programme[eip].param2 - 1;
|
|
}
|
|
|
|
} else if (programme[eip].instruction == GET) {
|
|
printf("Veuillez saisir un nombre : \n");
|
|
scanf("%d", &(mem[check_adresse(ebp + programme[eip].param1)]));
|
|
} else if (programme[eip].instruction == PRI) {
|
|
printf("%d@%d\n", mem[check_adresse(ebp + programme[eip].param1)], ebp + programme[eip].param1);
|
|
|
|
} else if (programme[eip].instruction == CALL) {
|
|
mem[check_adresse(ebp + programme[eip].param2)] = ebp;
|
|
mem[check_adresse(ebp + programme[eip].param2 + 1)] = eip + 1;
|
|
ebp = ebp + programme[eip].param2 + 2;
|
|
eip = programme[eip].param1 - 1;
|
|
|
|
} else if (programme[eip].instruction == RET) {
|
|
int lastebp = ebp;
|
|
eip = mem[check_adresse(ebp - 1)] - 1;
|
|
ebp = mem[check_adresse(ebp - 2)];
|
|
mem[check_adresse(lastebp - 2)] = mem[check_adresse(lastebp)];
|
|
|
|
} else if (programme[eip].instruction == STOP) {
|
|
if (programme[eip].param1 == 0) {
|
|
continuer = 0;
|
|
}
|
|
}
|
|
eip = (eip + 1) % TAILLE_BUFFER_INSTRUCTIONS;
|
|
//printf("EIP : %d \n", eip);
|
|
}
|
|
}
|