예제 #1
0
        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();

                var(Valid, Value, 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
        }
예제 #2
0
 /// <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));
 }