disx86.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,201 行 · 第 1/5 页

C
2,201
字号

    if( dir ) {
        X86GetXMM( reg, ins );
        X86XMMGetModRM( w, mod, rm, d, ins, ref_type );
    } else {
        X86XMMGetModRM( w, mod, rm, d, ins, ref_type );
        X86GetXMM( reg, ins );
    }
}

void X86GetRegModRM_B( DBIT dir, MOD mod, RM rm, RM reg, void *d, dis_dec_ins *ins )
/**********************************************************************/
//    dir                   1                 0
//   Destination           Reg              MODRM
//   Source               MODRM              Reg
{
    if( dir ) {
        X86GetReg( W_DEFAULT, reg, ins );
        X86GetModRM( W_DEFAULT, mod, rm, d, ins, X86GetRefType( W_DEFAULT ,ins ) );
    } else {
        X86GetModRM( W_DEFAULT, mod, rm, d, ins, X86GetRefType( W_DEFAULT ,ins ) );
        X86GetReg( W_DEFAULT, reg, ins );
    }
}



/*=====================================================================*/
/*                8-BIT OPCODE FUNCTIONS                               */
/*=====================================================================*/



typedef union {
    unsigned_32 full;
    struct {
        unsigned_32 w  : 1;
        unsigned_32 dir: 1;
        unsigned_32 op1: 6;
    } type1;
    struct {
        unsigned_32 reg: 3;
        unsigned_32 w  : 1;
        unsigned_32 op1: 4;
    } type2;
    struct {
        unsigned_32 w  : 1;
        unsigned_32 s  : 1;
        unsigned_32 op1: 6;
    } type3;
    struct {
        unsigned_32 op2: 3;
        unsigned_32 sreg:2;
        unsigned_32 op1: 3;
    } sreg;
} code_8;


dis_handler_return X86SReg_8( dis_handle *h, void *d, dis_dec_ins *ins )
/*********************************************************************
 *  OOO SS OOO
 *     sreg
 */
{
    code_8 code;

    code.full = ins->opcode;
    ins->size    += 1;
    ins->num_ops = 0;

    switch( ins->type ) {
    case DI_X86_push3:
        ins->op[ins->num_ops].base = X86GetRegister( W_DEFAULT, REG_SP, ins );
        ins->op[ins->num_ops].type = DO_MEMORY_ABS | DO_HIDDEN;
        ins->op[ins->num_ops].ref_type = X86GetRefType( W_DEFAULT, ins );
        ++ins->num_ops;
        break;
    default:
        break;
    }
    X86GetSReg(W_DEFAULT, code.sreg.sreg, ins);
    switch( ins->type ) {
    case DI_X86_pop3d:
    case DI_X86_pop3e:
    case DI_X86_pop3s:
        ins->op[ins->num_ops].base = X86GetRegister( W_DEFAULT, REG_SP, ins );
        ins->op[ins->num_ops].type = DO_MEMORY_ABS | DO_HIDDEN;
        ins->op[ins->num_ops].ref_type = X86GetRefType( W_DEFAULT, ins );
        ++ins->num_ops;
        break;
    default:
        break;
    }
#if 0
    if( DIF_X86_OPND_SIZE & ins->flags ) {
        if( DIF_X86_OPND_LONG & ins->flags ) {
            switch( ins->type ) {
            case DI_X86_push3:
                ins->type = DI_X86_pushd;
                break;
            default:
                break;
            }
        } else {
            switch( ins->type ) {
            case DI_X86_push3:
                ins->type = DI_X86_pushw;
                break;
            default:
                break;
            }
        }
    }
#endif
    return( DHR_DONE );
}

dis_handler_return X86NoOp_8( dis_handle *h, void *d, dis_dec_ins *ins )
/*********************************************************************
 *  OOOO OOOW
 */
{
    code_8 code;

    code.full = ins->opcode;
    ins->size    += 1;
    ins->num_ops = 0;

    switch( ins->type ) {
    case DI_X86_popa:
    case DI_X86_popf:
    case DI_X86_pusha:
    case DI_X86_pushf:
        ins->op[ins->num_ops].base = X86GetRegister( W_DEFAULT, REG_SP, ins );
        ins->op[ins->num_ops].type = DO_MEMORY_ABS | DO_HIDDEN;
        ins->op[ins->num_ops].ref_type = X86GetRefType( W_DEFAULT, ins );
        ++ins->num_ops;
        break;
    case DI_X86_xlat:
        if( DIF_X86_ADDR_LONG & ins->flags ) {
            ins->op[ins->num_ops].base = X86GetRegister_D( W_DEFAULT, REG_BX, ins );
        } else {
            ins->op[ins->num_ops].base = X86GetRegister_W( W_DEFAULT, REG_BX, ins );
        }
        ins->op[ins->num_ops].type = DO_MEMORY_ABS;
        ins->op[ins->num_ops].ref_type = X86GetRefType( W_DEFAULT, ins );
        ++ins->num_ops;
        break;
    default:
        break;
    }

    if( ins->flags & DIF_X86_OPND_LONG ) {
        switch(ins->type) {
        case DI_X86_cbw :
            ins->type = DI_X86_cwde;
            break;
        case DI_X86_cwd :
            ins->type = DI_X86_cdq;
            break;
        case DI_X86_iret:
            ins->type = DI_X86_iretd;
            break;
        case DI_X86_popa:
            ins->type = DI_X86_popad;
            break;
        case DI_X86_popf:
            ins->type = DI_X86_popfd;
            break;
        case DI_X86_pusha:
            ins->type = DI_X86_pushad;
            break;
        case DI_X86_pushf:
            ins->type = DI_X86_pushfd;
            break;
        default:
            break;
        }
    }
    return( DHR_DONE );
}

