96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
asm = open("instructions", "r").read().split("\n")
|
|
asm = [[int(part, 16) if part[:2] == "0x" else part for part in instruction.split("#")[0].strip().split()] for instruction in asm if len(instruction) > 0]
|
|
rs = dict([[item, 0] for item in ["ax", "bx", "cx", "dx", "ip", "sp", "sb", "fl"]])
|
|
ram = [0 for i in range(1024)]
|
|
|
|
def debug():
|
|
# prints the registers and the first 10 values in ram
|
|
print("Registers: " + str(rs));
|
|
i = len(ram) - 1
|
|
while ram[i] == 0: i -= 1
|
|
print("Ram: " + str(ram[:i+1])[:-1] + ", ...]")
|
|
def handle_three(i):
|
|
instruction = i[0]
|
|
first = i[1]
|
|
second = i[2]
|
|
if instruction == "add": rs[second] += rs[first]
|
|
if instruction == "addi": rs[second] += first
|
|
if instruction == "sub": rs[second] -= rs[first]
|
|
if instruction == "subi": rs[second] -= first
|
|
if instruction == "ls": rs[second] <<= rs[first]
|
|
if instruction == "lsi": rs[second] <<= first
|
|
if instruction == "rs": rs[second] >>= rs[first]
|
|
if instruction == "rsi": rs[second] >>= first
|
|
if instruction == "xor": rs[second] ^= rs[first]
|
|
if instruction == "xori": rs[second] ^= first
|
|
if instruction == "and": rs[second] &= rs[first]
|
|
if instruction == "andi": rs[second] &= first
|
|
if instruction == "mov": rs[second] = rs[first]
|
|
if instruction == "movi": rs[second] = first
|
|
if instruction == "test":
|
|
if rs[second] == rs[first]: rs["fl"] = 0b001
|
|
elif rs[second] < rs[first]: rs["fl"] = 0b010
|
|
else: rs["fl"] = 0b100
|
|
if instruction == "testi":
|
|
if rs[second] == first: rs["fl"] = 0b001
|
|
elif rs[second] < first: rs["fl"] = 0b010
|
|
else: rs["fl"] = 0b100
|
|
if instruction == "lea": rs[second] = ram[rs[first]]
|
|
if instruction == "leai": rs[second] = ram[first]
|
|
if instruction == "sea": ram[rs[first]] = rs[second]
|
|
if instruction == "seai": ram[first] = rs[second]
|
|
def handle_two(i):
|
|
instruction = i[0]
|
|
arg = i[1]
|
|
if instruction == "call":
|
|
handle_two(["pushi", rs["ip"]])
|
|
instruction = "jmp"
|
|
if instruction == "je":
|
|
if rs["fl"] & 0b001 > 0: instruction = "jmp"
|
|
if instruction == "jne":
|
|
if rs["fl"] & 0b001 == 0: instruction = "jmp"
|
|
if instruction == "jl":
|
|
if rs["fl"] & 0b100 > 0: instruction = "jmp"
|
|
if instruction == "jle":
|
|
if rs["fl"] & 0b101 > 0: instruction = "jmp"
|
|
if instruction == "jg":
|
|
if rs["fl"] & 0b010 > 0: instruction = "jmp"
|
|
if instruction == "jge":
|
|
if rs["fl"] & 0b011 > 0: instruction = "jmp"
|
|
if instruction == "jmp":
|
|
rs["ip"] = asm.index([arg + ":"]) - 1
|
|
if instruction == "push":
|
|
ram[rs["sp"]] = rs[arg]
|
|
rs["sp"] += 1
|
|
if instruction == "pushi":
|
|
ram[rs["sp"]] = arg
|
|
rs["sp"] += 1
|
|
if instruction == "pop":
|
|
rs["sp"] -= 1
|
|
rs[arg] = ram[rs["sp"]]
|
|
|
|
while True:
|
|
if rs["ip"] >= len(asm):
|
|
print("Out of instructions")
|
|
break;
|
|
instruction = asm[rs["ip"]]
|
|
if len(instruction) == 3: handle_three(instruction)
|
|
elif len(instruction) == 2: handle_two(instruction)
|
|
elif len(instruction) == 1:
|
|
instruction = instruction[0]
|
|
if instruction == "debug":
|
|
debug()
|
|
if instruction == "abort":
|
|
print("Aborted at " + str(rs["ip"]))
|
|
break
|
|
if instruction == "ret":
|
|
rs["sp"] -= 1
|
|
rs["ip"] = ram[rs["sp"]]
|
|
elif len(instruction) != 0:
|
|
print("Found suspiciously long instruction \"" + " ".join(instruction) + "\"")
|
|
rs["ip"] += 1
|
|
if rs["sp"] != 0:
|
|
print("WARNING - Stack was not empty at program exit")
|
|
debug()
|