/// <summary> Check if the provided string is a constant by evaluating it.</summary> public static (bool Valid, ulong Value, int NBits) Evaluate_Constant(string token, bool isCapitals = false) { //TODO bugfix: there is a issue with .net 1.6.2 and the evaluation code in Evaluate_Constant if (true) { // dont use expression evaluation, just parse it. return(ExpressionEvaluator.Parse_Constant(token, isCapitals)); } else { string token2 = token.Replace("_", string.Empty).Replace(".", string.Empty); return(ExpressionEvaluator.Evaluate_Constant(token2, isCapitals)); } }
Parse_Mem_Operand(string token, bool isCapitals = false) { int length = token.Length; if (length < 3) { return(Valid : false, BaseReg : Rn.NOREG, IndexReg : Rn.NOREG, Scale : 0, Displacement : 0, NBits : 0, ErrorMessage : null); // do not return a error message because the provided token can be a label } if (!isCapitals) { token = token.ToUpper(); } // 1] select everything between [] int beginPos = length; for (int i = 0; i < length; ++i) { if (token[i] == '[') { beginPos = i + 1; } } int endPos = length; for (int i = beginPos; i < length; ++i) { if (token[i] == ']') { endPos = i; } } int nBits = Get_Nbits_Mem_Operand(token); token = token.Substring(beginPos, endPos - beginPos).Trim(); length = token.Length; if (length == 0) { return(Valid : false, BaseReg : Rn.NOREG, IndexReg : Rn.NOREG, Scale : 0, Displacement : 0, NBits : 0, ErrorMessage : null);// do not return a error message because the provided token can be a label } // 2] check if the displacement is negative bool negativeDisplacement = token.Contains('-'); if (negativeDisplacement) { token = token.Replace('-', '+'); } // 3] remove superfluous initial + if (token[0] == '+') { token = token.Substring(1, length - 1).Trim(); } // 4] split based on + string[] x = token.Split('+'); Rn baseRn = Rn.NOREG; Rn indexRn = Rn.NOREG; int scale = 0; long displacement = 0; bool foundDisplacement = false; for (int i = 0; i < x.Length; ++i) { string y = x[i].Trim(); (bool Valid, ulong Value, int NBits) = ExpressionEvaluator.Parse_Constant(y, true); if (Valid) { if (foundDisplacement) { // found an second displacement, error return(Valid : false, BaseReg : Rn.NOREG, IndexReg : Rn.NOREG, Scale : 0, Displacement : 0, NBits : 0, ErrorMessage : "Multiple displacements"); } else { foundDisplacement = true; displacement = negativeDisplacement ? -(long)Value : (long)Value; } } else { Rn t1 = RegisterTools.ParseRn(y, true); if (t1 != Rn.NOREG) { if (baseRn == Rn.NOREG) { baseRn = t1; } else { indexRn = t1; scale = 1; } } if (y.Contains('*')) { string[] z = y.Split('*'); string z0 = z[0].Trim(); string z1 = z[1].Trim(); string scaleRaw = null; Rn z0r = RegisterTools.ParseRn(z0, true); if (z0r != Rn.NOREG) { indexRn = z0r; scaleRaw = z1; scale = ParseScale(z1); } else { Rn z1r = RegisterTools.ParseRn(z1, true); if (z1r != Rn.NOREG) { indexRn = z1r; scaleRaw = z0; scale = ParseScale(z0); } } if (scale == -1) { return(Valid : false, BaseReg : Rn.NOREG, IndexReg : Rn.NOREG, Scale : 0, Displacement : 0, NBits : 0, ErrorMessage : "Invalid scale " + scaleRaw); } } } } if ((baseRn != Rn.NOREG) && (indexRn != Rn.NOREG)) { if (RegisterTools.NBits(baseRn) != RegisterTools.NBits(indexRn)) { return(Valid : false, BaseReg : Rn.NOREG, IndexReg : Rn.NOREG, Scale : 0, Displacement : 0, NBits : 0, ErrorMessage : "Number of bits of base register " + baseRn + " is not equal to number of bits of index register " + indexRn); } } return(Valid : true, BaseReg : baseRn, IndexReg : indexRn, Scale : scale, Displacement : displacement, NBits : nBits, ErrorMessage : null); #region Local Methods int ParseScale(string str) { switch (str) { case "1": return(1); case "2": return(2); case "4": return(4); case "8": return(8); default: return(-1); } } /// <summary> Return the number of bits of the provided operand (assumes 64-bits) </summary> int Get_Nbits_Mem_Operand(string token2) { string s = token2.TrimStart(); if (s.StartsWith("PTR")) { s = s.Substring(3, token.Length - 3).TrimStart(); } if (s.StartsWith("BYTE")) { return(8); //nasm } if (s.StartsWith("SBYTE")) { return(8); } if (s.StartsWith("WORD")) { return(16); //nasm } if (s.StartsWith("SWORD")) { return(16); } if (s.StartsWith("DWORD")) { return(32); //nasm } if (s.StartsWith("SDWORD")) { return(32); } if (s.StartsWith("QWORD")) { return(64); //nasm } if (s.StartsWith("TWORD")) { return(80); //nasm } if (s.StartsWith("DQWORD")) { return(128); } if (s.StartsWith("OWORD")) { return(128); //nasm } if (s.StartsWith("XMMWORD")) { return(128); } if (s.StartsWith("XWORD")) { return(128); } if (s.StartsWith("YMMWORD")) { return(256); } if (s.StartsWith("YWORD")) { return(256); //nasm } if (s.StartsWith("ZMMWORD")) { return(512); } if (s.StartsWith("ZWORD")) { return(512); //nasm } //Console.WriteLine("AsmSourceTools:GetNbitsMemOperand: could not determine nBits in token " + token + " assuming 32 bits"); return(32); } #endregion }
/// <summary> Check if the provided string is a constant by parsing it. Does not evaluate arithmetic in the string.</summary> public static (bool Valid, ulong Value, int NBits) Parse_Constant(string token, bool isCapitals = false) { return(ExpressionEvaluator.Parse_Constant(token, isCapitals)); }