dis_handler_return X86String_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************
 * String Functions
 *  OOOO OOOW
 */
{
    code_8 code;

    code.full = ins->opcode;
    ins->size += 1;
    ins->num_ops = 2;

    switch( ins->type ) {
    case DI_X86_cmps:
        ins->op[0].base = X86GetRegisterAddr( W_DEFAULT, REG_SI, ins );
        ins->op[0].type = DO_MEMORY_ABS;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->op[1].base = X86GetRegisterAddr( W_DEFAULT, REG_DI, ins );
        ins->op[1].type = DO_MEMORY_ABS | DO_NO_SEG_OVR;
        ins->op[1].ref_type = X86GetRefType( code.type1.w, ins );
        break;
    case DI_X86_movs:
        ins->op[0].base = X86GetRegisterAddr( W_DEFAULT, REG_DI, ins );
        ins->op[0].type = DO_MEMORY_ABS | DO_NO_SEG_OVR;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->op[1].base = X86GetRegisterAddr( W_DEFAULT, REG_SI, ins );
        ins->op[1].type = DO_MEMORY_ABS;
        ins->op[1].ref_type = X86GetRefType( code.type1.w, ins );
        break;
    case DI_X86_ins:
        ins->op[0].base = X86GetRegisterAddr( W_DEFAULT, REG_DI, ins );
        ins->op[0].type = DO_MEMORY_ABS | DO_NO_SEG_OVR;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->op[1].base = DR_X86_dx;
        ins->op[1].type = DO_REG;
        ins->op[1].ref_type = X86GetRefType( code.type1.w, ins );
        break;
    case DI_X86_lods:
        ins->op[0].base = X86GetRegisterAddr( W_DEFAULT, REG_SI, ins );
        ins->op[0].type = DO_MEMORY_ABS;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->num_ops = 1;
        break;
    case DI_X86_outs:
        ins->op[0].base = DR_X86_dx;
        ins->op[0].type = DO_REG;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->op[1].base = X86GetRegisterAddr( W_DEFAULT, REG_SI, ins );
        ins->op[1].type = DO_MEMORY_ABS;
        ins->op[1].ref_type = X86GetRefType( code.type1.w, ins );
        break;
    case DI_X86_stos:
    case DI_X86_scas:
        ins->op[0].base = X86GetRegisterAddr( W_DEFAULT, REG_DI, ins );
        ins->op[0].type = DO_MEMORY_ABS | DO_NO_SEG_OVR;
        ins->op[0].ref_type = X86GetRefType( code.type1.w, ins );
        ins->num_ops = 1;
        break;
    default:
        break;
    }
    return( DHR_DONE );
}

dis_handler_return X86ImmAcc_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************
 * Immediate to Accumulator EAX, AX, or AL
 * Format:    OOOO OOOW
 */
{
    code_8 code;

    code.full    = ins->opcode;
    ins->num_ops = 0;
    ins->size   += 1;
    switch( ins->type ) {
    case DI_X86_in:
        X86GetReg( code.type1.w, REG_AX, ins );
        X86GetImmedVal( S_DEFAULT, W_BYTE, d, ins );
        break;
    case DI_X86_out:
        X86GetImmedVal( S_DEFAULT, W_BYTE, d, ins );
        X86GetReg(code.type1.w, REG_AX, ins);
        break;
    default:
        X86GetReg(code.type1.w, REG_AX, ins);
        X86GetImmedVal( S_DEFAULT, code.type1.w, d, ins  );
        break;
    }
    return( DHR_DONE );
}

