From 07b9de5f2a3ccf7a30f7d7bb6bafa94d73e97248 Mon Sep 17 00:00:00 2001 From: Giulio De Pasquale Date: Fri, 19 May 2017 12:23:18 +0200 Subject: [PATCH] Assemblaggio label corretto. BUGGATO A BESTIA --- assembler/assembler.py | 46 ++++++++++++++++++++++++++++++++++-------- vm/opcodes.h | 2 ++ vm/vm.cpp | 30 +++++++++++++++++++++++---- vm/vm.h | 3 ++- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/assembler/assembler.py b/assembler/assembler.py index 8e1a84f..76c8968 100644 --- a/assembler/assembler.py +++ b/assembler/assembler.py @@ -310,19 +310,27 @@ class VMSection: Represents a code section or "label" such as "main:" """ - def __init__(self, name): + def __init__(self, name, line_start): self.name = name self.size = 0 self.offset = 0 + self.line_start = line_start + self.line_end = 0 def set_size(self, size): self.size = size def set_offset(self, 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): - 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"], ["MOVR", "reg2reg"], @@ -360,6 +368,7 @@ op_names = [["MOVI", "imm2reg"], ["JPER", "jump"], ["JPNI", "jump"], ["JPNR", "jump"], + ["RETN", "single"], ["SHIT", "single"], ["NOPE", "single"], ["GRMN", "single"]] @@ -376,13 +385,29 @@ register_re = re.compile("(^[rRsS]{1}[0-9]{1}$)|([iIbBsS]{1}[pP]{1}$)") def parse_sections(lines): current_size = 0 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: if section_re.match(line): if current_section: tmp = next(x for x in sections if x.name == current_section) tmp.set_size(current_size) current_section = line.casefold()[:-1] - sections.append(VMSection(current_section)) current_size = 0 continue 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.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(): current_offset = 0 @@ -417,11 +448,10 @@ def main(): if "main" not in [x.name for x in sections]: sys.stderr.write("No main specified!") return - - calc_section_offsets() - - for line in filedata: - if not section_re.match(line): + + for s in sections: + section_code = filedata[s.line_start:s.line_end+1] + for line in section_code: vma.process_code_line(line) with open(sys.argv[3], 'wb') as f: diff --git a/vm/opcodes.h b/vm/opcodes.h index cc83155..a0b1f13 100644 --- a/vm/opcodes.h +++ b/vm/opcodes.h @@ -38,6 +38,7 @@ enum OPS_STARTING_VALUES { JPER, JPNI, JPNR, + RETN, SHIT, NOPE, GRMN, @@ -96,6 +97,7 @@ INSTRUCTION SIZES #define JPER_SIZE REGONLY #define JPNI_SIZE IMMONLY #define JPNR_SIZE REGONLY +#define RETN_SIZE SINGLE #define SHIT_SIZE SINGLE #define NOPE_SIZE SINGLE #define GRMN_SIZE SINGLE \ No newline at end of file diff --git a/vm/vm.cpp b/vm/vm.cpp index ab8de99..56b1595 100644 --- a/vm/vm.cpp +++ b/vm/vm.cpp @@ -70,8 +70,8 @@ uint8_t *VM::getRegName(uint8_t regvalue) { case IP: memcpy(buf, "IP", 2); break; - case BP: - memcpy(buf, "BP", 2); + case RP: + memcpy(buf, "RP", 2); break; case SP: memcpy(buf, "SP", 2); @@ -118,8 +118,8 @@ void VM::status(void) { case IP: DBG_INFO(("IP:\t0x%x\n", this->regs[i])); break; - case BP: - DBG_INFO(("BP:\t0x%x\n", this->regs[i])); + case RP: + DBG_INFO(("RP:\t0x%x\n", this->regs[i])); break; case SP: 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]; DBG_INFO(("JMPI 0x%x\n", imm)); + regs[RP] = regs[IP] + 3; regs[IP] = imm; return true; } @@ -546,6 +547,7 @@ bool VM::execJMPR(void) { reg = as.code[regs[IP] + 1]; DBG_INFO(("JMPR %s = 0x%x\n", getRegName(reg), regs[reg])); + regs[RP] = regs[IP] + 2; regs[IP] = regs[reg]; return true; } @@ -558,6 +560,7 @@ bool VM::execJPAI(void) { imm = *(uint16_t *)&as.code[regs[IP] + 1]; DBG_INFO(("JPAI 0x%x\n", imm)); if (flags.CF == 1) { + regs[RP] = regs[IP] + 2; regs[IP] = imm; return true; } @@ -572,6 +575,7 @@ bool VM::execJPAR(void) { reg = as.code[regs[IP] + 1]; DBG_INFO(("JPAR %s = 0x%x\n", getRegName(reg), regs[reg])); if (flags.CF == 1) { + regs[RP] = regs[IP] + 2; regs[IP] = reg; return true; } @@ -586,9 +590,12 @@ bool VM::execJPBI(void) { imm = *(uint16_t *)&as.code[regs[IP] + 1]; DBG_INFO(("JPBI 0x%x\n", imm)); if (flags.CF == 0) { + regs[RP] = regs[IP] + 3; + printf("IP: 0x%x | RP: 0x%x\n", regs[IP], regs[RP]); regs[IP] = imm; return true; } + printf("YO"); return false; } bool VM::execJPBR(void) { @@ -600,6 +607,7 @@ bool VM::execJPBR(void) { reg = as.code[regs[IP] + 1]; DBG_INFO(("JPBR %s = 0x%x\n", getRegName(reg), regs[reg])); if (flags.CF == 0) { + regs[RP] = regs[IP] + 2; regs[IP] = reg; return true; } @@ -614,6 +622,7 @@ bool VM::execJPEI(void) { imm = *(uint16_t *)&as.code[regs[IP] + 1]; DBG_INFO(("JPEI 0x%x\n", imm)); if (flags.ZF == 1) { + regs[RP] = regs[IP] + 2; regs[IP] = imm; return true; } @@ -628,6 +637,7 @@ bool VM::execJPER(void) { reg = as.code[regs[IP] + 1]; DBG_INFO(("JPER %s = 0x%x\n", getRegName(reg), regs[reg])); if (flags.ZF == 1) { + regs[RP] = regs[IP] + 2; regs[IP] = reg; return true; } @@ -642,6 +652,7 @@ bool VM::execJPNI(void) { imm = *(uint16_t *)&as.code[regs[IP] + 1]; DBG_INFO(("JPNI 0x%x\n", imm)); if (flags.ZF == 0) { + regs[RP] = regs[IP] + 2; regs[IP] = imm; return true; } @@ -656,11 +667,19 @@ bool VM::execJPNR(void) { reg = as.code[regs[IP] + 1]; DBG_INFO(("JPNR %s = 0x%x\n", getRegName(reg), regs[reg])); if (flags.ZF == 0) { + regs[RP] = regs[IP] + 2; regs[IP] = reg; return true; } 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) { uint8_t i; for (i = 0; i < NUM_REGS; i++) { @@ -784,6 +803,9 @@ void VM::run(void) { if (!execJPNR()) { regs[IP] += JPNR_SIZE; } + } else if (opcode == OPS[RETN]) { + execRETN(); + regs[IP] = regs[RP]; } else if (opcode == OPS[GRMN]) { execGRMN(); regs[IP] += GRMN_SIZE; diff --git a/vm/vm.h b/vm/vm.h index d57af66..cab22ae 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -3,7 +3,7 @@ #include "vmas.h" #include -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 { uint8_t ZF : 1; uint8_t CF : 1; @@ -68,6 +68,7 @@ private: bool execJPER(void); bool execJPNI(void); bool execJPNR(void); + bool execRETN(void); bool execGRMN(void); public: