diff options
author | kobalicek <kobalicek.petr@gmail.com> | 2017-03-07 15:59:06 +0300 |
---|---|---|
committer | kobalicek <kobalicek.petr@gmail.com> | 2017-03-07 15:59:06 +0300 |
commit | 0e80d2c3c36a790f09aa8bd2d021e8c32ab946a4 (patch) | |
tree | 935db822a154ea9bc50c820476d589f807f0ab86 | |
parent | 528951ab9afe4ed5a07320e0bfd53dfd847199b9 (diff) |
[bug] Fixed special case of mov[abs] instruction
-rw-r--r-- | src/asmjit/base/operand.h | 2 | ||||
-rw-r--r-- | src/asmjit/x86/x86assembler.cpp | 41 |
2 files changed, 25 insertions, 18 deletions
diff --git a/src/asmjit/base/operand.h b/src/asmjit/base/operand.h index 623663f..36def28 100644 --- a/src/asmjit/base/operand.h +++ b/src/asmjit/base/operand.h @@ -970,7 +970,7 @@ public: //! Get a higher part of a 64-bit offset or absolute address. //! //! NOTE: This function is UNSAFE and returns garbage if `has64BitOffset()` - //! returns false. Never use blindly without checking it. + //! returns false. Never use it blindly without checking it. ASMJIT_INLINE int32_t getOffsetHi32() const noexcept { return static_cast<int32_t>(_mem.base); } //! Set a 64-bit offset or an absolute address to `offset`. diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index c64614e..6ef792e 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -1508,17 +1508,17 @@ CaseX86M_GPB_MulDiv: ADD_PREFIX_BY_SIZE(o0.getSize()); } - // Handle a special form 'mov al|ax|eax|rax, [ptr64]' that doesn't use MOD. + // Handle a special form `mov al|ax|eax|rax, [ptr64]` that doesn't use MOD. if (o0.getId() == X86Gp::kIdAx && !rmRel->as<X86Mem>().hasBaseOrIndex()) { - opCode += 0xA0; imVal = rmRel->as<X86Mem>().getOffset(); - imLen = getGpSize(); - goto EmitX86Op; - } - else { - opCode += 0x8A; - goto EmitX86M; + if (!is64Bit() || (is64Bit() && ((options & X86Inst::kOptionLongForm) || !Utils::isInt32(imVal)))) { + opCode += 0xA0; + goto EmitX86OpMovAbs; + } } + + opCode += 0x8A; + goto EmitX86M; } } @@ -1543,17 +1543,17 @@ CaseX86M_GPB_MulDiv: ADD_PREFIX_BY_SIZE(o1.getSize()); } - // Handle a special form 'mov [ptr64], al|ax|eax|rax' that doesn't use MOD. - if (!rmRel->as<X86Mem>().hasBaseOrIndex() && o1.getId() == X86Gp::kIdAx) { - opCode += 0xA2; + // Handle a special form `mov [ptr64], al|ax|eax|rax` that doesn't use MOD. + if (o1.getId() == X86Gp::kIdAx && !rmRel->as<X86Mem>().hasBaseOrIndex()) { imVal = rmRel->as<X86Mem>().getOffset(); - imLen = getGpSize(); - goto EmitX86Op; - } - else { - opCode += 0x88; - goto EmitX86M; + if (!is64Bit() || (is64Bit() && ((options & X86Inst::kOptionLongForm) || !Utils::isInt32(imVal)))) { + opCode += 0xA2; + goto EmitX86OpMovAbs; + } } + + opCode += 0x88; + goto EmitX86M; } } @@ -3531,6 +3531,13 @@ CaseVexRvm_R: // [Emit - X86] // -------------------------------------------------------------------------- +EmitX86OpMovAbs: + imLen = getGpSize(); + + // Segment-override prefix. + if (rmRel->as<X86Mem>().hasSegment()) + EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]); + EmitX86Op: // Emit mandatory instruction prefix. EMIT_PP(opCode); |