Assemblaggio label corretto. BUGGATO A BESTIA
This commit is contained in:
parent
c24e2c791f
commit
07b9de5f2a
@ -310,19 +310,27 @@ class VMSection:
|
|||||||
Represents a code section or "label" such as "main:"
|
Represents a code section or "label" such as "main:"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name, line_start):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.size = 0
|
self.size = 0
|
||||||
self.offset = 0
|
self.offset = 0
|
||||||
|
self.line_start = line_start
|
||||||
|
self.line_end = 0
|
||||||
|
|
||||||
def set_size(self, size):
|
def set_size(self, size):
|
||||||
self.size = size
|
self.size = size
|
||||||
|
|
||||||
def set_offset(self, offset):
|
def set_offset(self, offset):
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
|
def set_line_start(self, start):
|
||||||
|
self.line_start = start
|
||||||
|
|
||||||
|
def set_line_end(self, end):
|
||||||
|
self.line_end = end
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "{} | s: {}, o: {}".format(self.name, hex(self.size), hex(self.offset))
|
return "{} | ls: {}, le: {}, s: {}, o: {}".format(self.name, hex(self.line_start), hex(self.line_end), hex(self.size), hex(self.offset))
|
||||||
|
|
||||||
op_names = [["MOVI", "imm2reg"],
|
op_names = [["MOVI", "imm2reg"],
|
||||||
["MOVR", "reg2reg"],
|
["MOVR", "reg2reg"],
|
||||||
@ -360,6 +368,7 @@ op_names = [["MOVI", "imm2reg"],
|
|||||||
["JPER", "jump"],
|
["JPER", "jump"],
|
||||||
["JPNI", "jump"],
|
["JPNI", "jump"],
|
||||||
["JPNR", "jump"],
|
["JPNR", "jump"],
|
||||||
|
["RETN", "single"],
|
||||||
["SHIT", "single"],
|
["SHIT", "single"],
|
||||||
["NOPE", "single"],
|
["NOPE", "single"],
|
||||||
["GRMN", "single"]]
|
["GRMN", "single"]]
|
||||||
@ -376,13 +385,29 @@ register_re = re.compile("(^[rRsS]{1}[0-9]{1}$)|([iIbBsS]{1}[pP]{1}$)")
|
|||||||
def parse_sections(lines):
|
def parse_sections(lines):
|
||||||
current_size = 0
|
current_size = 0
|
||||||
current_section = None
|
current_section = None
|
||||||
|
|
||||||
|
# first parsing to get sections' names
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if section_re.match(line):
|
||||||
|
if current_section:
|
||||||
|
tmp = next(x for x in sections if x.name == current_section)
|
||||||
|
tmp.set_line_end(i-1)
|
||||||
|
current_section = line.casefold()[:-1]
|
||||||
|
sections.append(VMSection(current_section, i + 1))
|
||||||
|
continue
|
||||||
|
#components = [x for x in re.split('\W', line) if x]
|
||||||
|
#instruction = VMInstruction(components[0], components[1:])
|
||||||
|
#current_size += instruction.size
|
||||||
|
tmp = next(x for x in sections if x.name == current_section)
|
||||||
|
tmp.set_line_end(i)
|
||||||
|
|
||||||
|
# calculating sizes and offsets
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if section_re.match(line):
|
if section_re.match(line):
|
||||||
if current_section:
|
if current_section:
|
||||||
tmp = next(x for x in sections if x.name == current_section)
|
tmp = next(x for x in sections if x.name == current_section)
|
||||||
tmp.set_size(current_size)
|
tmp.set_size(current_size)
|
||||||
current_section = line.casefold()[:-1]
|
current_section = line.casefold()[:-1]
|
||||||
sections.append(VMSection(current_section))
|
|
||||||
current_size = 0
|
current_size = 0
|
||||||
continue
|
continue
|
||||||
components = [x for x in re.split('\W', line) if x]
|
components = [x for x in re.split('\W', line) if x]
|
||||||
@ -391,6 +416,12 @@ def parse_sections(lines):
|
|||||||
tmp = next(x for x in sections if x.name == current_section)
|
tmp = next(x for x in sections if x.name == current_section)
|
||||||
tmp.set_size(current_size)
|
tmp.set_size(current_size)
|
||||||
|
|
||||||
|
# if not, main as to be the first entry
|
||||||
|
for i in range(len(sections)):
|
||||||
|
if sections[i].name == "main" and i is not 0:
|
||||||
|
sections[0], sections[i] = sections[i], sections[0]
|
||||||
|
break
|
||||||
|
calc_section_offsets()
|
||||||
|
|
||||||
def calc_section_offsets():
|
def calc_section_offsets():
|
||||||
current_offset = 0
|
current_offset = 0
|
||||||
@ -417,11 +448,10 @@ def main():
|
|||||||
if "main" not in [x.name for x in sections]:
|
if "main" not in [x.name for x in sections]:
|
||||||
sys.stderr.write("No main specified!")
|
sys.stderr.write("No main specified!")
|
||||||
return
|
return
|
||||||
|
|
||||||
calc_section_offsets()
|
for s in sections:
|
||||||
|
section_code = filedata[s.line_start:s.line_end+1]
|
||||||
for line in filedata:
|
for line in section_code:
|
||||||
if not section_re.match(line):
|
|
||||||
vma.process_code_line(line)
|
vma.process_code_line(line)
|
||||||
|
|
||||||
with open(sys.argv[3], 'wb') as f:
|
with open(sys.argv[3], 'wb') as f:
|
||||||
|
@ -38,6 +38,7 @@ enum OPS_STARTING_VALUES {
|
|||||||
JPER,
|
JPER,
|
||||||
JPNI,
|
JPNI,
|
||||||
JPNR,
|
JPNR,
|
||||||
|
RETN,
|
||||||
SHIT,
|
SHIT,
|
||||||
NOPE,
|
NOPE,
|
||||||
GRMN,
|
GRMN,
|
||||||
@ -96,6 +97,7 @@ INSTRUCTION SIZES
|
|||||||
#define JPER_SIZE REGONLY
|
#define JPER_SIZE REGONLY
|
||||||
#define JPNI_SIZE IMMONLY
|
#define JPNI_SIZE IMMONLY
|
||||||
#define JPNR_SIZE REGONLY
|
#define JPNR_SIZE REGONLY
|
||||||
|
#define RETN_SIZE SINGLE
|
||||||
#define SHIT_SIZE SINGLE
|
#define SHIT_SIZE SINGLE
|
||||||
#define NOPE_SIZE SINGLE
|
#define NOPE_SIZE SINGLE
|
||||||
#define GRMN_SIZE SINGLE
|
#define GRMN_SIZE SINGLE
|
30
vm/vm.cpp
30
vm/vm.cpp
@ -70,8 +70,8 @@ uint8_t *VM::getRegName(uint8_t regvalue) {
|
|||||||
case IP:
|
case IP:
|
||||||
memcpy(buf, "IP", 2);
|
memcpy(buf, "IP", 2);
|
||||||
break;
|
break;
|
||||||
case BP:
|
case RP:
|
||||||
memcpy(buf, "BP", 2);
|
memcpy(buf, "RP", 2);
|
||||||
break;
|
break;
|
||||||
case SP:
|
case SP:
|
||||||
memcpy(buf, "SP", 2);
|
memcpy(buf, "SP", 2);
|
||||||
@ -118,8 +118,8 @@ void VM::status(void) {
|
|||||||
case IP:
|
case IP:
|
||||||
DBG_INFO(("IP:\t0x%x\n", this->regs[i]));
|
DBG_INFO(("IP:\t0x%x\n", this->regs[i]));
|
||||||
break;
|
break;
|
||||||
case BP:
|
case RP:
|
||||||
DBG_INFO(("BP:\t0x%x\n", this->regs[i]));
|
DBG_INFO(("RP:\t0x%x\n", this->regs[i]));
|
||||||
break;
|
break;
|
||||||
case SP:
|
case SP:
|
||||||
DBG_INFO(("SP:\t0x%x\n", this->regs[i]));
|
DBG_INFO(("SP:\t0x%x\n", this->regs[i]));
|
||||||
@ -535,6 +535,7 @@ bool VM::execJMPI(void) {
|
|||||||
|
|
||||||
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JMPI 0x%x\n", imm));
|
DBG_INFO(("JMPI 0x%x\n", imm));
|
||||||
|
regs[RP] = regs[IP] + 3;
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -546,6 +547,7 @@ bool VM::execJMPR(void) {
|
|||||||
|
|
||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JMPR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
DBG_INFO(("JMPR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = regs[reg];
|
regs[IP] = regs[reg];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -558,6 +560,7 @@ bool VM::execJPAI(void) {
|
|||||||
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPAI 0x%x\n", imm));
|
DBG_INFO(("JPAI 0x%x\n", imm));
|
||||||
if (flags.CF == 1) {
|
if (flags.CF == 1) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -572,6 +575,7 @@ bool VM::execJPAR(void) {
|
|||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPAR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
DBG_INFO(("JPAR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
if (flags.CF == 1) {
|
if (flags.CF == 1) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = reg;
|
regs[IP] = reg;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -586,9 +590,12 @@ bool VM::execJPBI(void) {
|
|||||||
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPBI 0x%x\n", imm));
|
DBG_INFO(("JPBI 0x%x\n", imm));
|
||||||
if (flags.CF == 0) {
|
if (flags.CF == 0) {
|
||||||
|
regs[RP] = regs[IP] + 3;
|
||||||
|
printf("IP: 0x%x | RP: 0x%x\n", regs[IP], regs[RP]);
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
printf("YO");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool VM::execJPBR(void) {
|
bool VM::execJPBR(void) {
|
||||||
@ -600,6 +607,7 @@ bool VM::execJPBR(void) {
|
|||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPBR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
DBG_INFO(("JPBR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
if (flags.CF == 0) {
|
if (flags.CF == 0) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = reg;
|
regs[IP] = reg;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -614,6 +622,7 @@ bool VM::execJPEI(void) {
|
|||||||
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPEI 0x%x\n", imm));
|
DBG_INFO(("JPEI 0x%x\n", imm));
|
||||||
if (flags.ZF == 1) {
|
if (flags.ZF == 1) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -628,6 +637,7 @@ bool VM::execJPER(void) {
|
|||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPER %s = 0x%x\n", getRegName(reg), regs[reg]));
|
DBG_INFO(("JPER %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
if (flags.ZF == 1) {
|
if (flags.ZF == 1) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = reg;
|
regs[IP] = reg;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -642,6 +652,7 @@ bool VM::execJPNI(void) {
|
|||||||
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
imm = *(uint16_t *)&as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPNI 0x%x\n", imm));
|
DBG_INFO(("JPNI 0x%x\n", imm));
|
||||||
if (flags.ZF == 0) {
|
if (flags.ZF == 0) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -656,11 +667,19 @@ bool VM::execJPNR(void) {
|
|||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("JPNR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
DBG_INFO(("JPNR %s = 0x%x\n", getRegName(reg), regs[reg]));
|
||||||
if (flags.ZF == 0) {
|
if (flags.ZF == 0) {
|
||||||
|
regs[RP] = regs[IP] + 2;
|
||||||
regs[IP] = reg;
|
regs[IP] = reg;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool VM::execRETN(void) {
|
||||||
|
/*
|
||||||
|
RETN -> IP = RP , restores saved return IP
|
||||||
|
*/
|
||||||
|
DBG_INFO(("RETN 0x%x\n", regs[RP]));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool VM::execGRMN(void) {
|
bool VM::execGRMN(void) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < NUM_REGS; i++) {
|
for (i = 0; i < NUM_REGS; i++) {
|
||||||
@ -784,6 +803,9 @@ void VM::run(void) {
|
|||||||
if (!execJPNR()) {
|
if (!execJPNR()) {
|
||||||
regs[IP] += JPNR_SIZE;
|
regs[IP] += JPNR_SIZE;
|
||||||
}
|
}
|
||||||
|
} else if (opcode == OPS[RETN]) {
|
||||||
|
execRETN();
|
||||||
|
regs[IP] = regs[RP];
|
||||||
} else if (opcode == OPS[GRMN]) {
|
} else if (opcode == OPS[GRMN]) {
|
||||||
execGRMN();
|
execGRMN();
|
||||||
regs[IP] += GRMN_SIZE;
|
regs[IP] += GRMN_SIZE;
|
||||||
|
3
vm/vm.h
3
vm/vm.h
@ -3,7 +3,7 @@
|
|||||||
#include "vmas.h"
|
#include "vmas.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS };
|
enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, RP, SP, NUM_REGS };
|
||||||
typedef struct flags {
|
typedef struct flags {
|
||||||
uint8_t ZF : 1;
|
uint8_t ZF : 1;
|
||||||
uint8_t CF : 1;
|
uint8_t CF : 1;
|
||||||
@ -68,6 +68,7 @@ private:
|
|||||||
bool execJPER(void);
|
bool execJPER(void);
|
||||||
bool execJPNI(void);
|
bool execJPNI(void);
|
||||||
bool execJPNR(void);
|
bool execJPNR(void);
|
||||||
|
bool execRETN(void);
|
||||||
bool execGRMN(void);
|
bool execGRMN(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user