📄 operands.c
字号:
dest->address = UINT(stream + 1);
dest->segment = UINT(stream + ofs + 3);
return (ofs);
}
/* op 19 - ESC, mnem of bits 0-2 of opcode, imm,readrm */
static uint OP19(BYTE *stream, OPERAND *dest, OPERAND *source)
{
dest->code = OM_IMMEDIATE;
dest->flags |= OMF_BYTE;
dest->address = ((*(stream) &7) << 3) + ((*(stream + 1) >> 3) &7);
/* Note that byte mode and ESC code use the same bit... */
return (ReadRM(stream, source));
}
/* op 20 - long branch */
static uint OP20(BYTE *stream, OPERAND *dest)
{
strict = FALSE;
dest->code = OM_LONGBRANCH;
if (dest->flags &OMF_OP32)
{
dest->address = code_address + LONG(stream + 1) + 5+total_prefixes;
return (2);
}
else
{
dest->address = code_address + UINT(stream + 1) + 3+total_prefixes;
dest->address = dest->address &0xffff;
}
return (0);
}
/* op21 acc,dx */
static uint OP21(BYTE *stream, OPERAND *dest, OPERAND *source)
{
stream++;
SetReg(dest, REG_eAX);
source->flags &= ~(OMF_OP32 | OMF_BYTE);
SetReg(source, REG_DX);
return (0);
}
/* op22 - dx,acc */
static uint OP22(BYTE *stream, OPERAND *dest, OPERAND *source)
{
stream++;
dest->flags &= ~(OMF_OP32 | OMF_BYTE);
SetReg(dest, REG_DX);
SetReg(source, REG_eAX);
return (0);
}
/* op23 - port,acc where B1 of opcode set is port dest */
static uint OP23(BYTE *stream, OPERAND *dest, OPERAND *source)
{
if (B1(*stream))
{
dest->flags |= OMF_BYTE;
dest->code = OM_PORT;
dest->address = *(stream + 1);
SetReg(source, REG_eAX);
}
else
{
SetReg(dest, REG_eAX);
source->flags |= OMF_BYTE;
source->code = OM_PORT;
source->address = *(stream + 1);
}
return (0);
}
/* op 24 acc, absolute */
static uint OP24(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs = 0;
SetReg(dest, REG_eAX);
source->code = OM_ABSOLUTE;
if (source->flags &OMF_ADR32)
{
source->address = LONG(stream + 1);
ofs += 2;
}
else
source->address = UINT(stream + 1);
return (ofs);
}
/* op 25 - immediate byte or word */
static uint OP25(BYTE *stream, OPERAND *dest)
{
strict = FALSE;
if (B1(*stream))
dest->flags |= OMF_BYTE;
else
dest->flags &= ~OMF_BYTE;
return (Immediate(stream + 1, dest));
}
/* op 26, immediate 2byte,byte */
static uint OP26(BYTE *stream, OPERAND *dest, OPERAND *source)
{
strict = FALSE;
dest->flags &= ~(OMF_BYTE | OMF_OP32);
Immediate(stream + 1, dest);
source->flags |= OMF_BYTE;
source->flags &= ~OMF_OP32;
Immediate(stream + 3, source);
return (0);
}
/* op 27 - string */
static uint OP27(BYTE *stream, OPERAND *dest)
{
stream++;
if (segs &SG_OPSIZ)
if (dest->flags &OMF_OP32)
MnemonicChar('d');
else
MnemonicChar('w');
return (0);
}
/* op 28 - source = REG, dest = RM */
static uint OP28(BYTE *stream, OPERAND *dest, OPERAND *source)
{
SetReg(dest, REG(stream));
SetReg(source, RM(stream));
return (0);
}
/* op 29 - dest = RM, immediate */
static uint OP29(BYTE *stream, OPERAND *dest, OPERAND *source)
{
dest->flags |= OMF_BYTE;
SetReg(dest, RM(stream));
source->flags |= OMF_BYTE;
Immediate(stream + 2, source);
return (0);
}
/* op30 - RM, shift with B3 of stream selecting COUNT or CL*/
static uint OP30(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs = ReadRM(stream, dest);
source->code = OM_SHIFT;
if (B3(*stream))
/* The original author didn't let the RM field have any offsets... */
source->address = *(stream + (ofs++) + 2);
else
source->flags |= OMF_CL;
return (ofs);
}
/* op 31- reg, rm, count wher B1 of opcode = byte/word */
static uint OP31(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs;
extraoperand = *dest;
SetReg(dest, REG(stream));
ofs = ReadRM(stream, source);
if (B1(*stream))
extraoperand.flags |= OMF_BYTE;
else
extraoperand.flags &= ~OMF_BYTE;
ofs += Immediate(stream + 2, &extraoperand);
return (ofs);
}
/* op32 - 386 special regs */
static uint OP32(BYTE *stream, OPERAND *dest, OPERAND *source)
{
uint id = *((uint*)(stream)) &0xc005;
if (id == 0xc000)
id = OM_CRX;
else
if (id == 0xc001)
id = OM_DRX;
else
if (id == 0xc004)
id = OM_TRX;
else
id = OM_SUD;
dest->flags &= ~OMF_BYTE;
source->flags &= ~OMF_BYTE;
source->flags |= OMF_OP32;
dest->flags |= OMF_OP32;
if (B1(*stream))
{
dest->code = id;
dest->reg = REG(stream);
SetReg(source, RM(stream));
}
else
{
SetReg(dest, RM(stream));
source->code = id;
source->reg = REG(stream);
}
return (0);
}
/* op33 - reg,rm,shiftcnt where B3 = reg source, b0 = shift cl */
static uint OP33(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs;
dest->flags &= ~OMF_BYTE;
source->flags &= ~OMF_BYTE;
extraoperand = *dest;
extraoperand.code |= OM_SHIFT;
ofs = ReadRM(stream, dest);
SetReg(source, REG(stream));
if (B0(*stream))
extraoperand.flags |= OMF_CL;
else
extraoperand.address = *(stream + 2+ofs);
return (ofs);
}
/* op 34 - push & pop word */
static uint OP34(BYTE *stream, OPERAND *dest)
{
if ((segs &SG_TWOBYTEOP) || !(segs &SG_OPSIZ))
strict = FALSE;
return (ReadRM(stream, dest));
}
/* op 35 -floating RM */
static uint OP35(BYTE *stream, OPERAND *dest)
{
strict = FALSE;
if ((*((uint*)stream) &0xd0de) == 0xd0de)
MnemonicChar('p');
if (MOD(stream) != 3)
dest->flags |= OMF_FSTTAB | (B12(*stream) << OM_FTAB);
else
dest->flags |= OMF_FST;
return (ReadRM(stream, dest));
}
/* op 36 - sized floating RM */
static uint OP36(BYTE *stream, OPERAND *dest)
{
int size = SZ_QWORD;
strict = FALSE;
if ((*((uint*)stream) &0x2807) != 0x2807)
size = SZ_TBYTE;
dest->flags |= OMF_FSTTAB | ((size) << OM_FTAB);
return (ReadRM(stream, dest));
}
/* OP 37 - floating MATH */
static uint OP37(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs = 0, flop = 0;
strict = FALSE;
if ((*((uint*)stream) &0xc0de) == 0xc0de)
flop = 1;
if (((REG(stream) &5) ^ flop) == 5)
MnemonicChar('r');
if (MOD(stream) != 3)
{
ofs = ReadRM(stream, dest);
dest->flags |= OMF_FSTTAB | (B12(*stream) << OM_FTAB);
}
else
{
if (*stream &6)
MnemonicChar('p');
if (*stream &4)
{
SetReg(dest, RM(stream));
dest->flags |= OMF_FST;
source->code = OM_FSTREG;
}
else
{
dest->code = OM_FSTREG;
SetReg(source, RM(stream));
source->flags |= OMF_FST;
}
}
return (ofs);
}
//-------------------------------------------------------------------------
static uint OP38(BYTE *stream, OPERAND *dest)
{
/* This is how we get a DWORD PTR for the far jump */
strict = FALSE;
dest->flags |= OMF_FSTTAB;
return (ReadRM(stream, dest));
}
/* OP39 - word regrm with reg source */
static uint OP39(BYTE *stream, OPERAND *dest, OPERAND *source)
{
dest->flags &= ~OMF_BYTE;
source->flags &= ~OMF_BYTE;
return (RegRM(stream, source, dest));
}
/* op 40 regrm with reg source */
static uint OP40(BYTE *stream, OPERAND *dest, OPERAND *source)
{
return (RegRM(stream, source, dest));
}
/* op 41 reg, bitnum */
static uint OP41(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs;
dest->flags &= ~OMF_BYTE;
ofs = ReadRM(stream, dest);
source->flags |= OMF_BYTE;
Immediate(stream + 2+ofs, source);
return (ofs);
}
/* op 42 mixed regrm with reg dest & strictness enforced */
static uint OP42(BYTE *stream, OPERAND *dest, OPERAND *source)
{
int ofs = RegRM(stream, dest, source);
dest->flags &= ~OMF_BYTE;
source->flags &= ~OMF_OP32;
strict = TRUE;
return (ofs);
}
/* op43 - REGRM with b0 of opcode set reg is word else byte */
static uint OP43(BYTE *stream, OPERAND *dest, OPERAND *source)
{
if (!B0(*stream))
{
dest->flags |= OMF_BYTE;
source->flags |= OMF_BYTE;
}
return (RegRM(stream, dest, source)); /* Reg is dest */
}
//-------------------------------------------------------------------------
static FUNC optable[44] =
{
0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, OP11, OP12, OP13,
OP14, OP15, OP16, OP17, OP18, OP19, OP20, OP21, OP22, OP23, OP24, OP25,
OP26, OP27, OP28, OP29, OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37,
OP38, OP39, OP40, OP41, OP42, OP43
};
BYTE *ReadOverrides(BYTE *stream, uint validator)
{
segs = 0;
total_prefixes = 0;
for (;; stream++)
{
if (validator &VAL_VX)
{
if ((uint)(*stream - 0x64) < 2)
{
segs |= SG_REPNC << (*stream - 0x64);
total_prefixes++;
continue;
}
}
if (validator &VAL_386)
{
if ((uint)(*stream - 0x64) < 4)
{
segs |= SG_FS << (*stream - 0x64);
total_prefixes++;
continue;
}
}
if ((*stream &0xe7) == 0x26)
{
segs |= 1 << ((*stream >> 3) &3);
total_prefixes++;
continue;
}
if ((uint)(*stream - 0xf2) < 2)
{
segs |= SG_REPNZ << (*stream - 0xf2);
total_prefixes++;
continue;
}
break;
}
return (stream);
}
//-------------------------------------------------------------------------
BYTE *DispatchOperand(BYTE *stream, OPTABLE *opcode, BOOL adr32)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -