def operation(name, st0_target, st0_source, modrm_target): def _impl(inst, target, source=None): if source: if isinstance(target, st) and isinstance(source, st): if target.index == 0: inst.chr(0xd8) inst.chr(st0_target + source.index) elif source.index == 0: inst.chr(0xdc) inst.chr(st0_source + target.index) else: raise AssemblyError( '%s with registers must involve st(0)' % name) else: raise AssemblyError('unsupported operands: %s: %s %s' % (name, target, source)) else: operand = target if isinstance(operand, Address): inst.chr(0xd8) inst.modrmoff(modrm_target, operand, operand.offset) else: raise AssemblyError('unsupported operand: %s: %s' % (name, operand)) _impl.__name__ = name return Instruction.producer(_impl)
def operation(name, eax_int, reg_int, reg_addr, reg_reg_32, reg_reg_8, addr_int, addr_reg): def _impl(inst, target, source, width=32): if isinstance(source, int): if target is eax and source > 255: inst.chr(eax_int) inst.pack('i', source) elif isinstance(target, Register): if source <= 255: inst.chr(0x83) inst.modrm(3, reg_int, target) inst.pack('b', source) else: inst.chr(0x81) inst.modrm(3, reg_int, target) inst.pack('i', source) elif isinstance(target, Address): if width == 8: inst.chr(0x80) inst.modrm(1, addr_int, target) inst.chr(0) inst.pack('b', source) elif width == 32: inst.chr(0x81) inst.modrm(1, addr_int, target) inst.chr(0) inst.pack('i', source) else: raise AssemblyError('incompatible target operand: %s' % source) elif isinstance(source, Address): inst.chr(reg_addr) inst.modrmoff(target, source, source.offset) elif isinstance(source, Register): if isinstance(target, Register): if isinstance(source, DWordRegister): inst.chr(reg_reg_32) inst.modrm(3, target, source) elif isinstance(source, ByteRegister): inst.chr(reg_reg_8) inst.modrm(3, source, target) elif isinstance(target, Address): if abs(target.offset) < 128: inst.chr(addr_reg) inst.modrm(1, source, target) inst.pack('b', target.offset) else: inst.chr(addr_reg + 1) inst.modrm(2, source, target) inst.pack('i', target.offset) else: raise AssemblyError('incompatible target operand: %s' % target) else: raise AssemblyError('incompatible source operand: %s' % source) _impl.__name__ = name return Instruction.producer(_impl)
def operation(name, eax_int, reg_int, reg_addr, reg_reg_32, reg_reg_8, addr_int, addr_reg): def _impl(inst, target, source, width=32): if isinstance(source, int): if target is eax and source > 255: inst.chr(eax_int) inst.pack('i', source) elif isinstance(target, Register): if source <= 255: inst.chr(0x83) inst.modrm(3, reg_int, target) inst.pack('b', source) else: inst.chr(0x81) inst.modrm(3, reg_int, target) inst.pack('i', source) elif isinstance(target, Address): if width == 8: inst.chr(0x80) inst.modrm(1, addr_int, target) inst.chr(0) inst.pack('b', source) elif width == 32: inst.chr(0x81) inst.modrm(1, addr_int, target) inst.chr(0) inst.pack('i', source) else: raise AssemblyError('incompatible target operand: %s' % source) elif isinstance(source, Address): inst.chr(reg_addr) inst.modrmoff(target, source, source.offset) elif isinstance(source, Register): if isinstance(target, Register): if isinstance(source, DWordRegister): inst.chr(reg_reg_32) inst.modrm(3, target, source) elif isinstance(source, ByteRegister): inst.chr(reg_reg_8) inst.modrm(3, source, target) elif isinstance(target, Address): if abs(target.offset) < 128: inst.chr(addr_reg) inst.modrm(1, source, target) inst.pack('b', target.offset) else: inst.chr(addr_reg+1) inst.modrm(2, source, target) inst.pack('i', target.offset) else: raise AssemblyError('incompatible target operand: %s' % target) else: raise AssemblyError('incompatible source operand: %s' % source) _impl.__name__ = name return Instruction.producer(_impl)
def transfer(name, opcode, st1, st2, modrm_target): def _impl(inst, operand): if isinstance(operand, Address): inst.chr(0xd9) inst.modrmoff(modrm_target, operand, operand.offset) elif isinstance(operand, st): inst.chr(st1) inst.chr(st2 + operand.index) else: raise AssemblyError('unsupported operand: %s: %s' % (name, operand)) _impl.__name__ = name return Instruction.producer(_impl)
def popping(name, opcode): def _impl(inst, operand=None): if operand: if isinstance(operand, st): inst.chr(0xde) inst.chr(opcode+operand.index) else: raise AssemblyError('unsupported operand: %s: %s' % (name, operand)) else: inst.chr(0xde) inst.chr(opcode+1) _impl.__name__ = name return Instruction.producer(_impl)
def popping(name, opcode): def _impl(inst, operand=None): if operand: if isinstance(operand, st): inst.chr(0xde) inst.chr(opcode + operand.index) else: raise AssemblyError('unsupported operand: %s: %s' % (name, operand)) else: inst.chr(0xde) inst.chr(opcode + 1) _impl.__name__ = name return Instruction.producer(_impl)
def operation(name, st0_target, st0_source, modrm_target): def _impl(inst, target, source=None): if source: if isinstance(target, st) and isinstance(source, st): if target.index == 0: inst.chr(0xd8) inst.chr(st0_target + source.index) elif source.index == 0: inst.chr(0xdc) inst.chr(st0_source + target.index) else: raise AssemblyError('%s with registers must involve st(0)' % name) else: raise AssemblyError('unsupported operands: %s: %s %s' % (name, target, source)) else: operand = target if isinstance(operand, Address): inst.chr(0xd8) inst.modrmoff(modrm_target, operand, operand.offset) else: raise AssemblyError('unsupported operand: %s: %s' % (name, operand)) _impl.__name__ = name return Instruction.producer(_impl)