|
while (true) { |
|
VMPreparedCommand cmd = preparedCode.get(IP); |
|
int op1 = getOperand(cmd.getOp1()); |
|
int op2 = getOperand(cmd.getOp2()); |
|
switch (cmd.getOpCode()) { |
|
case VM_MOV: |
|
setValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(), |
|
mem, op2)); // SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2)); |
|
break; |
|
case VM_MOVB: |
|
setValue(true, mem, op1, getValue(true, mem, op2)); |
|
break; |
|
case VM_MOVD: |
|
setValue(false, mem, op1, getValue(false, mem, op2)); |
|
break; |
|
|
|
case VM_CMP: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int result = value1 - getValue(cmd.isByteMode(), mem, op2); |
|
|
|
if (result == 0) { |
|
flags = VMFlags.VM_FZ.getFlag(); |
|
} else { |
|
flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS |
|
.getFlag()); |
|
} |
|
} |
|
break; |
|
|
|
case VM_CMPB: { |
|
int value1 = getValue(true, mem, op1); |
|
int result = value1 - getValue(true, mem, op2); |
|
if (result == 0) { |
|
flags = VMFlags.VM_FZ.getFlag(); |
|
} else { |
|
flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS |
|
.getFlag()); |
|
} |
|
} |
|
break; |
|
case VM_CMPD: { |
|
int value1 = getValue(false, mem, op1); |
|
int result = value1 - getValue(false, mem, op2); |
|
if (result == 0) { |
|
flags = VMFlags.VM_FZ.getFlag(); |
|
} else { |
|
flags = (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS |
|
.getFlag()); |
|
} |
|
} |
|
break; |
|
|
|
case VM_ADD: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int result = (int) ((((long) value1 + (long) getValue(cmd |
|
.isByteMode(), mem, op2))) & 0xffffffff); |
|
if (cmd.isByteMode()) { |
|
result &= 0xff; |
|
flags = (result < value1) ? 1 |
|
: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: ((result & 0x80) != 0) ? VMFlags.VM_FS |
|
.getFlag() : 0); |
|
// Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ? |
|
// VM_FS:0)); |
|
} else { |
|
flags = (result < value1) ? 1 |
|
: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())); |
|
} |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
|
|
case VM_ADDB: |
|
setValue(true, mem, op1, |
|
(int) ((long) getValue(true, mem, op1) & 0xFFffFFff |
|
+ (long) getValue(true, mem, op2) & 0xFFffFFff)); |
|
break; |
|
case VM_ADDD: |
|
setValue( |
|
false, |
|
mem, |
|
op1, |
|
(int) ((long) getValue(false, mem, op1) & 0xFFffFFff |
|
+ (long) getValue(false, mem, op2) & 0xFFffFFff)); |
|
break; |
|
|
|
case VM_SUB: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int result = (int) ((long) value1 & 0xffFFffFF |
|
- (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff); |
|
flags = (result == 0) ? VMFlags.VM_FZ.getFlag() |
|
: (result > value1) ? 1 : 0 | (result & VMFlags.VM_FS |
|
.getFlag()); |
|
setValue(cmd.isByteMode(), mem, op1, result); // (Cmd->ByteMode,Op1,Result); |
|
} |
|
break; |
|
|
|
case VM_SUBB: |
|
setValue(true, mem, op1, |
|
(int) ((long) getValue(true, mem, op1) & 0xFFffFFff |
|
- (long) getValue(true, mem, op2) & 0xFFffFFff)); |
|
break; |
|
case VM_SUBD: |
|
setValue( |
|
false, |
|
mem, |
|
op1, |
|
(int) ((long) getValue(false, mem, op1) & 0xFFffFFff |
|
- (long) getValue(false, mem, op2) & 0xFFffFFff)); |
|
break; |
|
|
|
case VM_JZ: |
|
if ((flags & VMFlags.VM_FZ.getFlag()) != 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JNZ: |
|
if ((flags & VMFlags.VM_FZ.getFlag()) == 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_INC: { |
|
int result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff + 1); |
|
if (cmd.isByteMode()) { |
|
result &= 0xff; |
|
} |
|
|
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
} |
|
break; |
|
|
|
case VM_INCB: |
|
setValue( |
|
true, |
|
mem, |
|
op1, |
|
(int) ((long) getValue(true, mem, op1) & 0xFFffFFff + 1)); |
|
break; |
|
case VM_INCD: |
|
setValue(false, mem, op1, (int) ((long) getValue(false, mem, |
|
op1) & 0xFFffFFff + 1)); |
|
break; |
|
|
|
case VM_DEC: { |
|
int result = (int) ((long) getValue(cmd.isByteMode(), mem, op1) & 0xFFffFFff - 1); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
} |
|
break; |
|
|
|
case VM_DECB: |
|
setValue( |
|
true, |
|
mem, |
|
op1, |
|
(int) ((long) getValue(true, mem, op1) & 0xFFffFFff - 1)); |
|
break; |
|
case VM_DECD: |
|
setValue(false, mem, op1, (int) ((long) getValue(false, mem, |
|
op1) & 0xFFffFFff - 1)); |
|
break; |
|
|
|
case VM_JMP: |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
case VM_XOR: { |
|
int result = getValue(cmd.isByteMode(), mem, op1) |
|
^ getValue(cmd.isByteMode(), mem, op2); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_AND: { |
|
int result = getValue(cmd.isByteMode(), mem, op1) |
|
& getValue(cmd.isByteMode(), mem, op2); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_OR: { |
|
int result = getValue(cmd.isByteMode(), mem, op1) |
|
| getValue(cmd.isByteMode(), mem, op2); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_TEST: { |
|
int result = getValue(cmd.isByteMode(), mem, op1) |
|
& getValue(cmd.isByteMode(), mem, op2); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : result |
|
& VMFlags.VM_FS.getFlag(); |
|
} |
|
break; |
|
case VM_JS: |
|
if ((flags & VMFlags.VM_FS.getFlag()) != 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JNS: |
|
if ((flags & VMFlags.VM_FS.getFlag()) == 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JB: |
|
if ((flags & VMFlags.VM_FC.getFlag()) != 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JBE: |
|
if ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) != 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JA: |
|
if ((flags & (VMFlags.VM_FC.getFlag() | VMFlags.VM_FZ.getFlag())) == 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_JAE: |
|
if ((flags & VMFlags.VM_FC.getFlag()) == 0) { |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
} |
|
break; |
|
case VM_PUSH: |
|
R[7] -= 4; |
|
setValue(false, mem, R[7] & VM_MEMMASK, getValue(false, mem, |
|
op1)); |
|
break; |
|
case VM_POP: |
|
setValue(false, mem, op1, getValue(false, mem, R[7] |
|
& VM_MEMMASK)); |
|
R[7] += 4; |
|
break; |
|
case VM_CALL: |
|
R[7] -= 4; |
|
setValue(false, mem, R[7] & VM_MEMMASK, IP + 1); |
|
setIP(getValue(false, mem, op1)); |
|
continue; |
|
case VM_NOT: |
|
setValue(cmd.isByteMode(), mem, op1, ~getValue( |
|
cmd.isByteMode(), mem, op1)); |
|
break; |
|
case VM_SHL: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int value2 = getValue(cmd.isByteMode(), mem, op2); |
|
int result = value1 << value2; |
|
flags = (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())) |
|
| (((value1 << (value2 - 1)) & 0x80000000) != 0 ? VMFlags.VM_FC |
|
.getFlag() |
|
: 0); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_SHR: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int value2 = getValue(cmd.isByteMode(), mem, op2); |
|
int result = value1 >>> value2; |
|
flags = (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())) |
|
| ((value1 >>> (value2 - 1)) & VMFlags.VM_FC.getFlag()); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_SAR: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int value2 = getValue(cmd.isByteMode(), mem, op2); |
|
int result = ((int) value1) >>> value2; |
|
flags = (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())) |
|
| ((value1 >>> (value2 - 1)) & VMFlags.VM_FC.getFlag()); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_NEG: { |
|
int result = -getValue(cmd.isByteMode(), mem, op1); |
|
flags = result == 0 ? VMFlags.VM_FZ.getFlag() : VMFlags.VM_FC |
|
.getFlag() |
|
| (result & VMFlags.VM_FS.getFlag()); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
|
|
case VM_NEGB: |
|
setValue(true, mem, op1, -getValue(true, mem, op1)); |
|
break; |
|
case VM_NEGD: |
|
setValue(false, mem, op1, -getValue(false, mem, op1)); |
|
break; |
|
case VM_PUSHA: { |
|
for (int i = 0, SP = R[7] - 4; i < regCount; i++, SP -= 4) { |
|
setValue(false, mem, SP & VM_MEMMASK, R[i]); |
|
} |
|
R[7] -= regCount * 4; |
|
} |
|
break; |
|
case VM_POPA: { |
|
for (int i = 0, SP = R[7]; i < regCount; i++, SP += 4) { |
|
R[7 - i] = getValue(false, mem, SP & VM_MEMMASK); |
|
} |
|
} |
|
break; |
|
case VM_PUSHF: |
|
R[7] -= 4; |
|
setValue(false, mem, R[7] & VM_MEMMASK, flags); |
|
break; |
|
case VM_POPF: |
|
flags = getValue(false, mem, R[7] & VM_MEMMASK); |
|
R[7] += 4; |
|
break; |
|
case VM_MOVZX: |
|
setValue(false, mem, op1, getValue(true, mem, op2)); |
|
break; |
|
case VM_MOVSX: |
|
setValue(false, mem, op1, (byte) getValue(true, mem, op2)); |
|
break; |
|
case VM_XCHG: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
setValue(cmd.isByteMode(), mem, op1, getValue(cmd.isByteMode(), |
|
mem, op2)); |
|
setValue(cmd.isByteMode(), mem, op2, value1); |
|
} |
|
break; |
|
case VM_MUL: { |
|
int result = (int) (((long) getValue(cmd.isByteMode(), mem, op1) |
|
& 0xFFffFFff |
|
* (long) getValue(cmd.isByteMode(), mem, op2) & 0xFFffFFff) & 0xFFffFFff); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_DIV: { |
|
int divider = getValue(cmd.isByteMode(), mem, op2); |
|
if (divider != 0) { |
|
int result = getValue(cmd.isByteMode(), mem, op1) / divider; |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
} |
|
break; |
|
case VM_ADC: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int FC = (flags & VMFlags.VM_FC.getFlag()); |
|
int result = (int) ((long) value1 & 0xFFffFFff |
|
+ (long) getValue(cmd.isByteMode(), mem, op2) |
|
& 0xFFffFFff + (long) FC & 0xFFffFFff); |
|
if (cmd.isByteMode()) { |
|
result &= 0xff; |
|
} |
|
|
|
flags = (result < value1 || result == value1 && FC != 0) ? 1 |
|
: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
case VM_SBB: { |
|
int value1 = getValue(cmd.isByteMode(), mem, op1); |
|
int FC = (flags & VMFlags.VM_FC.getFlag()); |
|
int result = (int) ((long) value1 & 0xFFffFFff |
|
- (long) getValue(cmd.isByteMode(), mem, op2) |
|
& 0xFFffFFff - (long) FC & 0xFFffFFff); |
|
if (cmd.isByteMode()) { |
|
result &= 0xff; |
|
} |
|
flags = (result > value1 || result == value1 && FC != 0) ? 1 |
|
: 0 | (result == 0 ? VMFlags.VM_FZ.getFlag() |
|
: (result & VMFlags.VM_FS.getFlag())); |
|
setValue(cmd.isByteMode(), mem, op1, result); |
|
} |
|
break; |
|
|
|
case VM_RET: |
|
if (R[7] >= VM_MEMSIZE) { |
|
return (true); |
|
} |
|
setIP(getValue(false, mem, R[7] & VM_MEMMASK)); |
|
R[7] += 4; |
|
continue; |
|
|
|
case VM_STANDARD: |
|
ExecuteStandardFilter(VMStandardFilters.findFilter(cmd.getOp1() |
|
.getData())); |
|
break; |
|
case VM_PRINT: |
|
break; |
|
} |
|
IP++; |
|
--maxOpCount; |
|
} |