Compare commits

...

2 Commits

Author SHA1 Message Date
Giulio De Pasquale
f1060ff86c NULL pointers everywhere 2017-05-14 23:01:11 +02:00
Giulio De Pasquale
f818b5548e MOVI,MOVR,PUTM,GETM,ADDI 2017-05-14 22:10:58 +02:00
6 changed files with 241 additions and 42 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
*.out
.vscode/

View File

@ -8,19 +8,10 @@
using namespace std;
int main() {
ifstream vmbytecode;
VM vm;
uint8_t *data;
uint8_t bytecode[] = "\x00\x00\x00";
VM vm(bytecode, sizeof(bytecode));
vm.run();
printf("\n\n");
vm.status();
// vm.status();
/*
if (vmbytecode != NULL) {
fread()
} else {
fprintf(stderr, "Couldn't open bytecode!\n");
return 1;
}
*/
return 0;
}

View File

@ -3,15 +3,21 @@
#include "vmas.h"
#include <string.h>
/*
CONSTRUCTORS
*/
VM::VM() {
DBG_INFO(("Creating VM without code.\n"));
as.allocate();
init_regs();
}
VM::VM(uint8_t *code, uint32_t codesize) {
DBG_INFO(("Creating VM with code.\n"));
if (as.allocate()) {
as.insCode(code, codesize);
}
init_regs();
as.insCode(code, codesize);
}
void VM::init_regs(void) {
@ -68,4 +74,112 @@ void VM::status(void) {
return;
}
void VM::run(uint8_t *code) { return; }
/*
INSTRUCTIONS IMPLEMENTATIONS
*/
void VM::exec_movi(void) {
/*
MOVI R0, 0x2400 | R0 = 0x2400
*/
uint8_t dst;
uint16_t imm;
dst = as.code[regs[IP] + 1];
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("MOVI 0x%x 0x%x\n", dst, imm));
regs[dst] = imm;
return;
}
void VM::exec_movr(void) {
/*
MOVR R1, R0 | R1 = R0
---------------------
R1, R0 = 0x10 <- DST / SRC are nibbles!
*/
uint8_t dst, src;
dst = as.code[regs[IP] + 1] >> 4;
src = as.code[regs[IP] + 1] & 0b00001111;
DBG_INFO(("MOVR 0x%x 0x%x\n", dst, src));
regs[dst] = regs[src];
return;
}
void VM::exec_getm(void) {
/*
GETM R0, 0x1000 | R0 = data[0x1000]
*/
uint8_t dst;
uint16_t src;
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("GETM 0x%x 0x%x\n", dst, src));
regs[dst] = *((uint16_t *)&as.data[src]);
return;
}
void VM::exec_putm(void) {
/*
PUTM 0x1000, R0 | data[0x1000] = R0
*/
uint16_t dst;
uint8_t src;
dst = *((uint16_t *)&as.code[regs[IP] + 1]);
src = as.code[regs[IP] + 3];
DBG_INFO(("PUTM 0x%x 0x%x\n", dst, src));
*((uint16_t *)&as.data[dst]) = regs[src];
return;
}
void VM::exec_addi(void) {
/*
ADDI R0, 0x2 | R0 += 2
*/
uint8_t dst;
uint16_t src;
dst = as.code[regs[IP] + 1];
src = *((uint16_t *)&as.code[regs[IP] + 2]);
DBG_INFO(("ADDI 0x%x 0x%x\n", dst, src));
regs[dst] += src;
return;
}
void VM::run(void) {
uint8_t opcode;
bool finished = false;
while (!finished) {
opcode = (uint8_t)as.code[regs[IP]];
switch (opcode) {
case MOVI:
exec_movi();
regs[IP] += MOVI_SIZE;
break;
case MOVR:
exec_movr();
regs[IP] += MOVR_SIZE;
break;
case GETM:
exec_getm();
regs[IP] += GETM_SIZE;
break;
case PUTM:
exec_putm();
regs[IP] += PUTM_SIZE;
break;
case ADDI:
exec_addi();
regs[IP] += ADDI_SIZE;
break;
case HALT:
DBG_INFO(("HALT\n"));
finished = true;
break;
default:
DBG_INFO(("WAT: 0x%x\n", opcode));
finished = true;
break;
}
}
return;
}

View File