dis_handler_return X86MemAbsAcc_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************
 * Absolute Memory to Accumulator
 * Format:    OOOO OODW
 */
{
    code_8 code;

    code.full    = ins->opcode;
    ins->num_ops = 0;
    ins->size   += 1;
    if( code.type1.dir ) {
        ins->op[0].type = DO_MEMORY_ABS;
        ins->op[0].ref_type = X86GetRefType( code.type1.w , ins );
        ins->op[0].op_position = ins->size;
        if( ins->flags & DIF_X86_ADDR_LONG ) {
            ins->op[0].value = GetULong( d, ins->size );
            ins->size += 4;
        } else {
            ins->op[0].value = GetUShort( d, ins->size );
            ins->size   += 2;
        }
        ++ins->num_ops;
        X86GetReg(code.type1.w, REG_AX, ins);
    } else {
        X86GetReg(code.type1.w, REG_AX, ins);
        ins->op[1].type  = DO_MEMORY_ABS;
        ins->op[1].ref_type = X86GetRefType( code.type1.w , ins );
        ins->op[1].op_position = ins->size;
        if( ins->flags & DIF_X86_ADDR_LONG ) {
            ins->op[1].value = GetULong( d, ins->size );
            ins->size += 4;
        } else {
            ins->op[1].value = GetUShort( d, ins->size );
            ins->size += 2;
        }
        ++ins->num_ops;
    }
    return( DHR_DONE );
}


dis_handler_return X86Abs_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************/
{
    ins->size   += 1;
    ins->num_ops = 0;
    X86GetAbsVal( d, ins );
    return( DHR_DONE );
}


dis_handler_return X86Rel_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************/
{
    ins->size   += 1;
    ins->num_ops = 0;
    X86GetRelVal( d, ins );
    return( DHR_DONE );
}

dis_handler_return X86Imm_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************/
//  Byte      OOOO OOSW
{
    code_8 code;

    code.full = ins->opcode;

    ins->size   += 1;
    ins->num_ops = 0;
    ins->op[0].type = DO_IMMED;
    switch( ins->type ) {
    case DI_X86_int:
        if( code.type3.w ) {

            char intno = GetUByte( d, ins->size );

            if( ( intno >= 0x34 ) && ( intno <= 0x3D ) ) {
                ins->flags |= DIF_X86_EMU_INT;
                ins->op[ MAX_NUM_OPERANDS - 1 ].value = intno;
                ins->op[ MAX_NUM_OPERANDS - 1 ].type = DO_IMMED;
                ins->op[ MAX_NUM_OPERANDS - 1 ].ref_type = DRT_X86_BYTE;
                if( intno == 0x3C ) {
                    ins->size += 1;
                    ins->flags ^= DIF_X86_FWAIT;
                } else if( intno == 0x3D ) {
                } else {
                    ins->flags ^= DIF_X86_FWAIT;
                }
                return( DHR_CONTINUE );
            }
            ins->op[0].value = intno;
            ins->size += 1;
        } else {
            ins->op[0].value = 3;
        }
        ins->op[0].ref_type = DRT_X86_BYTE;
        ++ins->num_ops;
        break;
    case DI_X86_ret2:
    case DI_X86_retf2:
        ins->op[0].value = GetUShort( d, ins->size );
        ins->op[0].ref_type = DRT_X86_WORD;
        ins->size += 2;
        ++ins->num_ops;
        break;
    case DI_X86_push5:
        X86GetImmedVal( code.type3.s, W_DEFAULT, d, ins );
        if( code.type3.s ) {
            if( ( DIF_X86_OPND_LONG & ins->flags ) == 0 ) {
                ins->op[0].value &= 0xffff;
            }
        }
        if( DIF_X86_OPND_SIZE & ins->flags ) {
            if( DIF_X86_OPND_LONG & ins->flags ) {
                if( ( ins->op[0].value & 0xffff0000 ) == 0 ) {
                    ins->type = DI_X86_pushd;
                }
            } else {
                ins->type = DI_X86_pushw;
            }
        }
        break;
    default:
        X86GetImmedVal( code.type3.s, W_DEFAULT, d, ins );
        break;
    }
    return( DHR_DONE );
}


dis_handler_return X86ImmReg_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************/
//  8-bit   OOOO WRRR : Imm
{
    code_8 code;

    code.full = ins->opcode;
    ins->num_ops = 0;
    ++ins->size;
    X86GetReg( code.type2.w, code.type2.reg, ins );
    X86GetImmedVal( S_DEFAULT, code.type2.w, d, ins );
    return( DHR_DONE );
}

dis_handler_return X86ImmImm_8( dis_handle *h, void *d, dis_dec_ins *ins )
/**********************************************************************/
//  8-bit   OOOO OOOO : Imm16 Imm8
{
    ins->num_ops = 2;
    ins->size   += 1;
    ins->op[0].value = GetUShort( d, ins->size );
    ins->op[0].type = DO_IMMED;
    ins->op[0].ref_type = DRT_X86_WORD;
    ins->size   += 2;
    ins->op[1].value = GetUByte( d, ins->size );
    ins->op[1].type = DO_IMMED;
    ins->op[1].ref_type = DRT_X86_BYTE;
    ins->size   += 1;
    return( DHR_DONE );
}

dis_handler_return X86Reg_8( dis_handle *h, void *d , dis_dec_ins *ins )
/**********************************************************************/
//  Byte       OOOO  ORRR
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?