예제 #1
0
/// <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;
    }
}
예제 #2
0
/// <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;
    }
}