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