CALL + fix vari
This commit is contained in:
parent
9b5d5647a9
commit
e518029485
@ -56,6 +56,9 @@ class VMAssembler:
|
|||||||
self.functions = []
|
self.functions = []
|
||||||
self.decrypt_ops(key)
|
self.decrypt_ops(key)
|
||||||
self.parse_functions()
|
self.parse_functions()
|
||||||
|
self.resolve_functions_offsets()
|
||||||
|
self.resolve_symbols()
|
||||||
|
self.disassembly()
|
||||||
main = next((x for x in self.functions if x.name == "main"), None)
|
main = next((x for x in self.functions if x.name == "main"), None)
|
||||||
if main == None:
|
if main == None:
|
||||||
print("Main has to be defined")
|
print("Main has to be defined")
|
||||||
@ -85,20 +88,46 @@ class VMAssembler:
|
|||||||
i] = self.functions[i], self.functions[0]
|
i] = self.functions[i], self.functions[0]
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def resolve_functions_offsets(self):
|
||||||
# calculating functions offsets
|
# calculating functions offsets
|
||||||
for i in range(1, len(self.functions)):
|
for i in range(1, len(self.functions)):
|
||||||
prev_fun_tot_size = self.functions[
|
prev_fun_tot_size = self.functions[
|
||||||
i - 1].size + self.functions[i - 1].offset
|
i - 1].size() + self.functions[i - 1].offset
|
||||||
cur_fun_size = self.functions[i].size
|
|
||||||
self.functions[i].set_offset(prev_fun_tot_size)
|
self.functions[i].set_offset(prev_fun_tot_size)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def resolve_symbols(self):
|
||||||
|
for f in self.functions:
|
||||||
|
for i in f.instructions:
|
||||||
|
symcall = symcall_re.match(str(i))
|
||||||
|
if symcall:
|
||||||
|
symname = symcall.group(1)
|
||||||
|
|
||||||
|
# checking if it's a jump to a label
|
||||||
|
if symname in [y.label for x in self.functions for y in x.instructions]:
|
||||||
|
fun = next(
|
||||||
|
(x for x in self.functions for y in x.instructions if symname == y.label), None)
|
||||||
|
offset = f.offset_of_label(symname) + f.offset
|
||||||
|
# function
|
||||||
|
elif symname in [x.name for x in self.functions]:
|
||||||
|
offset = next(
|
||||||
|
(x.offset for x in self.functions if x.name == symname), None)
|
||||||
|
else:
|
||||||
|
print("SYMBOL \"{}\" NOT FOUND!".format(symname))
|
||||||
|
i.args[0].set_value(offset)
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
for f in self.functions:
|
for f in self.functions:
|
||||||
for i in f.instructions:
|
for i in f.instructions:
|
||||||
action = getattr(self, "{}".format(i.opcode.method))
|
action = getattr(self, "{}".format(i.opcode.method))
|
||||||
action(i)
|
action(i)
|
||||||
|
|
||||||
|
def disassembly(self):
|
||||||
|
for f in self.functions:
|
||||||
|
print("FUNCTION {}".format(f.name))
|
||||||
|
for idx, ins in enumerate(f.instructions):
|
||||||
|
print("{}:\t{}".format(hex(f.offset_of_instruction(idx)), ins))
|
||||||
|
|
||||||
def imm2reg(self, instruction):
|
def imm2reg(self, instruction):
|
||||||
"""
|
"""
|
||||||
Intel syntax -> REG, IMM
|
Intel syntax -> REG, IMM
|
||||||
@ -202,29 +231,11 @@ class VMAssembler:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def jump(self, instruction):
|
def jump(self, instruction):
|
||||||
imm_op_re = re.compile(".*[iI]$")
|
imm_op_re = re.compile("^([cC][aA][lL]{2})$|(.*[iI])$")
|
||||||
reg_op_re = re.compile(".*[rR]$")
|
reg_op_re = re.compile(".*[rR]$")
|
||||||
symcall = symcall_re.match(str(instruction))
|
symcall = symcall_re.match(str(instruction))
|
||||||
|
|
||||||
dst = instruction.args[0]
|
dst = instruction.args[0]
|
||||||
# let's check if the jump is to a label or a function
|
print(instruction)
|
||||||
if symcall:
|
|
||||||
# the symbal has not been resolved
|
|
||||||
if dst.name == dst.value:
|
|
||||||
# check whether it is a function
|
|
||||||
val = next(
|
|
||||||
(x.offset for x in self.functions if x.name == dst.name), None)
|
|
||||||
# check whether it is a label
|
|
||||||
if val == None:
|
|
||||||
for f in self.functions:
|
|
||||||
for i in f.instructions:
|
|
||||||
if i.label == dst.name:
|
|
||||||
val = f.offset_of_label(dst) + f.offset
|
|
||||||
|
|
||||||
if val == None:
|
|
||||||
raise AssemblerException()
|
|
||||||
# resolving the symbol
|
|
||||||
instruction.args[0].set_value(val)
|
|
||||||
# define the kind of jump: to immediate or to register
|
# define the kind of jump: to immediate or to register
|
||||||
if imm_op_re.match(instruction.opcode.name):
|
if imm_op_re.match(instruction.opcode.name):
|
||||||
self.immonly(instruction)
|
self.immonly(instruction)
|
||||||
@ -263,7 +274,6 @@ class VMFunction:
|
|||||||
|
|
||||||
def __init__(self, name, code):
|
def __init__(self, name, code):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.size = 0
|
|
||||||
self.offset = 0
|
self.offset = 0
|
||||||
self.instructions = []
|
self.instructions = []
|
||||||
|
|
||||||
@ -283,11 +293,12 @@ class VMFunction:
|
|||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
raise InvalidOperation(line)
|
raise InvalidOperation(line)
|
||||||
self.calc_size()
|
|
||||||
|
|
||||||
def calc_size(self):
|
def size(self):
|
||||||
|
size = 0
|
||||||
for i in self.instructions:
|
for i in self.instructions:
|
||||||
self.size += i.size
|
size += i.size
|
||||||
|
return size
|
||||||
|
|
||||||
def set_offset(self, offset):
|
def set_offset(self, offset):
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
@ -301,8 +312,16 @@ class VMFunction:
|
|||||||
|
|
||||||
return offset
|
return offset
|
||||||
|
|
||||||
|
def offset_of_instruction(self, idx):
|
||||||
|
offset = 0
|
||||||
|
for i, ins in enumerate(self.instructions):
|
||||||
|
if i == idx:
|
||||||
|
break
|
||||||
|
offset += ins.size
|
||||||
|
return offset
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "{}: size {}, offset {}".format(self.name, hex(self.size), hex(self.offset))
|
return "{}: size {}, offset {}".format(self.name, hex(self.size()), hex(self.offset))
|
||||||
|
|
||||||
|
|
||||||
class VMInstruction:
|
class VMInstruction:
|
||||||
@ -316,7 +335,7 @@ class VMInstruction:
|
|||||||
def __init__(self, line, label=None):
|
def __init__(self, line, label=None):
|
||||||
self.opcode = None
|
self.opcode = None
|
||||||
self.args = []
|
self.args = []
|
||||||
self.size = 1
|
self.size = 0
|
||||||
self.label = label
|
self.label = label
|
||||||
|
|
||||||
ins = instruction_re.match(line)
|
ins = instruction_re.match(line)
|
||||||
@ -326,13 +345,13 @@ class VMInstruction:
|
|||||||
self.opcode = next((x for x in ops if x.name == opcode), None)
|
self.opcode = next((x for x in ops if x.name == opcode), None)
|
||||||
if self.opcode == None:
|
if self.opcode == None:
|
||||||
raise InvalidOperation(opcode)
|
raise InvalidOperation(opcode)
|
||||||
|
self.size = ops_sizes[self.opcode.method]
|
||||||
args = [x for x in ins.groups()[1:] if x is not None]
|
args = [x for x in ins.groups()[1:] if x is not None]
|
||||||
|
print("OP: {} | ARGS: {} | SYMCALL: {}".format(self.opcode, args,symcall))
|
||||||
for a in args:
|
for a in args:
|
||||||
if immediate_re.match(a) or symcall:
|
if immediate_re.match(a) or symcall:
|
||||||
# directly append the immediate
|
# directly append the immediate
|
||||||
self.args.append(VMComponent(a, a))
|
self.args.append(VMComponent(a, a))
|
||||||
self.size += 2
|
|
||||||
continue
|
continue
|
||||||
elif register_re.match(a):
|
elif register_re.match(a):
|
||||||
# create a VM component for a register
|
# create a VM component for a register
|
||||||
@ -340,7 +359,6 @@ class VMInstruction:
|
|||||||
if reg == None:
|
if reg == None:
|
||||||
raise InvalidRegister(a)
|
raise InvalidRegister(a)
|
||||||
self.args.append(reg)
|
self.args.append(reg)
|
||||||
self.size += 1
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -436,7 +454,8 @@ op_names = [["MOVI", "imm2reg"],
|
|||||||
["SHRR", "reg2reg"],
|
["SHRR", "reg2reg"],
|
||||||
["PUSH", "regonly"],
|
["PUSH", "regonly"],
|
||||||
["POOP", "regonly"],
|
["POOP", "regonly"],
|
||||||
["CMPI", "imm2reg"],
|
["CMPB", "byt2reg"],
|
||||||
|
["CMPW", "imm2reg"],
|
||||||
["CMPR", "reg2reg"],
|
["CMPR", "reg2reg"],
|
||||||
["JMPI", "jump"],
|
["JMPI", "jump"],
|
||||||
["JMPR", "jump"],
|
["JMPR", "jump"],
|
||||||
@ -448,12 +467,21 @@ op_names = [["MOVI", "imm2reg"],
|
|||||||
["JPER", "jump"],
|
["JPER", "jump"],
|
||||||
["JPNI", "jump"],
|
["JPNI", "jump"],
|
||||||
["JPNR", "jump"],
|
["JPNR", "jump"],
|
||||||
|
["CALL", "jump"],
|
||||||
["RETN", "single"],
|
["RETN", "single"],
|
||||||
["SHIT", "single"],
|
["SHIT", "single"],
|
||||||
["NOPE", "single"],
|
["NOPE", "single"],
|
||||||
["GRMN", "single"]]
|
["GRMN", "single"]]
|
||||||
|
|
||||||
reg_names = ["R0", "R1", "R2", "R3", "S0", "S1", "S2", "S3", "IP", "BP", "SP"]
|
reg_names = ["R0", "R1", "R2", "R3", "S0", "S1", "S2", "S3", "IP", "RP", "SP"]
|
||||||
|
ops_sizes = {"reg2reg": 2,
|
||||||
|
"imm2reg": 4,
|
||||||
|
"reg2imm": 4,
|
||||||
|
"byt2reg": 3,
|
||||||
|
"regonly": 3,
|
||||||
|
"immonly": 3,
|
||||||
|
"jump": 3,
|
||||||
|
"single": 1}
|
||||||
ops = [VMComponent(le[0], i, le[1]) for i, le in enumerate(op_names)]
|
ops = [VMComponent(le[0], i, le[1]) for i, le in enumerate(op_names)]
|
||||||
regs = [VMComponent(s.casefold(), i) for i, s in enumerate(reg_names)]
|
regs = [VMComponent(s.casefold(), i) for i, s in enumerate(reg_names)]
|
||||||
instruction_re = re.compile(
|
instruction_re = re.compile(
|
||||||
@ -463,7 +491,7 @@ immediate_re = re.compile("(?:0x)?[0-9a-fA-F]+$")
|
|||||||
alpha_re = re.compile("^[a-zA-Z]*$")
|
alpha_re = re.compile("^[a-zA-Z]*$")
|
||||||
register_re = re.compile("(^[rRsS][0-4]$)|([iIrRsS][pP]$)")
|
register_re = re.compile("(^[rRsS][0-4]$)|([iIrRsS][pP]$)")
|
||||||
label_re = re.compile("^([a-zA-Z]+)\:$")
|
label_re = re.compile("^([a-zA-Z]+)\:$")
|
||||||
symcall_re = re.compile("^([jJ][pPmM][pPaAbBeEnN][iIrR])\ +([\w]*)$")
|
symcall_re = re.compile("^(?:[jJ][pPmM][pPaAbBeEnN][iIrR]|(?:[cC][aA][lL]{2}))\ +([\w]*)$")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -477,6 +505,7 @@ def main():
|
|||||||
filedata = [x.strip() for x in filedata if x.strip()]
|
filedata = [x.strip() for x in filedata if x.strip()]
|
||||||
|
|
||||||
vma = VMAssembler(sys.argv[1], filedata)
|
vma = VMAssembler(sys.argv[1], filedata)
|
||||||
|
print(vma.functions)
|
||||||
vma.parse()
|
vma.parse()
|
||||||
|
|
||||||
with open(sys.argv[3], 'wb') as f:
|
with open(sys.argv[3], 'wb') as f:
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
void encrypt(uint32_t *v, uint32_t *k) {
|
void encrypt(uint16_t *v, uint16_t *k) {
|
||||||
uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
|
uint16_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
|
||||||
//uint32_t delta = 0x9e3779b9; /* a key schedule constant */
|
//uint32_t delta = 0x9e3779b9; /* a key schedule constant */
|
||||||
uint16_t delta= 0x9e37;
|
uint16_t delta= 0x9e37;
|
||||||
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
|
uint16_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
|
||||||
for (i = 0; i < 32; i++) { /* basic cycle start */
|
for (i = 0; i < 64; i++) { /* basic cycle start */
|
||||||
sum += delta;
|
sum += delta;
|
||||||
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
|
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
|
||||||
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
|
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
|
||||||
@ -29,7 +29,7 @@ int main(int argc, char *argv[]) {
|
|||||||
buflen = strlen(argv[1]);
|
buflen = strlen(argv[1]);
|
||||||
buf = (uint8_t *)malloc(buflen);
|
buf = (uint8_t *)malloc(buflen);
|
||||||
memcpy(buf, argv[1], buflen);
|
memcpy(buf, argv[1], buflen);
|
||||||
encrypt((uint32_t *)buf, (uint32_t *)argv[2]);
|
encrypt((uint16_t *)buf, (uint16_t *)argv[2]);
|
||||||
printf("Result:\n");
|
printf("Result:\n");
|
||||||
for (i = 0; i < buflen; i++) {
|
for (i = 0; i < buflen; i++) {
|
||||||
printf("%02x", buf[i]);
|
printf("%02x", buf[i]);
|
||||||
|
@ -32,7 +32,8 @@ enum OPS_STARTING_VALUES {
|
|||||||
SHRR,
|
SHRR,
|
||||||
PUSH,
|
PUSH,
|
||||||
POOP,
|
POOP,
|
||||||
CMPI,
|
CMPB,
|
||||||
|
CMPW,
|
||||||
CMPR,
|
CMPR,
|
||||||
JMPI,
|
JMPI,
|
||||||
JMPR,
|
JMPR,
|
||||||
@ -44,6 +45,7 @@ enum OPS_STARTING_VALUES {
|
|||||||
JPER,
|
JPER,
|
||||||
JPNI,
|
JPNI,
|
||||||
JPNR,
|
JPNR,
|
||||||
|
CALL,
|
||||||
RETN,
|
RETN,
|
||||||
SHIT,
|
SHIT,
|
||||||
NOPE,
|
NOPE,
|
||||||
@ -97,7 +99,8 @@ INSTRUCTION SIZES
|
|||||||
#define SHRR_SIZE REG2REG
|
#define SHRR_SIZE REG2REG
|
||||||
#define PUSH_SIZE REGONLY
|
#define PUSH_SIZE REGONLY
|
||||||
#define POOP_SIZE REGONLY
|
#define POOP_SIZE REGONLY
|
||||||
#define CMPI_SIZE IMM2REG
|
#define CMPB_SIZE BYT2REG
|
||||||
|
#define CMPW_SIZE IMM2REG
|
||||||
#define CMPR_SIZE REG2REG
|
#define CMPR_SIZE REG2REG
|
||||||
#define JMPI_SIZE IMMONLY
|
#define JMPI_SIZE IMMONLY
|
||||||
#define JMPR_SIZE REGONLY
|
#define JMPR_SIZE REGONLY
|
||||||
|
67
vm/vm.cpp
67
vm/vm.cpp
@ -561,16 +561,38 @@ bool VM::execPOOP(void) {
|
|||||||
memcpy(®s[dst], &as.stack[regs[SP]], sizeof(uint16_t));
|
memcpy(®s[dst], &as.stack[regs[SP]], sizeof(uint16_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execCMPI(void) {
|
bool VM::execCMPB(void) {
|
||||||
/*
|
/*
|
||||||
CMPI R0, 0x2 -> Compare immediate with register
|
CMPB R0, 0x2 -> Compare immediate with lower half (BYTE) register
|
||||||
|
*/
|
||||||
|
uint8_t reg;
|
||||||
|
uint8_t imm;
|
||||||
|
|
||||||
|
reg = as.code[regs[IP] + 1];
|
||||||
|
imm = as.code[regs[IP] + 2];
|
||||||
|
DBG_INFO(("CMPB %s, 0x%x\n", getRegName(reg), imm));
|
||||||
|
if (*((uint8_t *)®s[reg]) == imm) {
|
||||||
|
flags.ZF = 1;
|
||||||
|
} else {
|
||||||
|
flags.ZF = 0;
|
||||||
|
}
|
||||||
|
if (*((uint8_t *)®s[reg]) > imm) {
|
||||||
|
flags.CF = 1;
|
||||||
|
} else {
|
||||||
|
flags.CF = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::execCMPW(void) {
|
||||||
|
/*
|
||||||
|
CMPW R0, 0x2 -> Compare immediate with whole (WORD) register
|
||||||
*/
|
*/
|
||||||
uint8_t reg;
|
uint8_t reg;
|
||||||
uint16_t imm;
|
uint16_t imm;
|
||||||
|
|
||||||
reg = as.code[regs[IP] + 1];
|
reg = as.code[regs[IP] + 1];
|
||||||
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
|
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("CMPI %s, 0x%x\n", getRegName(reg), imm));
|
DBG_INFO(("CMPW %s, 0x%x\n", getRegName(reg), imm));
|
||||||
if (regs[reg] == imm) {
|
if (regs[reg] == imm) {
|
||||||
flags.ZF = 1;
|
flags.ZF = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -613,7 +635,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -625,7 +646,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -638,7 +658,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -653,7 +672,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -668,7 +686,6 @@ 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;
|
|
||||||
regs[IP] = imm;
|
regs[IP] = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -683,7 +700,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -698,7 +714,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -713,7 +728,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -728,7 +742,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -743,17 +756,32 @@ 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::execCALL(void) {
|
||||||
|
/*
|
||||||
|
CALL 0x1000 -> Jump to data[0x1000] and saves the RP onto the stack
|
||||||
|
*/
|
||||||
|
uint16_t dst;
|
||||||
|
|
||||||
|
dst = *((uint16_t *)&as.code[regs[IP] + 1]);
|
||||||
|
DBG_INFO(("CALL 0x%x\n", dst));
|
||||||
|
*((uint16_t *)&as.stack[regs[SP]]) = regs[IP] + 3;
|
||||||
|
regs[SP] += sizeof(uint16_t);
|
||||||
|
regs[IP] = dst;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool VM::execRETN(void) {
|
bool VM::execRETN(void) {
|
||||||
/*
|
/*
|
||||||
RETN -> IP = RP , restores saved return IP
|
RETN -> IP = RP , restores saved return IP
|
||||||
*/
|
*/
|
||||||
|
regs[SP] -= sizeof(uint16_t);
|
||||||
|
regs[RP] = *((uint16_t *)&as.stack[regs[SP]]);
|
||||||
DBG_INFO(("RETN 0x%x\n", regs[RP]));
|
DBG_INFO(("RETN 0x%x\n", regs[RP]));
|
||||||
|
regs[IP] = regs[RP];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execGRMN(void) {
|
bool VM::execGRMN(void) {
|
||||||
@ -860,9 +888,12 @@ void VM::run(void) {
|
|||||||
} else if (opcode == OPS[POOP]) {
|
} else if (opcode == OPS[POOP]) {
|
||||||
execPOOP();
|
execPOOP();
|
||||||
regs[IP] += POOP_SIZE;
|
regs[IP] += POOP_SIZE;
|
||||||
} else if (opcode == OPS[CMPI]) {
|
} else if (opcode == OPS[CMPB]) {
|
||||||
execCMPI();
|
execCMPB();
|
||||||
regs[IP] += CMPI_SIZE;
|
regs[IP] += CMPB_SIZE;
|
||||||
|
} else if (opcode == OPS[CMPW]) {
|
||||||
|
execCMPW();
|
||||||
|
regs[IP] += CMPW_SIZE;
|
||||||
} else if (opcode == OPS[CMPR]) {
|
} else if (opcode == OPS[CMPR]) {
|
||||||
execCMPR();
|
execCMPR();
|
||||||
regs[IP] += CMPR_SIZE;
|
regs[IP] += CMPR_SIZE;
|
||||||
@ -902,6 +933,8 @@ void VM::run(void) {
|
|||||||
if (!execJPNR()) {
|
if (!execJPNR()) {
|
||||||
regs[IP] += JPNR_SIZE;
|
regs[IP] += JPNR_SIZE;
|
||||||
}
|
}
|
||||||
|
} else if (opcode == OPS[CALL]) {
|
||||||
|
execCALL();
|
||||||
} else if (opcode == OPS[RETN]) {
|
} else if (opcode == OPS[RETN]) {
|
||||||
execRETN();
|
execRETN();
|
||||||
regs[IP] = regs[RP];
|
regs[IP] = regs[RP];
|
||||||
@ -914,7 +947,7 @@ void VM::run(void) {
|
|||||||
} else if (opcode == OPS[NOPE]) {
|
} else if (opcode == OPS[NOPE]) {
|
||||||
regs[IP] += NOPE_SIZE;
|
regs[IP] += NOPE_SIZE;
|
||||||
} else {
|
} else {
|
||||||
DBG_ERROR(("WAT\n"));
|
DBG_ERROR(("WAT: 0x%x\n", as.code[regs[IP]]));
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
vm/vm.h
4
vm/vm.h
@ -62,7 +62,8 @@ private:
|
|||||||
bool execSHRR(void);
|
bool execSHRR(void);
|
||||||
bool execPUSH(void);
|
bool execPUSH(void);
|
||||||
bool execPOOP(void);
|
bool execPOOP(void);
|
||||||
bool execCMPI(void);
|
bool execCMPB(void);
|
||||||
|
bool execCMPW(void);
|
||||||
bool execCMPR(void);
|
bool execCMPR(void);
|
||||||
bool execJMPI(void);
|
bool execJMPI(void);
|
||||||
bool execJMPR(void);
|
bool execJMPR(void);
|
||||||
@ -74,6 +75,7 @@ private:
|
|||||||
bool execJPER(void);
|
bool execJPER(void);
|
||||||
bool execJPNI(void);
|
bool execJPNI(void);
|
||||||
bool execJPNR(void);
|
bool execJPNR(void);
|
||||||
|
bool execCALL(void);
|
||||||
bool execRETN(void);
|
bool execRETN(void);
|
||||||
bool execGRMN(void);
|
bool execGRMN(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user