/* * ix86 core. * Author: linuzappz */ #include #include "ix86.h" void x86Init(char *ptr) { x86Ptr = ptr; } void x86Shutdown() { } void x86SetJ8(u8 *j8) { *j8 = ((u8*)x86Ptr - j8) - 1; } void x86SetJ32(u32 *j32) { *j32 = ((u32*)x86Ptr - j32) - 4; } #define SIB 4 #define DISP32 5 #define write8(val) *(unsigned char *)x86Ptr = val; x86Ptr++; #define write16(val) *(unsigned short*)x86Ptr = val; x86Ptr+=2; #define write32(val) *(u32 *)x86Ptr = val; x86Ptr+=4; /* macros helpers */ #define ModRM(mod, rm, reg) \ write8((mod << 6) | (rm << 3) | (reg)); #define SibSB(ss, rm, index) \ write8((ss << 6) | (rm << 3) | (index)); #define SET8R(cc, to) { \ write8(0x0F); write8(cc); \ write8((0xC0) | (to)); } #define J8Rel(cc, to) { \ write8(cc); write8(to); return x86Ptr - 1; } #define CMOV32RtoR(cc, to, from) { \ write8(0x0F); write8(cc); \ ModRM(3, to, from); } #define CMOV32MtoR(cc, to, from) { \ write8(0x0F); write8(cc); \ ModRM(0, to, DISP32); \ write32(from); } /********************/ /* IX86 intructions */ /********************/ // mov instructions /* mov r32 to r32 */ void MOV32RtoR(int to, int from) { write8(0x89); ModRM(3, from, to); } /* mov r32 to m32 */ void MOV32RtoM(u32 to, int from) { write8(0x89); ModRM(0, from, DISP32); write32(to); } /* mov m32 to r32 */ void MOV32MtoR(int to, u32 from) { write8(0x8B); ModRM(0, to, DISP32); write32(from); } /* mov [r32] to r32 */ void MOV32RmtoR(int to, int from) { write8(0x8B); ModRM(0, to, from); } /* mov [r32][r32*scale] to r32 */ void MOV32RmStoR(int to, int from, int from2, int scale) { write8(0x8B); ModRM(0, to, 0x4); SibSB(scale, from2, from); } /* mov r32 to [r32] */ void MOV32RtoRm(int to, int from) { write8(0x89); ModRM(0, from, to); } /* mov imm32 to r32 */ void MOV32ItoR(int to, u32 from) { write8(0xB8 | to); write32(from); } /* mov imm32 to m32 */ void MOV32ItoM(u32 to, u32 from) { write8(0xC7); ModRM(0, 0, DISP32); write32(to); write32(from); } /* movsx r8 to r32 */ void MOVSX32R8toR(int to, int from) { write16(0xBE0F); ModRM(3, to, from); } /* movsx r16 to r32 */ void MOVSX32R16toR(int to, int from) { write16(0xBF0F); ModRM(3, to, from); } /* movzx r8 to r32 */ void MOVZX32R8toR(int to, int from) { write16(0xB60F); ModRM(3, to, from); } /* movzx r16 to r32 */ void MOVZX32R16toR(int to, int from) { write16(0xB70F); ModRM(3, to, from); } /* cmovne r32 to r32 */ void CMOVNE32RtoR(int to, int from) { CMOV32RtoR(0x45, to, from); } /* cmovne m32 to r32*/ void CMOVNE32MtoR(int to, u32 from) { CMOV32MtoR(0x45, to, from); } /* cmove r32 to r32*/ void CMOVE32RtoR(int to, int from) { CMOV32RtoR(0x44, to, from); } /* cmove m32 to r32*/ void CMOVE32MtoR(int to, u32 from) { CMOV32MtoR(0x44, to, from); } /* cmovg r32 to r32*/ void CMOVG32RtoR(int to, int from) { CMOV32RtoR(0x4F, to, from); } /* cmovg m32 to r32*/ void CMOVG32MtoR(int to, u32 from) { CMOV32MtoR(0x4F, to, from); } /* cmovge r32 to r32*/ void CMOVGE32RtoR(int to, int from) { CMOV32RtoR(0x4D, to, from); } /* cmovge m32 to r32*/ void CMOVGE32MtoR(int to, u32 from) { CMOV32MtoR(0x4D, to, from); } /* cmovl r32 to r32*/ void CMOVL32RtoR(int to, int from) { CMOV32RtoR(0x4C, to, from); } /* cmovl m32 to r32*/ void CMOVL32MtoR(int to, u32 from) { CMOV32MtoR(0x4C, to, from); } /* cmovle r32 to r32*/ void CMOVLE32RtoR(int to, int from) { CMOV32RtoR(0x4E, to, from); } /* cmovle m32 to r32*/ void CMOVLE32MtoR(int to, u32 from) { CMOV32MtoR(0x4E, to, from); } // arithmic instructions /* add imm32 to r32 */ void ADD32ItoR(int to, u32 from) { if (to == EAX) { write8(0x05); } else { write8(0x81); ModRM(3, 0, to); } write32(from); } /* add imm32 to m32 */ void ADD32ItoM(u32 to, u32 from) { write8(0x81); ModRM(0, 0, DISP32); write32(to); write32(from); } /* add r32 to r32 */ void ADD32RtoR(int to, int from) { write8(0x01); ModRM(3, from, to); } /* add m32 to r32 */ void ADD32MtoR(int to, u32 from) { write8(0x03); ModRM(0, to, DISP32); write32(from); } /* adc imm32 to r32 */ void ADC32ItoR(int to, u32 from) { if (to == EAX) { write8(0x15); } else { write8(0x81); ModRM(3, 2, to); } write32(from); } /* adc r32 to r32 */ void ADC32RtoR(int to, int from) { write8(0x11); ModRM(3, from, to); } /* adc m32 to r32 */ void ADC32MtoR(int to, u32 from) { write8(0x13); ModRM(0, to, DISP32); write32(from); } /* sub imm32 to r32 */ void SUB32ItoR(int to, u32 from) { if (to == EAX) { write8(0x2D); } else { write8(0x81); ModRM(3, 5, to); } write32(from); } /* sub r32 to r32 */ void SUB32RtoR(int to, int from) { write8(0x29); ModRM(3, from, to); } /* sub m32 to r32 */ void SUB32MtoR(int to, u32 from) { write8(0x2B); ModRM(0, to, DISP32); write32(from); } /* sbb imm32 to r32 */ void SBB32ItoR(int to, u32 from) { if (to == EAX) { write8(0x1D); } else { write8(0x81); ModRM(3, 3, to); } write32(from); } /* sbb r32 to r32 */ void SBB32RtoR(int to, int from) { write8(0x19); ModRM(3, from, to); } /* sbb m32 to r32 */ void SBB32MtoR(int to, u32 from) { write8(0x1B); ModRM(0, to, DISP32); write32(from); } /* mul eax by r32 to edx:eax */ void MUL32R(int from) { write8(0xF7); ModRM(3, 4, from); } /* imul eax by r32 to edx:eax */ void IMUL32R(int from) { write8(0xF7); ModRM(3, 5, from); } /* mul eax by m32 to edx:eax */ void MUL32M(u32 from) { write8(0xF7); ModRM(0, 4, DISP32); write32(from); } /* imul eax by m32 to edx:eax */ void IMUL32M(u32 from) { write8(0xF7); ModRM(0, 5, DISP32); write32(from); } /* div eax by r32 to edx:eax */ void DIV32R(int from) { write8(0xF7); ModRM(3, 6, from); } /* idiv eax by r32 to edx:eax */ void IDIV32R(int from) { write8(0xF7); ModRM(3, 7, from); } /* div eax by m32 to edx:eax */ void DIV32M(u32 from) { write8(0xF7); ModRM(0, 6, DISP32); write32(from); } /* idiv eax by m32 to edx:eax */ void IDIV32M(u32 from) { write8(0xF7); ModRM(0, 7, DISP32); write32(from); } // shifting instructions /* shl imm8 to r32 */ void SHL32ItoR(int to, unsigned char from) { write8(0xC1); ModRM(3, 4, to); write8(from); } /* shl cl to r32 */ void SHL32CLtoR(int to) { write8(0xD3); ModRM(3, 4, to); } /* shr imm8 to r32 */ void SHR32ItoR(int to, unsigned char from) { write8(0xC1); ModRM(3, 5, to); write8(from); } /* shr cl to r32 */ void SHR32CLtoR(int to) { write8(0xD3); ModRM(3, 5, to); } /* sar imm8 to r32 */ void SAR32ItoR(int to, unsigned char from) { write8(0xC1); ModRM(3, 7, to); write8(from); } /* sar cl to r32 */ void SAR32CLtoR(int to) { write8(0xD3); ModRM(3, 7, to); } // logical instructions /* or imm32 to r32 */ void OR32ItoR(int to, u32 from) { if (to == EAX) { write8(0x0D); } else { write8(0x81); ModRM(3, 1, to); } write32(from); } /* or imm32 to m32 */ void OR32ItoM(u32 to, u32 from) { write8(0x81); ModRM(0, 1, DISP32); write32(to); write32(from); } /* or r32 to r32 */ void OR32RtoR(int to, int from) { write8(0x09); ModRM(3, from, to); } /* or m32 to r32 */ void OR32MtoR(int to, u32 from) { write8(0x0B); ModRM(0, to, DISP32); write32(from); } /* xor imm32 to r32 */ void XOR32ItoR(int to, u32 from) { if (to == EAX) { write8(0x35); } else { write8(0x81); ModRM(3, 6, to); } write32(from); } /* xor imm32 to m32 */ void XOR32ItoM(u32 to, u32 from) { write8(0x81); ModRM(0, 6, DISP32); write32(to); write32(from); } /* xor r32 to r32 */ void XOR32RtoR(int to, int from) { write8(0x31); ModRM(3, from, to); } /* xor m32 to r32 */ void XOR32MtoR(int to, u32 from) { write8(0x33); ModRM(0, to, DISP32); write32(from); } /* and imm32 to r32 */ void AND32ItoR(int to, u32 from) { if (to == EAX) { write8(0x25); } else { write8(0x81); ModRM(3, 0x4, to); } write32(from); } /* and imm32 to m32 */ void AND32ItoM(u32 to, u32 from) { write8(0x81); ModRM(0, 0x4, DISP32); write32(to); write32(from); } /* and r32 to r32 */ void AND32RtoR(int to, int from) { write8(0x21); ModRM(3, from, to); } /* and m32 to r32 */ void AND32MtoR(int to, u32 from) { write8(0x23); ModRM(0, to, DISP32); write32(from); } /* not r32 */ void NOT32R(int from) { write8(0xF7); ModRM(3, 2, from); } /* neg r32 */ void NEG32R(int from) { write8(0xF7); ModRM(3, 3, from); } // jump instructions /* jmp rel8 */ u8* JMP8(unsigned char to) { write8(0xEB); write8(to); return x86Ptr - 1; } /* jmp rel32 */ u32* JMP32(u32 to) { write8(0xE9); write32(to); return (u32*)(x86Ptr - 4); } /* jmp r32 */ void JMP32R(int to) { write8(0xFF); ModRM(3, 4, to); } /* je rel8 */ u8* JE8(unsigned char to) { J8Rel(0x74, to); } /* jz rel8 */ u8* JZ8(unsigned char to) { J8Rel(0x74, to); } /* jg rel8 */ u8* JG8(unsigned char to) { J8Rel(0x7F, to); } /* jge rel8 */ u8* JGE8(unsigned char to) { J8Rel(0x7D, to); } /* jl rel8 */ u8* JL8(unsigned char to) { J8Rel(0x7C, to); } /* jle rel8 */ u8* JLE8(unsigned char to) { J8Rel(0x7E, to); } /* jne rel8 */ u8* JNE8(unsigned char to) { J8Rel(0x75, to); } /* jnz rel8 */ u8* JNZ8(unsigned char to) { J8Rel(0x75, to); } /* jng rel8 */ u8* JNG8(unsigned char to) { J8Rel(0x7E, to); } /* jnge rel8 */ u8* JNGE8(unsigned char to) { J8Rel(0x7C, to); } /* jnl rel8 */ u8* JNL8(unsigned char to) { J8Rel(0x7D, to); } /* jnle rel8 */ u8* JNLE8(unsigned char to) { J8Rel(0x7F, to); } /* call func */ void CALLFunc(u32 func) { CALL32(func - ((u32)x86Ptr + 5)); } /* call rel32 */ void CALL32(u32 to) { write8(0xE8); write32(to); } /* call r32 */ void CALL32R(int to) { write8(0xFF); ModRM(3, 2, to); } // misc instructions /* cmp imm32 to r32 */ void CMP32ItoR(int to, u32 from) { if (to == EAX) { write8(0x3D); } else { write8(0x81); ModRM(3, 7, to); } write32(from); } /* cmp imm32 to m32 */ void CMP32ItoM(u32 to, u32 from) { write8(0x81); ModRM(0, 7, DISP32); write32(to); write32(from); } /* cmp r32 to r32 */ void CMP32RtoR(int to, int from) { write8(0x39); ModRM(3, from, to); } /* cmp m32 to r32 */ void CMP32MtoR(int to, u32 from) { write8(0x3B); ModRM(0, to, DISP32); write32(from); } /* test imm32 to r32 */ void TEST32ItoR(int to, u32 from) { if (to == EAX) { write8(0xA9); } else { write8(0xF7); ModRM(3, 0, to); } write32(from); } /* test r32 to r32 */ void TEST32RtoR(int to, int from) { write8(0x85); ModRM(3, from, to); } /* setl r8 */ void SETL8R(int to) { SET8R(0x9C, to); } /* setb r8 */ void SETB8R(int to) { SET8R(0x92, to); } /* cbw */ void CBW() { write16(0x9866); } /* cwd */ void CWD() { write8(0x98); } /* cdq */ void CDQ() { write8(0x99); } /* push r32 */ void PUSH32R(int from) { write8(0x50 | from); } /* push m32 */ void PUSH32M(u32 from) { write8(0xFF); ModRM(0, 6, DISP32); write32(from); } /* push imm32 */ void PUSH32I(u32 from) { write8(0x68); write32(from); } /* pop r32 */ void POP32R(int from) { write8(0x58 | from); } /* pushad */ void PUSHA32() { write8(0x60); } /* popad */ void POPA32() { write8(0x61); } /* ret */ void RET() { write8(0xC3); } /********************/ /* FPU instructions */ /********************/ /* fild m32 to fpu reg stack */ void FILD32(u32 from) { write8(0xDB); ModRM(0, 0x0, DISP32); write32(from); } /* fistp m32 from fpu reg stack */ void FISTP32(u32 from) { write8(0xDB); ModRM(0, 0x3, DISP32); write32(from); } /* fld m32 to fpu reg stack */ void FLD32(u32 from) { write8(0xD9); ModRM(0, 0x0, DISP32); write32(from); } /* fstp m32 from fpu reg stack */ void FSTP32(u32 to) { write8(0xD9); ModRM(0, 0x3, DISP32); write32(to); } // /* fldcw fpu control word from m16 */ void FLDCW(u32 from) { write8(0xD9); ModRM(0, 0x5, DISP32); write32(from); } /* fnstcw fpu control word to m16 */ void FNSTCW(u32 to) { write8(0xD9); ModRM(0, 0x7, DISP32); write32(to); } // /* fadd m32 to fpu reg stack */ void FADD32(u32 from) { write8(0xD8); ModRM(0, 0x0, DISP32); write32(from); } /* fsub m32 to fpu reg stack */ void FSUB32(u32 from) { write8(0xD8); ModRM(0, 0x4, DISP32); write32(from); } /* fmul m32 to fpu reg stack */ void FMUL32(u32 from) { write8(0xD8); ModRM(0, 0x1, DISP32); write32(from); } /* fdiv m32 to fpu reg stack */ void FDIV32(u32 from) { write8(0xD8); ModRM(0, 0x6, DISP32); write32(from); } /* fabs fpu reg stack */ void FABS() { write16(0xE1D9); } /* fsqrt fpu reg stack */ void FSQRT() { write16(0xFAD9); } /* fchs fpu reg stack */ void FCHS() { write16(0xE0D9); } /********************/ /* MMX instructions */ /********************/ // r64 = mm /* movq m64 to r64 */ void MOVQMtoR(int to, u32 from) { write16(0x6F0F); ModRM(0, to, DISP32); write32(from); } /* movq r64 to m64 */ void MOVQRtoM(u32 to, int from) { write16(0x7F0F); ModRM(0, from, DISP32); write32(to); } /* pand r64 to r64 */ void PANDRtoR(int to, int from) { write16(0xDB0F); ModRM(3, to, from); } /* por r64 to r64 */ void PORRtoR(int to, int from) { write16(0xEB0F); ModRM(3, to, from); } /* por m64 to r64 */ void PORMtoR(int to, u32 from) { write16(0xEB0F); ModRM(0, to, DISP32); write32(from); } /* pxor r64 to r64 */ void PXORRtoR(int to, int from) { write16(0xEF0F); ModRM(3, to, from); } /* psllq r64 to r64 */ void PSLLQRtoR(int to, int from) { write16(0xF30F); ModRM(3, to, from); } /* psllq m64 to r64 */ void PSLLQMtoR(int to, u32 from) { write16(0xF30F); ModRM(0, to, DISP32); write32(from); } /* psllq imm8 to r64 */ void PSLLQItoR(int to, unsigned char from) { write16(0x730F); ModRM(3, 6, to); write8(from); } /* psrlq r64 to r64 */ void PSRLQRtoR(int to, int from) { write16(0xD30F); ModRM(3, to, from); } /* psrlq m64 to r64 */ void PSRLQMtoR(int to, u32 from) { write16(0xD30F); ModRM(0, to, DISP32); write32(from); } /* psrlq imm8 to r64 */ void PSRLQItoR(int to, unsigned char from) { write16(0x730F); ModRM(3, 2, to); write8(from); } /* paddusb r64 to r64 */ void PADDUSBRtoR(int to, int from) { write16(0xDC0F); ModRM(3, to, from); } /* paddusb m64 to r64 */ void PADDUSBMtoR(int to, u32 from) { write16(0xDC0F); ModRM(0, to, DISP32); write32(from); } /* paddusw r64 to r64 */ void PADDUSWRtoR(int to, int from) { write16(0xDD0F); ModRM(3, to, from); } /* paddusw m64 to r64 */ void PADDUSWMtoR(int to, u32 from) { write16(0xDD0F); ModRM(0, to, DISP32); write32(from); } /* paddb r64 to r64 */ void PADDBRtoR(int to, int from) { write16(0xFC0F); ModRM(3, to, from); } /* paddb m64 to r64 */ void PADDBMtoR(int to, u32 from) { write16(0xFC0F); ModRM(0, to, DISP32); write32(from); } /* paddw r64 to r64 */ void PADDWRtoR(int to, int from) { write16(0xFD0F); ModRM(3, to, from); } /* paddw m64 to r64 */ void PADDWMtoR(int to, u32 from) { write16(0xFD0F); ModRM(0, to, DISP32); write32(from); } /* paddd r64 to r64 */ void PADDDRtoR(int to, int from) { write16(0xFE0F); ModRM(3, to, from); } /* paddd m64 to r64 */ void PADDDMtoR(int to, u32 from) { write16(0xFE0F); ModRM(0, to, DISP32); write32(from); } /* emms */ void EMMS() { write16(0x770F); }