/* Copyright (C) 2001,2005 StrmnNrmn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Base/Types.h" #include "AssemblyWriterX64.h" //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::PUSH(EIntelReg reg) { if (reg >= R8_CODE) { EmitBYTE(0x41); EmitBYTE(0x50 | (reg & 7)); } else { EmitBYTE(0x50 | reg); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::POP(EIntelReg reg) { if (reg >= R8_CODE) { EmitBYTE(0x41); EmitBYTE(0x58 | (reg & 7)); } else { EmitBYTE(0x58 | reg); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::PUSHI( u32 value ) { EmitBYTE( 0x68 ); EmitDWORD( value ); } //***************************************************************************** // add reg1, reg2 //***************************************************************************** void CAssemblyWriterX64::ADD(EIntelReg reg1, EIntelReg reg2, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x03); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // sub reg1, reg2 //***************************************************************************** void CAssemblyWriterX64::SUB(EIntelReg reg1, EIntelReg reg2, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x2b); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MUL_EAX_MEM(u32 * mem) { EmitBYTE(0xf7); EmitBYTE(0xa3); EmitADDR(mem); // mul DWORD PTR [rbx+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MUL(EIntelReg reg) { EmitBYTE(0xf7); EmitBYTE(0xe0 | reg); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::ADD_REG_MEM_IDXx4( EIntelReg destreg, u32 * mem, EIntelReg idxreg ) { EmitBYTE(0x03); EmitBYTE(0x84 | (destreg << 3)); EmitBYTE(0x83 | (idxreg<<3)); EmitADDR(mem); // 03 84 83 12 34 56 79 add eax,DWORD PTR [rbx+rax*4+0x79563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::AND(EIntelReg reg1, EIntelReg reg2, bool is64) { if (reg1 != reg2) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x23); EmitBYTE(0xc0 | (reg1<<3) | reg2); } } //***************************************************************************** // and eax, 0x00FF - Mask off top bits! // This is slightly more efficient than ANDI( EAX_CODE, data ) //***************************************************************************** void CAssemblyWriterX64::AND_EAX( u32 mask ) { EmitBYTE(0x25); EmitDWORD(mask); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::OR(EIntelReg reg1, EIntelReg reg2, bool is64) { if (reg1 != reg2) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x0B); EmitBYTE(0xc0 | (reg1<<3) | reg2); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::XOR(EIntelReg reg1, EIntelReg reg2, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x33); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::NOT(EIntelReg reg1, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0xf7); EmitBYTE(0xd0 | reg1); } //***************************************************************************** // Use short form (0x83c0) if data is just one byte! //***************************************************************************** void CAssemblyWriterX64::ADDI(EIntelReg reg, s32 data, bool is64) { if (data == 0) return; if (is64) { u8 first_byte = 0x48; if (reg >= R8_CODE) { first_byte |= 0x4; reg = EIntelReg(reg & 7); } EmitBYTE(first_byte); } if (data <= 127 && data > -127) { EmitBYTE(0x83); EmitBYTE(0xc0 | reg); EmitBYTE((u8)data); } else { EmitBYTE(0x81); EmitBYTE(0xc0 | reg); EmitDWORD(data); } } //***************************************************************************** // Use short form (0x83c0) if data is just one byte! //***************************************************************************** void CAssemblyWriterX64::SUBI(EIntelReg reg, s32 data, bool is64) { if (data == 0) return; if (is64) { u8 first_byte = 0x48; if (reg >= R8_CODE) { first_byte |= 0x4; reg = EIntelReg(reg & 7); } EmitBYTE(first_byte); } if (data <= 127 && data > -127) { EmitBYTE(0x83); EmitBYTE(0xe8 | reg); EmitBYTE((u8)data); } else { EmitBYTE(0x81); EmitBYTE(0xe8 | reg); EmitDWORD(data); } } //***************************************************************************** // Use short form (0x83d0) if data is just one byte! //***************************************************************************** void CAssemblyWriterX64::ADCI(EIntelReg reg, s32 data) { /*if (reg == EAX_CODE) { EmitBYTE(0x15); EmitDWORD(data) } else*/ if (data <= 127 && data > -127) { EmitBYTE(0x83); EmitBYTE(0xd0 | reg); EmitBYTE((u8)(data)); } else { EmitBYTE(0x81); EmitBYTE(0xd0 | reg); EmitDWORD(data); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::ANDI(EIntelReg reg1, u32 data, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } /*if (reg == EAX_CODE) EmitBYTE(0x25); else */ { EmitBYTE(0x81); EmitBYTE(0xe0 | reg1); } EmitDWORD(data); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::ORI(EIntelReg reg1, u32 data, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } /*if (reg == EAX_CODE) EmitBYTE(0x0D); else*/ { EmitBYTE(0x81); EmitBYTE(0xc8 | reg1); } EmitDWORD(data); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::XORI(EIntelReg reg, u32 data, bool is64) { if (is64) { u8 first_byte = 0x48; if (reg >= R8_CODE) { first_byte |= 0x4; reg = EIntelReg(reg & 7); } EmitBYTE(first_byte); } if (data <= 255) { EmitBYTE(0x83); EmitBYTE(0xf0 | reg); EmitBYTE((u8)data); } else { EmitBYTE(0x81); EmitBYTE(0xf0 | reg); EmitDWORD(data); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::SHLI(EIntelReg reg, u8 sa) { EmitBYTE(0xc1); EmitBYTE(0xe0 | reg); EmitBYTE(sa); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::SHRI(EIntelReg reg, u8 sa) { EmitBYTE(0xc1); EmitBYTE(0xe8 | reg); EmitBYTE(sa); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::SARI(EIntelReg reg, u8 sa) { EmitBYTE(0xc1); EmitBYTE(0xf8 | reg); EmitBYTE(sa); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::CMP(EIntelReg reg1, EIntelReg reg2) { EmitBYTE(0x3b); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::TEST(EIntelReg reg1, EIntelReg reg2) { EmitBYTE(0x85); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // test ah, 41 //***************************************************************************** void CAssemblyWriterX64::TEST_AH( u8 flags ) { EmitBYTE(0xf6); EmitBYTE(0xc4); EmitBYTE(flags); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::CMPI(EIntelReg reg, u32 data) { EmitBYTE(0x81); EmitBYTE(0xf8 | reg); EmitDWORD(data); } //***************************************************************************** // cmp dword ptr p_mem, data //***************************************************************************** void CAssemblyWriterX64::CMP_MEM32_I32(const u32 *p_mem, u32 data) { EmitBYTE(0x81); EmitBYTE(0xbb); EmitADDR(p_mem); // 0: 81 bb 12 34 56 78 12 cmp DWORD PTR [rbx+0x78563412],0x78563412 // 7: 34 56 78 EmitDWORD(data); } //***************************************************************************** // cmp dword ptr p_mem, data //***************************************************************************** void CAssemblyWriterX64::CMP_MEM32_I8(const u32 *p_mem, u8 data) { EmitBYTE(0x83); EmitBYTE(0xbb); EmitADDR(p_mem); // 83 bb 12 34 56 78 12 cmp DWORD PTR [rbx+0x78563412],0x12 EmitBYTE(data); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::SETL(EIntelReg reg) { EmitWORD(0x9c0f); EmitBYTE(0xc0 | reg); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::SETB(EIntelReg reg) { EmitWORD(0x920f); EmitBYTE(0xc0 | reg); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JS(s32 off) { EmitBYTE(0x0f); EmitBYTE(0x88); EmitDWORD( u32(off) ); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JA(u8 off) { EmitWORD((off<<8) | 0x77); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JB(u8 off) { EmitWORD((off<<8) | 0x72); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JAE(u8 off) { EmitWORD((off<<8) | 0x73); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JE(u8 off) { EmitWORD((off<<8) | 0x74); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JNE(u8 off) { EmitWORD((off<<8) | 0x75); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JL(u8 off) { EmitWORD((off<<8) | 0x7C); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JGE(u8 off) { EmitWORD((off<<8) | 0x7D); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JLE(u8 off) { EmitWORD((off<<8) | 0x7E); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JG(u8 off) { EmitWORD((off<<8) | 0x7F); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JMP_SHORT(u8 off) { EmitWORD((off<<8) | 0xeb); } //***************************************************************************** // //***************************************************************************** CJumpLocation CAssemblyWriterX64::JumpConditionalLong( CCodeLabel target, u8 jump_type ) { const u32 JUMP_LONG_LENGTH = 6; CJumpLocation jump_location( mpAssemblyBuffer->GetJumpLocation() ); s32 offset( jump_location.GetOffset( target ) - JUMP_LONG_LENGTH ); EmitBYTE( 0x0f ); EmitBYTE( jump_type ); // EmitDWORD( offset ); return jump_location; } //***************************************************************************** // //***************************************************************************** CJumpLocation CAssemblyWriterX64::JELong( CCodeLabel target ) { return JumpConditionalLong( target, 0x84 ); } //***************************************************************************** // //***************************************************************************** CJumpLocation CAssemblyWriterX64::JNELong( CCodeLabel target ) { return JumpConditionalLong( target, 0x85 ); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::JMP_REG( EIntelReg reg ) { EmitWORD( ((0xe0|reg)<<8) | 0xff ); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::CALL_REG( EIntelReg reg ) { EmitWORD(((0xd0|reg)<<8) | 0xff); } //***************************************************************************** // //***************************************************************************** CJumpLocation CAssemblyWriterX64::CALL( CCodeLabel target ) { const u32 CALL_LONG_LENGTH = 5; #ifdef DAEDALUS_W32 SUBI(RSP_CODE, 32, true); #endif CJumpLocation jump_location( mpAssemblyBuffer->GetJumpLocation() ); CJumpLocation rbx_location(&gCPUState); if (jump_location.IsIn32BitRange(target)) { s32 offset( jump_location.GetOffset( target ) - CALL_LONG_LENGTH ); EmitBYTE( 0xe8 ); EmitDWORD( offset ); } else if (rbx_location.IsIn32BitRange(target)) { LEA(RAX_CODE, target.GetTargetU8P()); EmitWORD(0xd0ff); } #ifdef DAEDALUS_W32 ADDI(RSP_CODE, 32, true); #endif return jump_location; } //***************************************************************************** // //***************************************************************************** CJumpLocation CAssemblyWriterX64::JMPLong( CCodeLabel target ) { const u32 JUMP_DIRECT_LONG_LENGTH = 5; CJumpLocation jump_location( mpAssemblyBuffer->GetJumpLocation() ); s32 offset( jump_location.GetOffset( target ) - JUMP_DIRECT_LONG_LENGTH ); EmitBYTE(0xe9); EmitDWORD( static_cast< u32 >( offset ) ); return jump_location; } //***************************************************************************** // call dword ptr [mem + reg*4] //***************************************************************************** void CAssemblyWriterX64::CALL_MEM_PLUS_REGx4( void * mem, EIntelReg reg ) { EmitBYTE(0xFF); EmitBYTE(0x94); EmitBYTE(0x83 | (reg<<3)); EmitADDR(mem); // ff 94 83 12 34 56 78 call QWORD PTR [rbx+rax*4+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::RET() { EmitBYTE(0xC3); } //***************************************************************************** // mov reg1, reg2 //***************************************************************************** void CAssemblyWriterX64::MOV(EIntelReg reg1, EIntelReg reg2, bool is64) { if (reg1 != reg2) { if (is64) { u8 first_byte = 0x48; if (reg2 >= R8_CODE) { first_byte |= 0x1; reg2 = EIntelReg(reg2 & 7); } if (reg1 >= R8_CODE) { first_byte |= 0x4; reg1 = EIntelReg(reg1 & 7); } EmitBYTE(first_byte); } EmitBYTE(0x8b); EmitBYTE(0xc0 | (reg1<<3) | reg2); } } //***************************************************************************** // movsx reg1, reg2 //***************************************************************************** void CAssemblyWriterX64::MOVSX(EIntelReg reg1, EIntelReg reg2, bool _8bit) { EmitBYTE(0x0f); EmitBYTE(_8bit ? 0xBE : 0xBF); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // movzx reg1, reg2 //***************************************************************************** void CAssemblyWriterX64::MOVZX(EIntelReg reg1, EIntelReg reg2, bool _8bit) { EmitBYTE(0x0f); EmitBYTE(_8bit ? 0xB6 : 0xB7); EmitBYTE(0xc0 | (reg1<<3) | reg2); } //***************************************************************************** // mov dword ptr[ mem ], reg //***************************************************************************** void CAssemblyWriterX64::MOV_MEM_REG(u32 * mem, EIntelReg isrc) { /*if (reg == EAX_CODE) EmitBYTE(0xa3); else*/ { EmitBYTE(0x89); EmitBYTE((isrc<<3) | 0x83); } EmitADDR(mem); // 89 83 12 34 56 78 mov DWORD PTR [rbx+0x78563412],eax } //***************************************************************************** // mov qword ptr[ mem ], reg //***************************************************************************** void CAssemblyWriterX64::MOV64_MEM_REG(u64 * mem, EIntelReg isrc) { EmitBYTE(0x48); /*if (reg == EAX_CODE) EmitBYTE(0xa3); else*/ { EmitBYTE(0x89); EmitBYTE((isrc<<3) | 0x83); } EmitADDR(mem); // 48 89 83 12 34 56 78 mov QWORD PTR [rbx+0x78563412],rax } //***************************************************************************** // mov reg, qword ptr[ mem ] //***************************************************************************** void CAssemblyWriterX64::MOV64_REG_MEM(EIntelReg reg, const u64 * mem) { EmitBYTE(0x48); /*if (reg == EAX_CODE) EmitBYTE(0xa1); else*/ { EmitBYTE(0x8b); EmitBYTE((reg<<3) | 0x83); } EmitADDR(mem); // 48 8b 83 12 34 56 78 mov rax,QWORD PTR [rbx+0x78563412] } //***************************************************************************** // mov reg, dword ptr[ mem ] //***************************************************************************** void CAssemblyWriterX64::MOV_REG_MEM(EIntelReg reg, const u32 * mem) { /*if (reg == EAX_CODE) EmitBYTE(0xa1); else*/ { EmitBYTE(0x8b); EmitBYTE((reg<<3) | 0x83); } EmitADDR(mem); // 8b 83 12 34 56 78 mov eax,DWORD PTR [rbx+0x78563412] } //***************************************************************************** // mov byte ptr [base], src //***************************************************************************** void CAssemblyWriterX64::MOV8_MEM_BASE_REG( EIntelReg ibase, EIntelReg isrc ) { DAEDALUS_ASSERT( IsValidMov8Reg( isrc ), "Invalid source register for 8 bit move" ); EmitBYTE(0x88); EmitBYTE(0x00 | (isrc<<3) | ibase); } //***************************************************************************** // mov dst, byte ptr [base] //***************************************************************************** void CAssemblyWriterX64::MOV8_REG_MEM_BASE( EIntelReg idst, EIntelReg ibase ) { DAEDALUS_ASSERT( IsValidMov8Reg( idst ), "Invalid destination register for 8 bit move" ); EmitBYTE(0x8A); EmitBYTE(0x00 | (idst<<3) | ibase); } //***************************************************************************** // mov word ptr [base], src //***************************************************************************** void CAssemblyWriterX64::MOV16_MEM_BASE_REG( EIntelReg ibase, EIntelReg isrc ) { EmitBYTE(0x66); EmitBYTE(0x89); EmitBYTE(0x00 | (isrc<<3) | ibase); } //***************************************************************************** // mov dst, word ptr[base] e.g. mov ax, word ptr [eax] //***************************************************************************** void CAssemblyWriterX64::MOV16_REG_MEM_BASE( EIntelReg idst, EIntelReg ibase ) { EmitBYTE(0x66); EmitBYTE(0x8B); EmitBYTE(0x00 | (idst<<3) | ibase); } //***************************************************************************** // mov dword ptr [base + nnnnnnnn], src //***************************************************************************** void CAssemblyWriterX64::MOV_MEM_BASE_OFFSET32_REG( EIntelReg ibase, s32 offset, EIntelReg isrc ) { EmitBYTE(0x89); EmitBYTE(0x80 | (isrc<<3) | ibase); EmitDWORD((u32)offset); } //***************************************************************************** // mov dword ptr [base + nn], src //***************************************************************************** void CAssemblyWriterX64::MOV_MEM_BASE_OFFSET8_REG( EIntelReg ibase, s8 offset, EIntelReg isrc ) { EmitBYTE(0x89); EmitBYTE(0x40 | (isrc<<3) | ibase); EmitBYTE((u8)offset); } //***************************************************************************** // mov dword ptr [base], src //***************************************************************************** void CAssemblyWriterX64::MOV_MEM_BASE_REG( EIntelReg ibase, EIntelReg isrc ) { EmitBYTE(0x89); EmitBYTE(0x00 | (isrc<<3) | ibase); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MOV_MEM_BASE_OFFSET_REG( EIntelReg ibase, s32 offset, EIntelReg isrc ) { if(offset == 0) { MOV_MEM_BASE_REG( ibase, isrc ); } else if (offset < 128 && offset > -128) { MOV_MEM_BASE_OFFSET8_REG( ibase, (s8)offset, isrc ); } else { MOV_MEM_BASE_OFFSET32_REG( ibase, offset, isrc ); } } //***************************************************************************** // mov dst, dword ptr [base + nnnnnnnn] //***************************************************************************** void CAssemblyWriterX64::MOV_REG_MEM_BASE_OFFSET32( EIntelReg idst, EIntelReg ibase, s32 offset ) { EmitBYTE(0x8B); EmitBYTE(0x80 | (idst<<3) | ibase); EmitDWORD((u32)offset); } //***************************************************************************** // mov dst, dword ptr [base + nn] //***************************************************************************** void CAssemblyWriterX64::MOV_REG_MEM_BASE_OFFSET8( EIntelReg idst, EIntelReg ibase, s8 offset ) { EmitBYTE(0x8B); EmitBYTE(0x40 | (idst<<3) | ibase); EmitBYTE((u8)offset); } //***************************************************************************** // mov dst, dword ptr [base] //***************************************************************************** void CAssemblyWriterX64::MOV_REG_MEM_BASE( EIntelReg idst, EIntelReg ibase ) { EmitBYTE(0x8B); EmitBYTE(0x00 | (idst<<3) | ibase); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MOV_REG_MEM_BASE_OFFSET( EIntelReg idst, EIntelReg ibase, s32 offset ) { if(offset == 0) { MOV_REG_MEM_BASE( idst, ibase ); } else if(offset < 128 && offset > -128) { MOV_REG_MEM_BASE_OFFSET8( idst, ibase, (s8)offset ); } else { MOV_REG_MEM_BASE_OFFSET32( idst, ibase, offset ); } } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MOVI(EIntelReg reg, u32 data) { EmitBYTE(0xB8 | reg); EmitDWORD(data); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MOVI_64(EIntelReg reg, u64 data) { // 0: 48 b8 78 56 34 12 78 movabs rax,0x1234567812345678 // 7: 56 34 12 EmitBYTE(0x48); EmitBYTE(0xB8 | reg); EmitQWORD(data); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::MOVI_MEM(u32 * mem, u32 data) { EmitBYTE(0xc7); EmitBYTE(0x83); EmitADDR(mem); // 0: c7 83 12 34 56 78 12 mov DWORD PTR [rbx+0x78563412],0x78563412 // 7: 34 56 78 EmitDWORD(data); } //***************************************************************************** // mov byte ptr mem, data //***************************************************************************** void CAssemblyWriterX64::MOVI_MEM8(u32 * mem, u8 data) { EmitBYTE(0xc6); EmitBYTE(0x83); EmitADDR(mem); //0: c6 83 12 34 56 78 12 mov BYTE PTR [rbx+0x78563412],0x12 EmitBYTE(data); } //***************************************************************************** // movsx dst, src (e.g. movsx eax, al) //***************************************************************************** void CAssemblyWriterX64::MOVSX8( EIntelReg idst, EIntelReg isrc ) { DAEDALUS_ASSERT( IsValidMov8Reg( isrc ), "Invalid source register for 8 bit move" ); EmitBYTE(0x0F); EmitBYTE(0xBE); EmitBYTE(0xC0 | (idst<<3) | isrc); } //***************************************************************************** // movsx dst, src (e.g. movsx eax, ax) //***************************************************************************** void CAssemblyWriterX64::MOVSX16( EIntelReg idst, EIntelReg isrc ) { EmitBYTE(0x0F); EmitBYTE(0xBF); EmitBYTE(0xC0 | (idst<<3) | isrc); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FSQRT() { EmitWORD(0xfad9); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FCHS() { EmitWORD(0xe0d9); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FILD_MEM( u32 * pmem ) { EmitWORD(0x83db); EmitADDR(pmem); // 0: db 83 12 34 56 78 fild DWORD PTR [rbx+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FLD_MEMp32( u32 * pmem ) { EmitWORD(0x83d9); EmitADDR(pmem); // d9 83 12 34 56 78 fld DWORD PTR [rbx+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FSTP_MEMp32( u32 * pmem ) { EmitWORD( 0x9bd9); EmitADDR(pmem); // 0: d9 9b 12 34 56 78 fstp DWORD PTR [rbx+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FLD_MEMp64( u64 * mem) { EmitWORD(0xabdf); EmitADDR(mem); // df ab 78 56 34 12 fild QWORD PTR [rbx+0x12345678] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FSTP_MEMp64( u64 * mem) { EmitWORD(0x9bdd); EmitADDR(mem); // dd 9b 78 56 34 12 fstp QWORD PTR [rbx+0x12345678] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FISTP_MEMp( u32 * pmem ) { EmitWORD( 0x9bdb ); EmitADDR(pmem); // db 9b 12 34 56 78 fistp DWORD PTR [rbx+0x78563412] } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FLD( u32 i ) { EmitWORD((u16)((0xc0 + (i))<<8) |(0xd9)); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FXCH( u32 i ) { EmitWORD((u16)((0xc8 + (i))<<8) |(0xd9)); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FCOMP( u32 i ) { EmitWORD((u16)((0xd8 + (i))<<8) |(0xd8)); } //***************************************************************************** //fnstsw ax //***************************************************************************** void CAssemblyWriterX64::FNSTSW() { EmitWORD(0xe0df); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FFREE( u32 i ) { EmitWORD((u16)((0xc0 + (i))<<8) |(0xdd)); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FINCSTP() { EmitWORD(0xf7d9); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FSQRTp() { EmitWORD(0xfad9); } //***************************************************************************** // //***************************************************************************** void CAssemblyWriterX64::FCHSp() { EmitWORD(0xe0d9); } //***************************************************************************** // fadd st(0),st(i) //***************************************************************************** void CAssemblyWriterX64::FADD( u32 i ) { EmitWORD((u16)((0xc0 + (i))<<8) |(0xd8)); } //***************************************************************************** // fsub st(0),st(i) //***************************************************************************** void CAssemblyWriterX64::FSUB( u32 i ) { EmitWORD((u16)((0xe0 + (i))<<8) |(0xd8)); } //***************************************************************************** // fmul st(0),st(i) //***************************************************************************** void CAssemblyWriterX64::FMUL( u32 i ) { EmitWORD((u16)((0xc8 + (i))<<8) |(0xd8)); } //***************************************************************************** // fdiv st(0),st(i) //***************************************************************************** void CAssemblyWriterX64::FDIV( u32 i ) { EmitWORD((u16)((0xf0 + (i))<<8) |(0xd8)); } void CAssemblyWriterX64::CDQ() { EmitBYTE(0x99); } void CAssemblyWriterX64::LEA(EIntelReg reg, const void* mem) { EmitBYTE(0x48); EmitBYTE(0x8d); EmitBYTE(0x83 | (reg << 3)); EmitADDR(mem); // 0: 48 8d 83 12 34 56 78 lea rax,[rbx+0x78563412] }