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): emu.jump(label, g=True) @add_opcode("jl") def jl(emu, label): emu.jump(label, l=True) @add_opcode("je") def je(emu, label): emu.jump(label, e=True) @add_opcode("jge") def jge(emu, label): emu.jump(label, "or", g=True, e=True) @add_opcode("jle") def jle(emu, label): emu.jump(label, "or", l=True, e=True) @add_opcode("jne") def jne(emu, label): emu.jump(label, e=False) # 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()