📄 rar3vm.cpp
字号:
{
UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
SetOperand32(&cmd->Op1, res);
FLAGS_UPDATE_SZ;
}
break;
case CMD_ANDB:
{
Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
SetOperand8(&cmd->Op1, res);
FLAGS_UPDATE_SZ_B;
}
break;
case CMD_OR:
{
UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2);
SetOperand32(&cmd->Op1, res);
FLAGS_UPDATE_SZ;
}
break;
case CMD_ORB:
{
Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2);
SetOperand8(&cmd->Op1, res);
FLAGS_UPDATE_SZ_B;
}
break;
case CMD_TEST:
{
UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
FLAGS_UPDATE_SZ;
}
break;
case CMD_TESTB:
{
Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
FLAGS_UPDATE_SZ_B;
}
break;
case CMD_NOT:
SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1));
break;
case CMD_NEG:
{
UInt32 res = 0 - GetOperand32(&cmd->Op1);
SetOperand32(&cmd->Op1, res);
Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S);
}
break;
case CMD_NEGB:
{
Byte res = (Byte)(0 - GetOperand8(&cmd->Op1));
SetOperand8(&cmd->Op1, res);
Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res);
}
break;
case CMD_SHL:
{
UInt32 v1 = GetOperand32(&cmd->Op1);
int v2 = (int)GetOperand32(&cmd->Op2);
UInt32 res = v1 << v2;
SetOperand32(&cmd->Op1, res);
Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0);
}
break;
case CMD_SHLB:
{
Byte v1 = GetOperand8(&cmd->Op1);
int v2 = (int)GetOperand8(&cmd->Op2);
Byte res = (Byte)(v1 << v2);
SetOperand8(&cmd->Op1, res);
Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0);
}
break;
case CMD_SHR:
{
UInt32 v1 = GetOperand32(&cmd->Op1);
int v2 = (int)GetOperand32(&cmd->Op2);
UInt32 res = v1 >> v2;
SetOperand32(&cmd->Op1, res);
Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
}
break;
case CMD_SHRB:
{
Byte v1 = GetOperand8(&cmd->Op1);
int v2 = (int)GetOperand8(&cmd->Op2);
Byte res = (Byte)(v1 >> v2);
SetOperand8(&cmd->Op1, res);
Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
}
break;
case CMD_SAR:
{
UInt32 v1 = GetOperand32(&cmd->Op1);
int v2 = (int)GetOperand32(&cmd->Op2);
UInt32 res = UInt32(((Int32)v1) >> v2);
SetOperand32(&cmd->Op1, res);
Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
}
break;
case CMD_SARB:
{
Byte v1 = GetOperand8(&cmd->Op1);
int v2 = (int)GetOperand8(&cmd->Op2);
Byte res = (Byte)(((signed char)v1) >> v2);
SetOperand8(&cmd->Op1, res);
Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
}
break;
case CMD_JMP:
SET_IP_OP1;
continue;
case CMD_JZ:
if ((Flags & FLAG_Z) != 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JNZ:
if ((Flags & FLAG_Z) == 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JS:
if ((Flags & FLAG_S) != 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JNS:
if ((Flags & FLAG_S) == 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JB:
if ((Flags & FLAG_C) != 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JBE:
if ((Flags & (FLAG_C | FLAG_Z)) != 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JA:
if ((Flags & (FLAG_C | FLAG_Z)) == 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_JAE:
if ((Flags & FLAG_C) == 0)
{
SET_IP_OP1;
continue;
}
break;
case CMD_PUSH:
R[kStackRegIndex] -= 4;
SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1));
break;
case CMD_POP:
SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]));
R[kStackRegIndex] += 4;
break;
case CMD_CALL:
R[kStackRegIndex] -= 4;
SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1));
SET_IP_OP1;
continue;
case CMD_PUSHA:
{
for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4)
SetValue32(&Mem[SP & kSpaceMask], R[i]);
R[kStackRegIndex] -= kNumRegs * 4;
}
break;
case CMD_POPA:
{
for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4)
R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]);
}
break;
case CMD_PUSHF:
R[kStackRegIndex] -= 4;
SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags);
break;
case CMD_POPF:
Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
R[kStackRegIndex] += 4;
break;
case CMD_MOVZX:
SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2));
break;
case CMD_MOVSX:
SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2));
break;
case CMD_XCHG:
{
UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1);
SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2));
SetOperand(cmd->ByteMode, &cmd->Op2, v1);
}
break;
case CMD_MUL:
{
UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2);
SetOperand32(&cmd->Op1, res);
}
break;
case CMD_MULB:
{
Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2);
SetOperand8(&cmd->Op1, res);
}
break;
case CMD_DIV:
{
UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2);
if (divider != 0)
{
UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider;
SetOperand(cmd->ByteMode, &cmd->Op1, res);
}
}
break;
#endif
case CMD_RET:
{
if (R[kStackRegIndex] >= kSpaceSize)
return true;
UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
SET_IP(ip);
R[kStackRegIndex] += 4;
continue;
}
case CMD_PRINT:
break;
}
cmd++;
--maxOpCount;
}
}
//////////////////////////////////////////////////////
// Read program
UInt32 ReadEncodedUInt32(CMemBitDecoder &inp)
{
switch(inp.ReadBits(2))
{
case 0:
return inp.ReadBits(4);
case 1:
{
UInt32 v = inp.ReadBits(4);
if (v == 0)
return 0xFFFFFF00 | inp.ReadBits(8);
else
return (v << 4) | inp.ReadBits(4);
}
case 2:
return inp.ReadBits(16);
default:
return inp.ReadBits(32);
}
}
void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode)
{
if (inp.ReadBit())
{
op.Type = OP_TYPE_REG;
op.Data = inp.ReadBits(kNumRegBits);
}
else if (inp.ReadBit() == 0)
{
op.Type = OP_TYPE_INT;
if (byteMode)
op.Data = inp.ReadBits(8);
else
op.Data = ReadEncodedUInt32(inp);
}
else
{
op.Type = OP_TYPE_REGMEM;
if (inp.ReadBit() == 0)
{
op.Data = inp.ReadBits(kNumRegBits);
op.Base = 0;
}
else
{
if (inp.ReadBit() == 0)
op.Data = inp.ReadBits(kNumRegBits);
else
op.Data = kNumRegs;
op.Base = ReadEncodedUInt32(inp);
}
}
}
void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg)
{
CMemBitDecoder inp;
inp.Init(code, codeSize);
prg->StaticData.Clear();
if (inp.ReadBit())
{
UInt32 dataSize = ReadEncodedUInt32(inp) + 1;
for (UInt32 i = 0; inp.Avail() && i < dataSize; i++)
prg->StaticData.Add((Byte)inp.ReadBits(8));
}
while (inp.Avail())
{
prg->Commands.Add(CCommand());
CCommand *cmd = &prg->Commands.Back();
if (inp.ReadBit() == 0)
cmd->OpCode = (ECommand)inp.ReadBits(3);
else
cmd->OpCode = (ECommand)(8 + inp.ReadBits(5));
if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE)
cmd->ByteMode = (inp.ReadBit()) ? true : false;
else
cmd->ByteMode = 0;
int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK);
if (opNum > 0)
{
DecodeArg(inp, cmd->Op1, cmd->ByteMode);
if (opNum == 2)
DecodeArg(inp, cmd->Op2, cmd->ByteMode);
else
{
if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC)))
{
int Distance = cmd->Op1.Data;
if (Distance >= 256)
Distance -= 256;
else
{
if (Distance >= 136)
Distance -= 264;
else if (Distance >= 16)
Distance -= 8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -