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 re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from opcodes import OPCODES
|
||||||
|
|
||||||
REGISTERS=["%rax", "%rbx", "%rcx", "%rdx", "%rsp", "%rbp", "%rsi", "%rdi",
|
REGISTERS=["%rax", "%rbx", "%rcx", "%rdx", "%rsp", "%rbp", "%rsi", "%rdi",
|
||||||
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"]
|
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"]
|
||||||
REG_STATUS_TO_COLOR = {
|
REG_STATUS_TO_COLOR = {
|
||||||
|
@ -127,6 +129,7 @@ class Emulator:
|
||||||
self.status["g"] = val1>val2
|
self.status["g"] = val1>val2
|
||||||
self.status["l"] = val1<val2
|
self.status["l"] = val1<val2
|
||||||
self.status["e"] = val1==val2
|
self.status["e"] = val1==val2
|
||||||
|
|
||||||
def changedRegisters (self, *args):
|
def changedRegisters (self, *args):
|
||||||
for reg, val in args:
|
for reg, val in args:
|
||||||
self.changes[reg] = val
|
self.changes[reg] = val
|
||||||
|
@ -174,54 +177,8 @@ class Emulator:
|
||||||
instruct = self.code[self.registers['%rip']]
|
instruct = self.code[self.registers['%rip']]
|
||||||
opcode = instruct[0]
|
opcode = instruct[0]
|
||||||
self.changes = {}
|
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":
|
OPCODES[opcode](self, *instruct[1:])
|
||||||
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()
|
|
||||||
|
|
||||||
if self.registers['%rip'] == old_rip:
|
if self.registers['%rip'] == old_rip:
|
||||||
self.registers['%rip'] += 1
|
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