1
0

Moved opcodes into their own file. Now the format is crazy extensible.

This commit is contained in:
Jon Michael Aanes 2015-12-17 00:52:47 +01:00
parent b783b22bc4
commit 31075fd0b9
2 changed files with 98 additions and 47 deletions

View File

@ -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
View 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()