Moved opcodes into their own file. Now the format is crazy extensible.
This commit is contained in:
parent
b783b22bc4
commit
31075fd0b9
51
infernal.py
51
infernal.py
|
@ -2,6 +2,8 @@
|
|||
import re
|
||||
import sys
|
||||
|
||||
from opcodes import OPCODES
|
||||
|
||||
REGISTERS=["%rax", "%rbx", "%rcx", "%rdx", "%rsp", "%rbp", "%rsi", "%rdi",
|
||||
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"]
|
||||
REG_STATUS_TO_COLOR = {
|
||||
|
@ -127,6 +129,7 @@ class Emulator:
|
|||
self.status["g"] = val1>val2
|
||||
self.status["l"] = val1<val2
|
||||
self.status["e"] = val1==val2
|
||||
|
||||
def changedRegisters (self, *args):
|
||||
for reg, val in args:
|
||||
self.changes[reg] = val
|
||||
|
@ -174,54 +177,8 @@ class Emulator:
|
|||
instruct = self.code[self.registers['%rip']]
|
||||
opcode = instruct[0]
|
||||
self.changes = {}
|
||||
if opcode[:4] == "push":
|
||||
self.pushToStack(self.getVal(instruct[1]))
|
||||
elif opcode[:3] == "pop":
|
||||
self.registers[instruct[1]] = self.popFromStack()
|
||||
self.changedRegisters((instruct[1],"change"))
|
||||
|
||||
elif opcode[:3] == "mov":
|
||||
self.changedRegisters((instruct[2],"change"))
|
||||
self.registers[instruct[2]] = self.getVal(instruct[1])
|
||||
elif opcode[:3] == "add":
|
||||
self.changedRegisters((instruct[2],"change"))
|
||||
self.registers[instruct[2]] = self.getVal(instruct[2]) + self.getVal(instruct[1])
|
||||
elif opcode[:3] == "sub":
|
||||
self.changedRegisters((instruct[2],"change"))
|
||||
self.registers[instruct[2]] = self.getVal(instruct[2]) - self.getVal(instruct[1])
|
||||
|
||||
elif opcode[:3] == "cmp":
|
||||
self.compareVal(instruct[1],instruct[2])
|
||||
|
||||
elif opcode == "jg":
|
||||
if self.status["g"]:
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "jl":
|
||||
if self.status["l"]:
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "je":
|
||||
if self.status["e"]:
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "jge":
|
||||
if (self.status["g"] or self.status["e"]):
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "jle":
|
||||
if (self.status["l"] or self.status["e"]):
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "jne":
|
||||
if not self.status["e"]:
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "jmp":
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
|
||||
elif opcode == "call":
|
||||
self.pushToStack(self.registers['%rip']+1)
|
||||
self.registers['%rip'] = self.labels[instruct[1]]
|
||||
elif opcode == "leave":
|
||||
self.registers["%rsp"] = self.registers["%rbp"]
|
||||
self.registers["%rbp"] = self.popFromStack()
|
||||
elif opcode == "ret":
|
||||
self.registers['%rip'] = self.popFromStack()
|
||||
OPCODES[opcode](self, *instruct[1:])
|
||||
|
||||
if self.registers['%rip'] == old_rip:
|
||||
self.registers['%rip'] += 1
|
||||
|
|
94
opcodes.py
Normal file
94
opcodes.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
OPCODES = {}
|
||||
|
||||
def add_opcode (*opcode_names):
|
||||
def wrapped (func):
|
||||
for name in opcode_names:
|
||||
OPCODES[name] = func
|
||||
return wrapped
|
||||
|
||||
################################################################################
|
||||
|
||||
# Stack
|
||||
|
||||
@add_opcode("push","pushq")
|
||||
def push(emu, value):
|
||||
emu.pushToStack(emu.getVal(value))
|
||||
|
||||
@add_opcode("pop","popq")
|
||||
def pop(emu, target_reg):
|
||||
emu.registers[target_reg] = emu.popFromStack()
|
||||
emu.changedRegisters((target_reg,"change"))
|
||||
|
||||
# Arithmetic
|
||||
|
||||
@add_opcode("mov","movq")
|
||||
def mov(emu, from_reg, target_reg):
|
||||
emu.registers[target_reg] = emu.getVal(from_reg)
|
||||
emu.changedRegisters((target_reg,"change"))
|
||||
|
||||
@add_opcode("add","addq")
|
||||
def add(emu, add_val, target_reg):
|
||||
emu.registers[target_reg] += emu.getVal(add_val)
|
||||
emu.changedRegisters((target_reg,"change"))
|
||||
|
||||
@add_opcode("sub","subq")
|
||||
def sub(emu, sub_val, target_reg):
|
||||
emu.registers[target_reg] -= emu.getVal(sub_val)
|
||||
emu.changedRegisters((target_reg,"change"))
|
||||
|
||||
# Comparison and conditional jumping
|
||||
|
||||
@add_opcode("cmp","cmpq")
|
||||
def comp(emu, val1, val2):
|
||||
emu.compareVal(val1, val2)
|
||||
|
||||
@add_opcode("jg")
|
||||
def jg(emu, label):
|
||||
if emu.status["g"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("jl")
|
||||
def jl(emu, label):
|
||||
if emu.status["l"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("je")
|
||||
def je(emu, label):
|
||||
if emu.status["e"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("jge")
|
||||
def jge(emu, label):
|
||||
if emu.status["g"] or emu.status["e"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("jle")
|
||||
def jle(emu, label):
|
||||
if emu.status["l"] or emu.status["e"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("jne")
|
||||
def jne(emu, label):
|
||||
if not emu.status["e"]:
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
# Unconditional Jumping
|
||||
|
||||
@add_opcode("jmp")
|
||||
def jmp(emu, label):
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("call")
|
||||
def call(emu, label):
|
||||
emu.pushToStack(emu.registers['%rip']+1)
|
||||
emu.registers['%rip'] = emu.labels[label]
|
||||
|
||||
@add_opcode("leave")
|
||||
def leave(emu):
|
||||
emu.registers["%rsp"] = emu.registers["%rbp"]
|
||||
emu.registers["%rbp"] = emu.popFromStack()
|
||||
|
||||
@add_opcode("ret")
|
||||
def ret(emu):
|
||||
emu.registers['%rip'] = emu.popFromStack()
|
Loading…
Reference in New Issue
Block a user