/// <summary> /// Push function argument /// </summary> /// <param name="arg">Argument.</param> /// <param name="regidx">Push type(register or stack)</param> void AsmHelper64::PushArg( const AsmVariant& arg, size_t index ) { switch (arg.type) { case AsmVariant::imm: case AsmVariant::structRet: PushArgp( arg.imm_val, index ); break; case AsmVariant::dataPtr: case AsmVariant::dataStruct: PushArgp( arg.new_imm_val, index ); break; case AsmVariant::imm_double: PushArgp( arg.getImm_double(), index, true ); break; case AsmVariant::imm_float: PushArgp( arg.getImm_float(), index, true ); break; case AsmVariant::mem_ptr: _assembler.lea( asmjit::host::rax, arg.mem_val ); PushArgp( asmjit::host::rax, index ); break; case AsmVariant::mem: PushArgp( arg.mem_val, index ); break; case AsmVariant::reg: PushArgp( arg.reg_val, index ); break; default: assert( "Invalid argument type" && false ); break; } }
/// <summary> /// Push function argument /// </summary> /// <param name="arg">Argument.</param> /// <param name="regidx">Push type(register or stack)</param> void AsmHelper32::PushArg( const AsmVariant& arg, eArgType regidx /*= AT_stack*/ ) { switch (arg.type) { case AsmVariant::imm: case AsmVariant::structRet: // TODO: resolve 64bit imm values instead of ignoring high bits PushArgp( arg.imm_val, regidx ); break; case AsmVariant::dataPtr: PushArgp( arg.new_imm_val, regidx ); break; // Copy argument onto stack case AsmVariant::dataStruct: { // Ensure stack remain aligned on word size size_t realSize = Align( arg.size, sizeof( uint32_t ) ); _assembler.sub( asmjit::host::esp, realSize ); _assembler.mov( asmjit::host::esi, arg.new_imm_val ); _assembler.mov( asmjit::host::edi, asmjit::host::esp); // Preserve ecx value, may be __thiscall or __fastcall function _assembler.mov( asmjit::host::eax, asmjit::host::ecx ); _assembler.mov( asmjit::host::ecx, arg.size ); _assembler.rep_movsb(); // Restore registers _assembler.mov( asmjit::host::ecx, asmjit::host::eax ); } break; case AsmVariant::imm_double: { ULARGE_INTEGER li; li.QuadPart = arg.getImm_double(); PushArgp( static_cast<uint32_t>(li.HighPart), regidx ); PushArgp( static_cast<uint32_t>(li.LowPart), regidx ); } break; case AsmVariant::imm_float: PushArgp( arg.getImm_float(), regidx ); break; case AsmVariant::mem_ptr: _assembler.lea( asmjit::host::eax, arg.mem_val ); PushArgp( asmjit::host::eax, regidx ); break; case AsmVariant::mem: PushArgp( arg.mem_val, regidx ); break; case AsmVariant::reg: PushArgp( arg.reg_val, regidx ); break; default: assert( "Invalid argument type" && false ); break; } }