diff --git a/cpp/emulator.cpp b/cpp/emulator.cpp index 2705e0b..ad91509 100644 --- a/cpp/emulator.cpp +++ b/cpp/emulator.cpp @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { std::ifstream bytecode_if; std::streamsize bytecode_size; - uint8_t * bytecode; + uint8_t *bytecode; if (argc < 3) { printf("Usage: %s \n", argv[0]); @@ -23,8 +23,8 @@ int main(int argc, char *argv[]) { bytecode_if.seekg(0, std::ios::beg); bytecode = new uint8_t[bytecode_size]; - bytecode_if.read((char*)bytecode, bytecode_size); - VM vm((uint8_t*)argv[1], bytecode, bytecode_size); + bytecode_if.read((char *)bytecode, bytecode_size); + VM vm((uint8_t *)argv[1], bytecode, bytecode_size); vm.run(); vm.status(); return 0; diff --git a/cpp/opcodes.h b/cpp/opcodes.h index a2b2def..76cc530 100644 --- a/cpp/opcodes.h +++ b/cpp/opcodes.h @@ -1,7 +1,7 @@ /* MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG */ -enum ops_starting_values { +enum OPS_STARTING_VALUES { MOVI, MOVR, LOAD, diff --git a/cpp/vm.cpp b/cpp/vm.cpp index 723f9fc..f5193bc 100644 --- a/cpp/vm.cpp +++ b/cpp/vm.cpp @@ -40,7 +40,7 @@ void VM::defineOpcodes(uint8_t *key) { DBG UTILS */ -uint8_t *VM::reg_name(uint8_t regvalue) { +uint8_t *VM::getRegName(uint8_t regvalue) { uint8_t *buf = new uint8_t[2]; #ifdef DBG switch (regvalue) { @@ -166,7 +166,7 @@ void VM::initVariables(void) { INSTRUCTIONS IMPLEMENTATIONS */ -bool VM::exec_movi(void) { +bool VM::execMOVI(void) { /* MOVI R0, 0x2400 | R0 = 0x2400 */ @@ -174,7 +174,7 @@ bool VM::exec_movi(void) { uint16_t imm; dst = as.code[regs[IP] + 1]; imm = *((uint16_t *)&as.code[regs[IP] + 2]); - DBG_INFO(("MOVI %s, 0x%x\n", reg_name(dst), imm)); + DBG_INFO(("MOVI %s, 0x%x\n", getRegName(dst), imm)); if (dst == IP) { DBG_ERROR(("Can't MOVI to IP!\n")); return false; @@ -183,7 +183,7 @@ bool VM::exec_movi(void) { return true; } -bool VM::exec_movr(void) { +bool VM::execMOVR(void) { /* MOVR R1, R0 | R1 = R0 --------------------- @@ -192,7 +192,7 @@ bool VM::exec_movr(void) { uint8_t dst, src; dst = as.code[regs[IP] + 1] >> 4; src = as.code[regs[IP] + 1] & 0b00001111; - DBG_INFO(("MOVR %s, %s\n", reg_name(dst), reg_name(src))); + DBG_INFO(("MOVR %s, %s\n", getRegName(dst), getRegName(src))); if (dst == IP || src == IP) { DBG_ERROR(("Can't MOVR IP!\n")); return false; @@ -201,7 +201,7 @@ bool VM::exec_movr(void) { return true; } -bool VM::exec_load(void) { +bool VM::execLOAD(void) { /* LOAD R0, 0x1000 | R0 = data[0x1000] */ @@ -209,12 +209,12 @@ bool VM::exec_load(void) { uint16_t src; dst = as.code[regs[IP] + 1]; src = *((uint16_t *)&as.code[regs[IP] + 2]); - DBG_INFO(("LOAD %s, 0x%x\n", reg_name(dst), src)); + DBG_INFO(("LOAD %s, 0x%x\n", getRegName(dst), src)); regs[dst] = *((uint16_t *)&as.data[src]); return true; } -bool VM::exec_stor(void) { +bool VM::execSTOR(void) { /* STOR 0x1000, R0 | data[0x1000] = R0 */ @@ -222,12 +222,12 @@ bool VM::exec_stor(void) { uint8_t src; dst = *((uint16_t *)&as.code[regs[IP] + 1]); src = as.code[regs[IP] + 3]; - DBG_INFO(("STOR 0x%x, %s\n", dst, reg_name(src))); + DBG_INFO(("STOR 0x%x, %s\n", dst, getRegName(src))); *((uint16_t *)&as.data[dst]) = regs[src]; return true; } -bool VM::exec_addi(void) { +bool VM::execADDI(void) { /* ADDI R0, 0x2 | R0 += 2 */ @@ -236,30 +236,41 @@ bool VM::exec_addi(void) { dst = as.code[regs[IP] + 1]; src = *((uint16_t *)&as.code[regs[IP] + 2]); - DBG_INFO(("ADDI %s, 0x%x\n", reg_name(dst), src)); + DBG_INFO(("ADDI %s, 0x%x\n", getRegName(dst), src)); regs[dst] += src; return true; } +void VM::execADDR(void) { + uint8_t dst; + uint8_t src; + + dst = as.code[regs[IP] + 1] >> 4; + src = as.code[regs[IP] + 1] & 0b00001111; + DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src)); + regs[dst] += regs[src]; + return; +} + void VM::run(void) { uint8_t opcode; bool finished = false; while (!finished) { opcode = (uint8_t)as.code[regs[IP]]; if (opcode == OPS[MOVI]) { - exec_movi(); + execMOVI(); regs[IP] += MOVI_SIZE; } else if (opcode == OPS[MOVR]) { - exec_movr(); + execMOVR(); regs[IP] += MOVR_SIZE; } else if (opcode == OPS[LOAD]) { - exec_load(); + execLOAD(); regs[IP] += LOAD_SIZE; } else if (opcode == OPS[STOR]) { - exec_stor(); + execSTOR(); regs[IP] += STOR_SIZE; } else if (opcode == OPS[ADDI]) { - exec_addi(); + execADDI(); regs[IP] += ADDI_SIZE; } else if (opcode == OPS[SHIT]) { finished = true; diff --git a/cpp/vm.h b/cpp/vm.h index 2b11483..21a0195 100644 --- a/cpp/vm.h +++ b/cpp/vm.h @@ -3,7 +3,6 @@ #include "vmas.h" #include - enum regs { R0, R1, R2, R3, S0, S1, S2, S3, IP, BP, SP, NUM_REGS }; class VM { @@ -23,24 +22,25 @@ private: // FUNCTIONS /////////////////////// void initVariables(void); - void defineOpcodes(uint8_t * key); + void defineOpcodes(uint8_t *key); /* DBG UTILS */ - uint8_t *reg_name(uint8_t); + uint8_t *getRegName(uint8_t); /* IMPLEMENTATIONS */ - bool exec_movi(void); - bool exec_movr(void); - bool exec_movm(void); - bool exec_load(void); - bool exec_stor(void); - bool exec_addi(void); + bool execMOVI(void); + bool execMOVR(void); + bool execMOVM(void); + bool execLOAD(void); + bool execSTOR(void); + bool execADDI(void); + void execADDR(void); public: - VM(uint8_t * key); - VM(uint8_t * key, uint8_t *code, uint32_t codesize); + VM(uint8_t *key); + VM(uint8_t *key, uint8_t *code, uint32_t codesize); void status(void); void run(); }; diff --git a/python/assembler.py b/python/assembler.py index 738c652..95825ab 100644 --- a/python/assembler.py +++ b/python/assembler.py @@ -48,8 +48,9 @@ class InvalidValue(AssemblerException): super().__init__("Invalid value while assembling: {}".format(instruction)) rol = lambda val, r_bits, max_bits: \ - (val << r_bits%max_bits) & (2**max_bits-1) | \ - ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits))) + (val << r_bits % max_bits) & (2**max_bits - 1) | \ + ((val & (2**max_bits - 1)) >> (max_bits - (r_bits % max_bits))) + class VMAssembler: @@ -87,6 +88,23 @@ class VMAssembler: return def reg2reg(self, instruction): + """ + Intel syntax -> DST_REG, SRC_REG + """ + opcode = instruction.opcode + dst_reg = instruction.args[0] + src_reg = instruction.args[1] + if dst_reg.name == "ip" or src_reg.name == "ip": + raise IPOverwrite(instruction) + if not dst_reg.isreg(): + raise ExpectedRegister(dst_reg) + if not src_reg.isreg(): + raise ExpectedRegister(src_reg) + if not opcode.uint8() or not dst_reg.uint8() or not src_reg.uint8(): + raise InvalidValue(instruction) + byte_with_nibbles = struct.pack("