reg2reg assembler
This commit is contained in:
parent
56b8a9c407
commit
ffb11f9a2e
@ -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 <opcodes_key> <program>\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;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
MEMORY LOCATIONS AND IMMEDIATES ARE 16 BITS LONG
|
||||
*/
|
||||
enum ops_starting_values {
|
||||
enum OPS_STARTING_VALUES {
|
||||
MOVI,
|
||||
MOVR,
|
||||
LOAD,
|
||||
|
43
cpp/vm.cpp
43
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;
|
||||
|
22
cpp/vm.h
22
cpp/vm.h
@ -3,7 +3,6 @@
|
||||
#include "vmas.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
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();
|
||||
};
|
||||
|
@ -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("<B", dst_reg.uint8()[0] << 4 ^ (
|
||||
src_reg.uint8()[0] & 0b00001111))
|
||||
self.assembled_code += opcode.uint8() + byte_with_nibbles
|
||||
return
|
||||
|
||||
def reg2imm(self, instruction):
|
||||
@ -125,6 +143,9 @@ class VMAssembler:
|
||||
def op_addi(self, instruction):
|
||||
self.imm2reg(instruction)
|
||||
|
||||
def op_addr(self, instruction):
|
||||
self.reg2reg(instruction)
|
||||
|
||||
def define_ops(self, key):
|
||||
key_ba = bytearray(key, 'utf-8')
|
||||
olds = copy.deepcopy(ops)
|
||||
@ -281,7 +302,8 @@ def assemble_data(line):
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: {} opcodes_key file_to_assemble output".format(sys.argv[0]))
|
||||
print("Usage: {} opcodes_key file_to_assemble output".format(
|
||||
sys.argv[0]))
|
||||
return
|
||||
vma = VMAssembler(sys.argv[1])
|
||||
with open(sys.argv[2], 'r') as f:
|
||||
|
Loading…
Reference in New Issue
Block a user