@ -1,32 +1,35 @@
#ifndef VM_H
#define VM_H
#include <stdint.h>
#include "vmas.h"
#include <stdint.h>
#define MOVI_SIZE 4
#define MOVR_SIZE 2
#define GETM_SIZE 4
#define PUTM_SIZE 4
#define ADDI_SIZE 4
enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP };
/*
MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG
*/
enum ins {
MOVI,
MOVR,
MOVM,
GETM,
PUTM,
ADDI,
ADDR,
ADDM,
SUBI,
SUBR,
SUBM,
XORI,
XORR,
XORM,
NOTI,
NOTR,
NOTM,
MULI,
MULR,
MULM,
DIVI,
DIVR,
DIVM,
PUSH,
POOP,
CALL,
@ -35,19 +38,29 @@ enum ins {
};
class VM {
private:
uint16_t regs[0xb];
struct flags {
uint8_t zf : 1;
uint8_t cf : 1;
};
VMAddrSpace as;
/*
IMPLEMENTATIONS
*/
void exec_movi(void);
void exec_movr(void);
void exec_movm(void);
void exec_getm(void);
void exec_putm(void);
void exec_addi(void);
public:
VM();
VM(uint8_t *code, uint32_t codesize);
void init_regs(void);
void status(void);
void run(uint8_t *code);
void run();
};
#endif

View File

@ -1,22 +1,94 @@
#include <stdint.h>
#include <string.h>
#include "vmas.h"
#include "debug.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
void VMAddrSpace::insCode(uint8_t * buf, uint8_t size) {
DBG_INFO(("Copying buffer into code section.\n"));
memcpy(&this->code, buf, size);
return;
VMAddrSpace::VMAddrSpace() {
stack = NULL;
code = NULL;
data = NULL;
stacksize = DEFAULT_STACKSIZE;
codesize = DEFAULT_CODESIZE;
datasize = DEFAULT_DATASIZE;
return;
}
void VMAddrSpace::insStack(uint8_t * buf, uint8_t size) {
DBG_INFO(("Copying buffer into code section.\n"));
memcpy(&this->stack, buf, size);
return;
VMAddrSpace::VMAddrSpace(uint32_t ss, uint32_t cs, uint32_t ds) {
stack = NULL;
code = NULL;
data = NULL;
stacksize = ss;
codesize = cs;
datasize = ds;
return;
}
void VMAddrSpace::insData(uint8_t * buf, uint8_t size) {
bool VMAddrSpace::allocate(void) {
DBG_INFO(("Allocating sections...\n"));
if (code == NULL) {
DBG_INFO(("\tcode...\n"));
code = (uint8_t *)malloc(codesize);
}
if (data == NULL) {
DBG_INFO(("\tdata...\n"));
data = (uint8_t *)malloc(datasize);
}
if (stack == NULL) {
DBG_INFO(("\tstack...\n"));
stack = (uint8_t *)malloc(stacksize);
}
if (code == NULL) {
DBG_ERROR(("Couldn't allocate code section.\n"));
return false;
}
data = (uint8_t *)malloc(datasize);
if (data == NULL) {
DBG_ERROR(("Couldn't allocate data section.\n"));
return false;
}
stack = (uint8_t *)malloc(stacksize);
if (stack == NULL) {
DBG_ERROR(("Couldn't allocate stack section.\n"));
return false;
}
memset(code, 0xff,
stacksize); // auto halt in case the assembly is not correct
memset(stack, 0x0, stacksize);
memset(data, 0x0, stacksize);
DBG_SUCC(("Done!\n"));
return true;
}
bool VMAddrSpace::insCode(uint8_t *buf, uint8_t size) {
if (code) {
DBG_INFO(("Copying buffer into code section.\n"));
memcpy(code, buf, size);
} else {
DBG_ERROR(("Couldn't write into code section.\n"));
return false;
}
return true;
}
bool VMAddrSpace::insStack(uint8_t *buf, uint8_t size) {
if (stack) {
DBG_INFO(("Copying buffer into stack section.\n"));
memcpy(stack, buf, size);
} else {
DBG_ERROR(("Couldn't write into stack section.\n"));
return false;
}
return true;
}
bool VMAddrSpace::insData(uint8_t *buf, uint8_t size) {
if (this->code) {
DBG_INFO(("Copying buffer into data section.\n"));
memcpy(&this->data, buf, size);
return;
memcpy(data, buf, size);
} else {
DBG_ERROR(("Couldn't write into data section.\n"));
return false;
}
return true;
}

View File

@ -1,14 +1,22 @@
#ifndef VMAS_H
#define VMAS_H
#include <stdint.h>
#define DEFAULT_STACKSIZE 0x100
#define DEFAULT_CODESIZE 0x300
#define DEFAULT_DATASIZE 0x100
class VMAddrSpace {
uint8_t stack[0x100], code[0x300], data[0x500];
private:
uint32_t stacksize, codesize, datasize;
public:
void assemble(void);
void insStack(uint8_t *buf, uint8_t size);
void insCode(uint8_t *buf, uint8_t size);
void insData(uint8_t *buf, uint8_t size);
VMAddrSpace();
VMAddrSpace(uint32_t ss, uint32_t cs, uint32_t ds);
uint8_t *stack, *code, *data;
bool allocate(void);
bool insStack(uint8_t *buf, uint8_t size);
bool insCode(uint8_t *buf, uint8_t size);
bool insData(uint8_t *buf, uint8_t size);
};
#endif