Instruction* Out::CreateInstruction(unsigned char* memLoc, Processor* proc) { unsigned char* opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newOut = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case OUT_IMM8_AL: case OUT_IMM8_AX: { eRegisters reg = *opLoc == OUT_IMM8_AL ? REG_AL : REG_AX; Operand* dst = new ImmediateOperand(*(opLoc + 1), 1); Operand* src = new RegisterOperand(reg, proc); GETINST(preSize + 2); snprintf(buf, 65, "OUT %s, %s", dst->GetDisasm().c_str(), reg == REG_AX ? "AX" : "AL"); newOut = new Out(pre, buf, inst, (int)*opLoc); newOut->SetOperand(Operand::SRC, src); newOut->SetOperand(Operand::DST, dst); break; } case OUT_DX_AL: case OUT_DX_AX: { eRegisters reg = *opLoc == OUT_DX_AL ? REG_AL : REG_AX; Operand* dst = new RegisterOperand(REG_DX, proc); Operand* src = new RegisterOperand(reg, proc); GETINST(preSize + 1); snprintf(buf, 65, "OUT DX, %s", reg == REG_AX ? "AX" : "AL"); newOut = new Out(pre, buf, inst, (int)*opLoc); newOut->SetOperand(Operand::SRC, src); newOut->SetOperand(Operand::DST, dst); break; } } return newOut; }
Instruction* In::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newIn = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case IN_AL_IMM8: case IN_AX_IMM8: { eRegisters reg = *opLoc == IN_AL_IMM8 ? REG_AL : REG_AX; Operand* src = new ImmediateOperand(*(opLoc + 1), 1, (opLoc + 1).getOffset()); Operand* dst = new RegisterOperand(reg, proc); GETINST(preSize + 2); snprintf(buf, 65, "IN %s, %s",reg == REG_AX ? "AX" : "AL", src->GetDisasm().c_str()); newIn = new In(pre, buf, inst, (int)*opLoc); newIn->SetOperand(Operand::SRC, src); newIn->SetOperand(Operand::DST, dst); break; } case IN_AL_DX: case IN_AX_DX: { eRegisters reg = *opLoc == IN_AL_DX ? REG_AL : REG_AX; Operand* src = new RegisterOperand(REG_DX, proc); Operand* dst = new RegisterOperand(reg, proc); GETINST(preSize + 1); snprintf(buf, 65, "IN %s, DX", reg == REG_AX ? "AX" : "AL"); newIn = new In(pre, buf, inst, (int)*opLoc); newIn->SetOperand(Operand::SRC, src); newIn->SetOperand(Operand::DST, dst); break; } } return newIn; }
Instruction* Cwd::CreateInstruction(Memory::MemoryOffset& memLoc, Processor*) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; if(pre) { opLoc += preSize = pre->GetLength(); } if(*opLoc == CWD) { snprintf(buf, 65, "CWD"); GETINST(preSize + 1); return new Cwd(pre, buf, inst, (int)*opLoc); } return 0; }
Instruction* Aas::CreateInstruction(unsigned char* memLoc, Processor* proc) { unsigned char* opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newAas = 0; if(pre) { opLoc += preSize = pre->GetLength(); } if(*opLoc == AAS) { GETINST(preSize + 1); snprintf(buf, 65, "AAS"); newAas = new Aas(pre, buf, inst, (int)*opLoc); } return newAas; }
Instruction* Aaa::CreateInstruction(Memory::MemoryOffset& memLoc, Processor*) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newAaa = 0; if(pre) { opLoc += preSize = pre->GetLength(); } if(*opLoc == AAA) { GETINST(preSize + 1); snprintf(buf, 65, "AAA"); newAaa = new Aaa(pre, buf, inst, (int)*opLoc); } return newAaa; }
Instruction* Mov::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newMov = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case MOV_MOD8_REG8: case MOV_MOD16_REG16: { unsigned int size = (*opLoc == MOV_MOD8_REG8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_REG8_MOD8: case MOV_REG16_MOD16: { unsigned int size = (*opLoc == MOV_REG8_MOD8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOD16_SEGREG: { Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::SEGREG, 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_SEGREG_MOD16: { Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::SEGREG, 2); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_AL_MOFF8: case MOV_AX_MOFF16: { unsigned int size = (*opLoc == MOV_AL_MOFF8 ? 1 : 2); Operand* dst = new RegisterOperand(*opLoc == MOV_AL_MOFF8 ? REG_AL : REG_AX, proc); unsigned int val = (int)*(opLoc + 1); val += ((int)*(opLoc + 2)) << 8; Memory::MemoryOffset tmpMem = opLoc.getNewOffset(val); Operand* src = AddressOperand::GetAddressOperand(proc, tmpMem, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 3); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOFF8_AL: case MOV_MOFF16_AX: { unsigned int size = (*opLoc == MOV_MOFF8_AL ? 1 : 2); Operand* src = new RegisterOperand(*opLoc == MOV_MOFF8_AL ? REG_AL : REG_AX, proc); unsigned int val = (int)*(opLoc + 1); val += ((int)*(opLoc + 2)) << 8; Memory::MemoryOffset tmpMem = opLoc.getNewOffset(val); Operand* dst = AddressOperand::GetAddressOperand(proc, tmpMem, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 3); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_AL_IMM8: case MOV_CL_IMM8: case MOV_DL_IMM8: case MOV_BL_IMM8: case MOV_AH_IMM8: case MOV_CH_IMM8: case MOV_DH_IMM8: case MOV_BH_IMM8: case MOV_AX_IMM16: case MOV_CX_IMM16: case MOV_DX_IMM16: case MOV_BX_IMM16: case MOV_SP_IMM16: case MOV_BP_IMM16: case MOV_SI_IMM16: case MOV_DI_IMM16: { unsigned int size = 0; Operand* dst = 0; if(*opLoc <= MOV_BL_IMM8) { //The 8 bit omes size = 1; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AL_IMM8 + REG_AL), proc); } else if(*opLoc <= MOV_BH_IMM8) { size = 1; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AH_IMM8 + REG_AH), proc); } else { size = 2; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AX_IMM16), proc); } unsigned int val = (int)*(opLoc + 1 + dst->GetBytecodeLen()); if(size == 2) { val += (int)*(opLoc + 2 + dst->GetBytecodeLen()) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 1 + dst->GetBytecodeLen()).getOffset()); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOD8_IMM8: case MOV_MOD16_IMM16: { unsigned int size = (*opLoc == MOV_MOD8_IMM8 ? 1 : 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); unsigned int val = (int)*(opLoc + 2 + dst->GetBytecodeLen()); if(size == 2) { val += (int)*(opLoc + 3 + dst->GetBytecodeLen()) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 2 + dst->GetBytecodeLen()).getOffset()); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); } break; } return newMov; }
Instruction* Push::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newPush = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case PUSH_MOD16: { if((unsigned int)((*(opLoc + 1) & 0x38) >> 3) != PUSH_SUB_OPCODE) return newPush; Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_REG_AX: case PUSH_REG_CX: case PUSH_REG_DX: case PUSH_REG_BX: case PUSH_REG_SP: case PUSH_REG_BP: case PUSH_REG_SI: case PUSH_REG_DI: { Operand* dst = new RegisterOperand((eRegisters)(*opLoc - PUSH_REG_AX + REG_AX), proc); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_IMM8: case PUSH_IMM16: { unsigned int val = *(opLoc + 1); unsigned int size = *opLoc == PUSH_IMM8 ? 1 : 2; if(size == 2) { val += *(opLoc + 2) << 0x8; } else { val += (val >= 0x80) ? 0xFF00 : 0x0000; } Operand* dst = new ImmediateOperand(val, 2, (opLoc + 1).getOffset()); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + size); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_CS: case PUSH_SS: case PUSH_DS: case PUSH_ES: { eRegisters reg = REG_CS; if(*opLoc == PUSH_CS) reg = REG_CS; else if(*opLoc == PUSH_DS) reg = REG_DS; else if(*opLoc == PUSH_SS) reg = REG_SS; else if(*opLoc == PUSH_ES) reg = REG_ES; Operand* dst = new RegisterOperand(reg, proc); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSHF: { Operand* dst = new RegisterOperand(REG_FLAGS, proc); snprintf(buf, 65, "PUSHF"); GETINST(preSize + 1); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSHA: { snprintf(buf, 65, "PUSHA"); GETINST(preSize + 1); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); } } return newPush; }
Instruction* Or::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; int prefixLen = 0; char buf[65]; int tInt1 = 0; unsigned char modrm = 0; Prefix* prefix = 0; Instruction* newOr = 0; //Build a prefix if possible prefix = Prefix::GetPrefix(memLoc); //Start looking after the prefix if(prefix) { opLoc += prefix->GetLength(); prefixLen += prefix->GetLength(); } std::string inst; //Switch for the different valid opcodes switch(*opLoc) { case OR_AL_IMM8: sprintf(buf, "OR AL, 0x%02X", (int)*(opLoc + 1)); GETINST(prefixLen + 2); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(*(opLoc + 1), 1,(opLoc + 1).getOffset())); newOr->SetOperand(Operand::DST, new RegisterOperand(REG_AL, proc)); break; case OR_AX_IMM16: tInt1 = (unsigned char)*(opLoc + 1); tInt1 |= (((unsigned char)*(opLoc + 2)) << 8); sprintf(buf, "OR AX, 0x%04X", tInt1); GETINST(prefixLen + 3); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(tInt1, 2, (opLoc + 1).getOffset())); newOr->SetOperand(Operand::DST, new RegisterOperand(REG_AX, proc)); break; case GRP1_OR_MOD8_IMM8: case GRP1_OR_MOD16_IMM16: case GRP1_OR_MOD16_IMM8: modrm = (*(opLoc + 1) & 0x38) >> 3; if(modrm == 1) { unsigned int immSize = (*opLoc == GRP1_OR_MOD8_IMM8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, immSize); tInt1 = (int)*(opLoc+2+dst->GetBytecodeLen()); if(immSize == 2) { if(*opLoc == GRP1_OR_MOD16_IMM16) { tInt1 += ((int)*(opLoc+3+dst->GetBytecodeLen())) << 8; }else { tInt1 = (tInt1 >= 0x80) ? 0xFF00 + tInt1 : tInt1; } } if(immSize == 1) sprintf(buf, "OR %s, 0x%02X", "", tInt1); else sprintf(buf, "OR %s, 0x%04X", "", tInt1); GETINST(prefixLen + 2 + immSize + dst->GetBytecodeLen() - (*opLoc == GRP1_OR_MOD16_IMM8 ? 1 : 0)); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(tInt1, immSize, (opLoc + 2 + dst->GetBytecodeLen()).getOffset())); newOr->SetOperand(Operand::DST, dst); } break; case GRP2_OR_MOD8_REG8: case GRP2_OR_MOD16_REG16: { unsigned int size = (*opLoc == GRP2_OR_MOD8_REG8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::REG, size); sprintf(buf, "OR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(prefixLen + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, src); newOr->SetOperand(Operand::DST, dst); break; } case GRP3_OR_REG8_MOD8: case GRP3_OR_REG16_MOD16: { unsigned int size = *opLoc == GRP3_OR_REG8_MOD8 ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::REG, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, size); sprintf(buf, "OR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(prefixLen + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, src); newOr->SetOperand(Operand::DST, dst); break; } default: break; } return newOr; }
Instruction* Test::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newTest = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case TEST_AL_IMM8: case TEST_AX_IMM16: { unsigned int size = (*opLoc == TEST_AL_IMM8 ? 1 : 2); unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } GETINST(preSize + 1 + size); Operand* src = new ImmediateOperand(val, size, (opLoc + 1).getOffset()); Operand* dst = new RegisterOperand(*opLoc == TEST_AL_IMM8 ? REG_AL : REG_AX, proc); snprintf(buf, 65, "TEST %s, %s", size == 1 ? "AL" : "AH", src->GetDisasm().c_str()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } case TEST_MOD8_IMM8: case TEST_MOD16_IMM16: { if((unsigned int)((*(opLoc + 1) & 0x38) >> 3) != TEST_SUB_OPCODE) return 0; unsigned int size = (*opLoc == TEST_MOD8_IMM8 ? 1 : 2); unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 1).getOffset()); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "TEST %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + size + dst->GetBytecodeLen()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } case TEST_MOD8_REG8: case TEST_MOD16_REG16: { unsigned int size = (*opLoc == TEST_MOD8_REG8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "TEST %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } } return newTest; }
int VM::LoadVirgoFile(const char* filename) { mLoaded = false; mInstructions.clear(); mLabels.clear(); mMem.Clear(); std::ifstream fin; fin.open(filename, std::ios_base::in); if(fin.fail()) { return VM_ERR_FOPEN; } //parse header int numInitArgs, numLines, addrStart, bytesTotal; fin >> numInitArgs; fin >> numLines; fin >> addrStart; fin >> bytesTotal; int i = 0; unsigned int hexSize; char* hex; char label[128]; char disasm[256]; unsigned int addr; unsigned int delay; char line[512]; char text[TEXT_LEN]; memset(line, 0, 512); fin.ignore(100, '\n'); while(!fin.eof()) { fin.getline(line, 512); if(fin.eof()) break; //swap all "quotation marks" with nulls for(char* c = line; *c != '\0'; c++) *c = *c == '\x001f' ? '\0' : *c; hex = 0; label[0] = '\0'; disasm[0] = '\0'; delay = 0; char* cl = line; cl++; //Parse Address if(strlen(cl) != 0) sscanf(cl, "%x", &addr); //Skip to next field cl += strlen(cl) + 2; //Number of bytes in hex representation if(strlen(cl) != 0) sscanf(cl, "%d", &hexSize); //Next Field cl += strlen(cl) + 2; //Create a buffer for the hex unsigned int hexArrSize = (hexSize > 1024 ? 1024 : (hexSize == 0 ? 1 : (hexSize * 2 + 1)) * sizeof(char)); hex = new char[hexArrSize]; //copy hex into buffer if(strlen(cl) != 0) { strncpy(hex, cl, hexArrSize); } else { hex[0] = '\0'; } //Next Field cl += strlen(cl) + 2; //Copy label if it exists if(strlen(cl) != 0) strncpy(label, cl, 128); //next Field cl += strlen(cl) + 2; //copy disassembled version if(strlen(cl) != 0) strncpy(disasm, cl, 256); //next Field cl += strlen(cl) + 2; //copy delay (20) if(strlen(cl) != 0) sscanf(cl, "%d", &delay); //Check for invalid hex string if(strlen(hex) % 2 != 0 || strlen(hex) / 2 != hexSize) { //odd number of hex digits, not bytes delete hex; mLoaded = false; return VM_ERR_CORRUPT; } //convert ascii hex into real hex memset(text, 0, TEXT_LEN); for(size_t j = 0; j < strlen(hex); j++) { if(j == TEXT_LEN) { delete hex; mLoaded = false; return VM_ERR_OVERFLOW; } if(hex[j] >= '0' && hex[j] <= '9') { text[j/2] |= (hex[j] - '0') << (j % 2 == 0 ? 4 : 0); }else if(toupper(hex[j]) >= 'A' && toupper(hex[j]) <= 'F') { text[j/2] |= (hex[j] - 'A' + 10) << (j % 2 == 0 ? 4 : 0); } } //Try to build a prefix Prefix* pre = Prefix::GetPrefix((unsigned char*)text, TEXT_LEN); char* opLoc = text; if(pre) { opLoc += pre->GetLength(); } std::string s; std::string dis(disasm); //trim whitespace from disassemblu dis.erase(dis.find_last_not_of(" \f\n\r\t\v") + 1); dis.erase(0, dis.find_first_not_of(" \f\n\r\t\v")); //Prefix with label // dis = label + ('\t' + dis); s.insert(0, hex); //clear up buffer from above delete hex; if(hexSize != 0) { memcpy(mMem.getPtr() + (addr % MEM_SIZE), text, hexSize); } if((dis.size() == 0 || (hexSize == 0 && label[0] == '\0')) && (strlen(label) == 0)) continue; Instruction* inst = new VirgoInstruction(pre, dis, s, (int)*opLoc); inst->SetAddress(addr); mInstructions.push_back(inst); mLabels.push_back(label); if(++i >= numLines) break; } mLoaded = true; mVirgo = true; mProc.Initialize(addrStart); return VM_SUCCESS; }
Instruction* Xor::CreateInstruction(unsigned char* memLoc, Processor* proc) { unsigned char* opLoc = memLoc; unsigned int preSize = 0; char buf[65]; std::string inst; Instruction* newXor = 0; Prefix* pre = Prefix::GetPrefix(memLoc); if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case XOR_AL_IMM8: case XOR_AX_IMM16: { unsigned int size = (*opLoc) == XOR_AL_IMM8 ? 1 : 2; unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } GETINST(preSize + 1 + size); Operand* dst = new RegisterOperand(size == 1 ? REG_AL : REG_AX, proc); Operand* src = new ImmediateOperand(val, size); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } case XOR_MOD8_IMM8: case XOR_MOD16_IMM16: case XOR_MOD16_IMM8: { if(((*(opLoc + 1) & 0x38) >> 3) != XOR_REG_CONST) break; unsigned int size = *opLoc == XOR_MOD8_IMM8 ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); unsigned int val = (int)*(opLoc + 2 +dst->GetBytecodeLen()); if(size == 2) { if(*opLoc == XOR_MOD16_IMM16) val += (int)*(opLoc + 3 + dst->GetBytecodeLen()) << 8; else val += val >= 0x80 ? 0xFF00 : 0x0000; } Operand* src = new ImmediateOperand(val, size); GETINST(preSize + 2 + (*opLoc == XOR_MOD16_IMM8 ? 1 : size) + dst->GetBytecodeLen()); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } case XOR_MOD8_REG8: case XOR_MOD16_REG16: case XOR_REG8_MOD8: case XOR_REG16_MOD16: { unsigned int size = (*opLoc == XOR_MOD8_REG8 || *opLoc == XOR_REG8_MOD8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, (*opLoc == XOR_MOD8_REG8 || *opLoc == XOR_MOD16_REG16) ? ModrmOperand::MOD : ModrmOperand::REG, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, (*opLoc == XOR_REG8_MOD8 || *opLoc == XOR_REG16_MOD16) ? ModrmOperand::MOD : ModrmOperand::REG, size); GETINST(preSize + 2 + src->GetBytecodeLen() + dst->GetBytecodeLen()); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } } return newXor; }