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 + -
显示快捷键?