void MnemonicTranslateImplicitAlias(char* Mnemonic, Inst* Instruction) { // Avoid naming conflicts (SSE "_XMM", MOVSX*) if(strchr(Mnemonic, '_') || strchr(Mnemonic, 'X') || strchr(Mnemonic, 'x')) return; // Certain string instructions need to override the instruction size if(!_strnicmp(Mnemonic, "ins", 3) || !_strnicmp(Mnemonic, "outs", 4) || !_strnicmp(Mnemonic, "movs", 4) || !_strnicmp(Mnemonic, "cmps", 4) || !_strnicmp(Mnemonic, "stos", 4) || !_strnicmp(Mnemonic, "lods", 4) || !_strnicmp(Mnemonic, "scas", 4)) { if(Instruction->OperandCount >= 2) { // Determine size from the MEMORY operand REGISTER auto operands = Instruction->Operands; if(operands[0].Type == OPERAND_MEM) Instruction->AddressSizeOverride = OpsizeToBits(RegGetSize(operands[0].Mem.BaseVal)); else if(operands[1].Type == OPERAND_MEM) Instruction->AddressSizeOverride = OpsizeToBits(RegGetSize(operands[1].Mem.BaseVal)); } // All operands are implicit/hidden Instruction->OperandCount = 0; } }
void OperandToString(char* Buffer, InstOperand* Operand) { switch(Operand->Type) { case OPERAND_INVALID: strcpy(Buffer, "(INVALID OPERAND)"); break; case OPERAND_REG: strcpy(Buffer, RegToString(Operand->Reg.Reg)); break; case OPERAND_IMM: if(Operand->Imm.Signed && Operand->Imm.simm < 0) sprintf(Buffer, "-0x%llX", (~Operand->Imm.imm) + 1); else sprintf(Buffer, "0x%llX", Operand->Imm.imm); break; case OPERAND_MEM: { char base[64]; char scale[64]; memset(base, 0, sizeof(base)); memset(scale, 0, sizeof(scale)); if(Operand->Mem.Base) sprintf(base, "%s + ", RegToString(Operand->Mem.BaseVal)); if(Operand->Mem.Index) sprintf(scale, "%s * %d + ", RegToString(Operand->Mem.IndexVal), Operand->Mem.ScaleVal); sprintf(Buffer, "%s ptr %s:[%s%s0x%llX/%d]", OpsizeToString(Operand->Size), RegToString(Operand->Segment), base, scale, Operand->Mem.DispVal, OpsizeToBits(Operand->Mem.DispWidth)); } break; case OPERAND_SEGSEL: sprintf(Buffer, "0x%llX", Operand->Sel.Offset); break; } }
OPSIZE PromoteImmediateWidth(bool Signed, ULONGLONG Value, OPSIZE Width) { // Adjustment fix-up when the sign bit is set // // half = pow(2, n_bits - 1); // minhalf = -half; xed_uint64_t maxhalf = 1 << (OpsizeToBits(Width) - 1); xed_uint64_t minhalf = 1 + (~maxhalf); // Values that are < -(MAX_VALUE/2) need to use the next biggest size // Values that are >= +(MAX_VALUE/2) need to use the next biggest size if((Signed && Value < minhalf) || (!Signed && Value >= maxhalf)) { switch(Width) { case SIZE_BYTE: return SIZE_DWORD; case SIZE_DWORD: return SIZE_QWORD; } } return Width; }