2007-05-02 17:45:31 +00:00
|
|
|
#ifndef _X86ASSEMBLER_H_
|
|
|
|
#define _X86ASSEMBLER_H_
|
|
|
|
|
|
|
|
#include "Types.h"
|
2007-12-01 04:08:34 +00:00
|
|
|
#include <functional>
|
2007-11-12 03:59:42 +00:00
|
|
|
#include <map>
|
2007-05-02 17:45:31 +00:00
|
|
|
|
|
|
|
class CX86Assembler
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum REGISTER
|
|
|
|
{
|
|
|
|
rAX = 0,
|
|
|
|
rCX,
|
|
|
|
rDX,
|
|
|
|
rBX,
|
|
|
|
rSP,
|
|
|
|
rBP,
|
|
|
|
rSI,
|
|
|
|
rDI,
|
|
|
|
r8,
|
|
|
|
r9,
|
|
|
|
r10,
|
|
|
|
r11,
|
|
|
|
r12,
|
|
|
|
r13,
|
|
|
|
r14,
|
|
|
|
r15,
|
|
|
|
};
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
enum XMMREGISTER
|
|
|
|
{
|
|
|
|
xMM0 = 0,
|
|
|
|
xMM1,
|
|
|
|
xMM2,
|
|
|
|
xMM3,
|
|
|
|
xMM4,
|
|
|
|
xMM5,
|
|
|
|
xMM6,
|
|
|
|
xMM7,
|
|
|
|
xMM8,
|
|
|
|
xMM9,
|
|
|
|
xMM10,
|
|
|
|
xMM11,
|
|
|
|
xMM12,
|
|
|
|
xMM13,
|
|
|
|
xMM14,
|
|
|
|
xMM15,
|
|
|
|
};
|
|
|
|
|
2007-12-01 04:08:34 +00:00
|
|
|
typedef std::tr1::function<void (uint8)> WriteFunctionType;
|
|
|
|
typedef std::tr1::function<void (unsigned int, uint8)> WriteAtFunctionType;
|
|
|
|
typedef std::tr1::function<size_t ()> TellFunctionType;
|
2007-11-12 03:59:42 +00:00
|
|
|
typedef unsigned int LABEL;
|
2007-05-02 17:45:31 +00:00
|
|
|
|
|
|
|
class CAddress
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CAddress();
|
|
|
|
|
|
|
|
bool nIsExtendedModRM;
|
2007-12-11 07:05:37 +00:00
|
|
|
bool nIsExtendedSib;
|
2007-05-02 17:45:31 +00:00
|
|
|
|
|
|
|
union MODRMBYTE
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
unsigned int nRM : 3;
|
|
|
|
unsigned int nFnReg : 3;
|
|
|
|
unsigned int nMod : 2;
|
|
|
|
};
|
|
|
|
uint8 nByte;
|
|
|
|
};
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
union SIB
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
unsigned int base : 3;
|
|
|
|
unsigned int index : 3;
|
|
|
|
unsigned int scale : 2;
|
|
|
|
};
|
|
|
|
uint8 byteValue;
|
|
|
|
};
|
|
|
|
|
2007-05-02 17:45:31 +00:00
|
|
|
MODRMBYTE ModRm;
|
2007-12-11 07:05:37 +00:00
|
|
|
SIB sib;
|
2007-05-02 17:45:31 +00:00
|
|
|
uint32 nOffset;
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
bool HasSib() const;
|
2007-05-02 17:45:31 +00:00
|
|
|
void Write(const WriteFunctionType&);
|
|
|
|
};
|
|
|
|
|
2007-11-12 03:59:42 +00:00
|
|
|
CX86Assembler(
|
|
|
|
const WriteFunctionType&,
|
|
|
|
const WriteAtFunctionType&,
|
|
|
|
const TellFunctionType&);
|
2007-05-02 17:45:31 +00:00
|
|
|
virtual ~CX86Assembler();
|
|
|
|
|
|
|
|
static CAddress MakeRegisterAddress(REGISTER);
|
2007-12-29 17:22:26 +00:00
|
|
|
static CAddress MakeXmmRegisterAddress(XMMREGISTER);
|
2007-12-01 04:08:34 +00:00
|
|
|
static CAddress MakeByteRegisterAddress(REGISTER);
|
2007-12-11 07:05:37 +00:00
|
|
|
static CAddress MakeIndRegAddress(REGISTER);
|
2007-05-02 17:45:31 +00:00
|
|
|
static CAddress MakeIndRegOffAddress(REGISTER, uint32);
|
2008-01-02 04:03:05 +00:00
|
|
|
static CAddress MakeBaseIndexScaleAddress(REGISTER, REGISTER, uint8);
|
2007-05-02 17:45:31 +00:00
|
|
|
|
2007-11-12 03:59:42 +00:00
|
|
|
LABEL CreateLabel();
|
|
|
|
void MarkLabel(LABEL);
|
|
|
|
void ResolveLabelReferences();
|
|
|
|
|
2008-01-02 04:03:05 +00:00
|
|
|
void AdcEd(REGISTER, const CAddress&);
|
2007-12-27 20:35:09 +00:00
|
|
|
void AdcId(const CAddress&, uint32);
|
2007-12-06 21:36:12 +00:00
|
|
|
void AddEd(REGISTER, const CAddress&);
|
2007-05-02 17:45:31 +00:00
|
|
|
void AddId(const CAddress&, uint32);
|
2007-12-06 21:36:12 +00:00
|
|
|
void AndEd(REGISTER, const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void AndIb(const CAddress&, uint8);
|
2007-12-06 21:36:12 +00:00
|
|
|
void AndId(const CAddress&, uint32);
|
2008-05-23 01:01:43 +00:00
|
|
|
void BsrEd(REGISTER, const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void CallEd(const CAddress&);
|
2008-03-08 15:51:03 +00:00
|
|
|
void CmovsEd(REGISTER, const CAddress&);
|
|
|
|
void CmovnsEd(REGISTER, const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void CmpEd(REGISTER, const CAddress&);
|
2007-05-02 17:45:31 +00:00
|
|
|
void CmpEq(REGISTER, const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void CmpIb(const CAddress&, uint8);
|
2007-10-31 22:09:21 +00:00
|
|
|
void CmpId(const CAddress&, uint32);
|
2007-05-02 17:45:31 +00:00
|
|
|
void CmpIq(const CAddress&, uint64);
|
2008-01-02 04:03:05 +00:00
|
|
|
void Cdq();
|
2008-01-07 04:05:17 +00:00
|
|
|
void DivEd(const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void IdivEd(const CAddress&);
|
2007-12-06 21:36:12 +00:00
|
|
|
void ImulEd(const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void JaeJb(LABEL);
|
2008-01-19 03:36:27 +00:00
|
|
|
void JcJb(LABEL);
|
2007-11-12 03:59:42 +00:00
|
|
|
void JeJb(LABEL);
|
2007-12-01 04:08:34 +00:00
|
|
|
void JmpJb(LABEL);
|
2007-11-12 03:59:42 +00:00
|
|
|
void JneJb(LABEL);
|
2008-03-08 15:51:03 +00:00
|
|
|
void JnoJb(LABEL);
|
2008-05-23 01:01:43 +00:00
|
|
|
void JnsJb(LABEL);
|
2008-02-08 22:07:28 +00:00
|
|
|
void LeaGd(REGISTER, const CAddress&);
|
2007-05-02 17:45:31 +00:00
|
|
|
void MovEd(REGISTER, const CAddress&);
|
|
|
|
void MovEq(REGISTER, const CAddress&);
|
|
|
|
void MovGd(const CAddress&, REGISTER);
|
|
|
|
void MovId(REGISTER, uint32);
|
2007-12-11 07:05:37 +00:00
|
|
|
void MovsxEb(REGISTER, const CAddress&);
|
|
|
|
void MovsxEw(REGISTER, const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void MovzxEb(REGISTER, const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void MulEd(const CAddress&);
|
2008-05-23 01:01:43 +00:00
|
|
|
void NegEd(const CAddress&);
|
2007-12-06 21:36:12 +00:00
|
|
|
void Nop();
|
2008-01-10 05:18:34 +00:00
|
|
|
void NotEd(const CAddress&);
|
2007-12-06 21:36:12 +00:00
|
|
|
void OrEd(REGISTER, const CAddress&);
|
|
|
|
void OrId(const CAddress&, uint32);
|
2007-12-11 07:05:37 +00:00
|
|
|
void Pop(REGISTER);
|
2007-12-01 04:08:34 +00:00
|
|
|
void Push(REGISTER);
|
2007-12-06 21:36:12 +00:00
|
|
|
void PushEd(const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void PushId(uint32);
|
2008-02-08 22:07:28 +00:00
|
|
|
void RepMovsb();
|
2007-11-12 03:59:42 +00:00
|
|
|
void Ret();
|
2008-01-15 20:27:44 +00:00
|
|
|
void SarEd(const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void SarEd(const CAddress&, uint8);
|
2008-01-02 04:03:05 +00:00
|
|
|
void SbbEd(REGISTER, const CAddress&);
|
|
|
|
void SbbId(const CAddress&, uint32);
|
2007-12-01 04:08:34 +00:00
|
|
|
void SetbEb(const CAddress&);
|
|
|
|
void SetbeEb(const CAddress&);
|
|
|
|
void SeteEb(const CAddress&);
|
2008-04-06 20:38:34 +00:00
|
|
|
void SetneEb(const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void SetlEb(const CAddress&);
|
2009-03-30 04:57:52 +00:00
|
|
|
void SetleEb(const CAddress&);
|
2008-05-28 02:29:57 +00:00
|
|
|
void SetgEb(const CAddress&);
|
2008-01-02 04:03:05 +00:00
|
|
|
void ShrEd(const CAddress&);
|
2007-12-06 21:36:12 +00:00
|
|
|
void ShrEd(const CAddress&, uint8);
|
2008-01-02 04:03:05 +00:00
|
|
|
void ShrdEd(const CAddress&, REGISTER);
|
2007-12-06 21:36:12 +00:00
|
|
|
void ShrdEd(const CAddress&, REGISTER, uint8);
|
2008-01-02 04:03:05 +00:00
|
|
|
void ShlEd(const CAddress&);
|
2007-12-06 21:36:12 +00:00
|
|
|
void ShlEd(const CAddress&, uint8);
|
2008-01-02 04:03:05 +00:00
|
|
|
void ShldEd(const CAddress&, REGISTER);
|
2007-12-06 21:36:12 +00:00
|
|
|
void ShldEd(const CAddress&, REGISTER, uint8);
|
2007-07-20 14:49:36 +00:00
|
|
|
void SubEd(REGISTER, const CAddress&);
|
2007-05-02 17:45:31 +00:00
|
|
|
void SubId(const CAddress&, uint32);
|
2008-01-02 04:03:05 +00:00
|
|
|
void TestEb(REGISTER, const CAddress&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void TestEd(REGISTER, const CAddress&);
|
2007-12-29 17:22:26 +00:00
|
|
|
void XorEd(REGISTER, const CAddress&);
|
2007-12-27 20:35:09 +00:00
|
|
|
void XorId(const CAddress&, uint32);
|
2007-05-02 17:45:31 +00:00
|
|
|
void XorGd(const CAddress&, REGISTER);
|
|
|
|
void XorGq(const CAddress&, REGISTER);
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
//FPU
|
|
|
|
void FldEd(const CAddress&);
|
|
|
|
void FildEd(const CAddress&);
|
|
|
|
void FstpEd(const CAddress&);
|
|
|
|
void FistpEd(const CAddress&);
|
|
|
|
void FisttpEd(const CAddress&);
|
|
|
|
void FaddpSt(uint8);
|
|
|
|
void FsubpSt(uint8);
|
|
|
|
void FmulpSt(uint8);
|
|
|
|
void FdivpSt(uint8);
|
|
|
|
void Fwait();
|
2008-06-23 01:35:05 +00:00
|
|
|
void Fsin();
|
2007-12-11 07:05:37 +00:00
|
|
|
void FnstcwEw(const CAddress&);
|
|
|
|
void FldcwEw(const CAddress&);
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
//SSE
|
2007-12-29 17:22:26 +00:00
|
|
|
|
|
|
|
enum SSE_CMP_TYPE
|
|
|
|
{
|
|
|
|
SSE_CMP_EQ = 0,
|
|
|
|
SSE_CMP_LT = 1,
|
|
|
|
SSE_CMP_LE = 2,
|
|
|
|
SSE_CMP_UNORD = 3,
|
|
|
|
SSE_CMP_NEQ = 4,
|
|
|
|
SSE_CMP_NLT = 5,
|
|
|
|
SSE_CMP_NLE = 6,
|
|
|
|
SSE_CMP_ORD = 7,
|
|
|
|
};
|
|
|
|
|
2008-03-06 03:14:33 +00:00
|
|
|
void MovdVo(XMMREGISTER, const CAddress&);
|
2008-01-12 07:00:48 +00:00
|
|
|
void MovdquVo(const CAddress&, XMMREGISTER);
|
|
|
|
void MovdquVo(XMMREGISTER, const CAddress&);
|
2008-02-27 02:23:28 +00:00
|
|
|
void MovapsVo(const CAddress&, XMMREGISTER);
|
2008-02-28 02:16:54 +00:00
|
|
|
void MovapsVo(XMMREGISTER, const CAddress&);
|
2008-03-16 22:31:37 +00:00
|
|
|
void PackssdwVo(XMMREGISTER, const CAddress&);
|
|
|
|
void PackuswbVo(XMMREGISTER, const CAddress&);
|
2008-02-08 22:07:28 +00:00
|
|
|
void PaddwVo(XMMREGISTER, const CAddress&);
|
2008-01-12 07:00:48 +00:00
|
|
|
void PandVo(XMMREGISTER, const CAddress&);
|
2008-02-27 02:23:28 +00:00
|
|
|
void PandnVo(XMMREGISTER, const CAddress&);
|
2008-01-12 07:00:48 +00:00
|
|
|
void PcmpeqdVo(XMMREGISTER, const CAddress&);
|
2008-02-08 22:07:28 +00:00
|
|
|
void PcmpgtwVo(XMMREGISTER, const CAddress&);
|
2008-02-01 02:34:50 +00:00
|
|
|
void PmaxswVo(XMMREGISTER, const CAddress&);
|
|
|
|
void PminswVo(XMMREGISTER, const CAddress&);
|
2008-01-12 07:00:48 +00:00
|
|
|
void PorVo(XMMREGISTER, const CAddress&);
|
2008-02-10 23:08:04 +00:00
|
|
|
void PsllwVo(XMMREGISTER, uint8);
|
2008-02-27 02:23:28 +00:00
|
|
|
void PslldVo(XMMREGISTER, uint8);
|
2008-02-10 23:08:04 +00:00
|
|
|
void PsrawVo(XMMREGISTER, uint8);
|
2008-03-16 22:31:37 +00:00
|
|
|
void PsradVo(XMMREGISTER, uint8);
|
2008-02-01 02:34:50 +00:00
|
|
|
void PsrlwVo(XMMREGISTER, uint8);
|
2008-03-06 03:14:33 +00:00
|
|
|
void PsrldVo(XMMREGISTER, uint8);
|
2008-01-12 07:00:48 +00:00
|
|
|
void PsubbVo(XMMREGISTER, const CAddress&);
|
2008-01-15 20:27:44 +00:00
|
|
|
void PsubdVo(XMMREGISTER, const CAddress&);
|
2008-02-08 22:07:28 +00:00
|
|
|
void PunpcklbwVo(XMMREGISTER, const CAddress&);
|
2008-02-27 02:23:28 +00:00
|
|
|
void PunpcklwdVo(XMMREGISTER, const CAddress&);
|
2008-02-29 02:11:27 +00:00
|
|
|
void PunpckldqVo(XMMREGISTER, const CAddress&);
|
2008-02-08 22:07:28 +00:00
|
|
|
void PunpckhbwVo(XMMREGISTER, const CAddress&);
|
2008-02-29 02:11:27 +00:00
|
|
|
void PunpckhdqVo(XMMREGISTER, const CAddress&);
|
2008-01-07 04:05:17 +00:00
|
|
|
void PxorVo(XMMREGISTER, const CAddress&);
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void MovssEd(const CAddress&, XMMREGISTER);
|
|
|
|
void MovssEd(XMMREGISTER, const CAddress&);
|
|
|
|
void AddssEd(XMMREGISTER, const CAddress&);
|
|
|
|
void SubssEd(XMMREGISTER, const CAddress&);
|
|
|
|
void MulssEd(XMMREGISTER, const CAddress&);
|
|
|
|
void DivssEd(XMMREGISTER, const CAddress&);
|
2008-04-20 20:55:03 +00:00
|
|
|
void RcpssEd(XMMREGISTER, const CAddress&);
|
2008-03-03 00:38:28 +00:00
|
|
|
void RsqrtssEd(XMMREGISTER, const CAddress&);
|
2008-02-17 23:51:25 +00:00
|
|
|
void SqrtssEd(XMMREGISTER, const CAddress&);
|
2007-12-29 17:22:26 +00:00
|
|
|
void CmpssEd(XMMREGISTER, const CAddress&, SSE_CMP_TYPE);
|
2007-12-14 01:41:48 +00:00
|
|
|
void Cvtsi2ssEd(XMMREGISTER, const CAddress&);
|
|
|
|
void Cvttss2siEd(REGISTER, const CAddress&);
|
2008-03-16 22:31:37 +00:00
|
|
|
void Cvtdq2psVo(XMMREGISTER, const CAddress&);
|
|
|
|
void Cvttps2dqVo(XMMREGISTER, const CAddress&);
|
2007-12-14 01:41:48 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void AddpsVo(XMMREGISTER, const CAddress&);
|
2008-06-09 00:06:58 +00:00
|
|
|
void DivpsVo(XMMREGISTER, const CAddress&);
|
2008-03-15 16:20:36 +00:00
|
|
|
void MaxpsVo(XMMREGISTER, const CAddress&);
|
|
|
|
void MinpsVo(XMMREGISTER, const CAddress&);
|
2008-02-28 02:16:54 +00:00
|
|
|
void MulpsVo(XMMREGISTER, const CAddress&);
|
2008-02-27 02:23:28 +00:00
|
|
|
void SubpsVo(XMMREGISTER, const CAddress&);
|
|
|
|
void ShufpsVo(XMMREGISTER, const CAddress&, uint8);
|
|
|
|
|
2007-05-02 17:45:31 +00:00
|
|
|
private:
|
2007-11-12 03:59:42 +00:00
|
|
|
struct LABELREF
|
|
|
|
{
|
|
|
|
size_t address;
|
|
|
|
unsigned int offsetSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::map<LABEL, size_t> LabelMapType;
|
|
|
|
typedef std::multimap<LABEL, LABELREF> LabelReferenceMapType;
|
|
|
|
|
2007-05-02 17:45:31 +00:00
|
|
|
void WriteRexByte(bool, const CAddress&);
|
|
|
|
void WriteRexByte(bool, const CAddress&, REGISTER&);
|
2007-12-01 04:08:34 +00:00
|
|
|
void WriteEvOp(uint8, uint8, bool, const CAddress&);
|
2007-05-02 17:45:31 +00:00
|
|
|
void WriteEvGvOp(uint8, bool, const CAddress&, REGISTER);
|
2008-01-02 04:03:05 +00:00
|
|
|
void WriteEvIb(uint8, const CAddress&, uint8);
|
2007-05-02 17:45:31 +00:00
|
|
|
void WriteEvId(uint8, const CAddress&, uint32);
|
|
|
|
void WriteEvIq(uint8, const CAddress&, uint64);
|
2007-12-14 01:41:48 +00:00
|
|
|
void WriteEdVdOp(uint8, const CAddress&, XMMREGISTER);
|
2008-02-01 02:34:50 +00:00
|
|
|
void WriteVrOp(uint8, uint8, XMMREGISTER);
|
2007-12-11 07:05:37 +00:00
|
|
|
void WriteStOp(uint8, uint8, uint8);
|
2007-05-02 17:45:31 +00:00
|
|
|
|
2007-11-12 03:59:42 +00:00
|
|
|
void CreateLabelReference(LABEL, unsigned int);
|
|
|
|
|
2007-05-02 17:45:31 +00:00
|
|
|
static unsigned int GetMinimumConstantSize(uint32);
|
|
|
|
static unsigned int GetMinimumConstantSize64(uint64);
|
|
|
|
|
|
|
|
void WriteByte(uint8);
|
|
|
|
void WriteDWord(uint32);
|
|
|
|
WriteFunctionType m_WriteFunction;
|
2007-11-12 03:59:42 +00:00
|
|
|
WriteAtFunctionType m_WriteAtFunction;
|
|
|
|
TellFunctionType m_TellFunction;
|
|
|
|
LabelMapType m_labels;
|
|
|
|
LabelReferenceMapType m_labelReferences;
|
|
|
|
LABEL m_nextLabelId;
|
2007-05-02 17:45:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|