예제 #1
0
        public Operand(string token)
        {
            //TODO: properly handle optional elements {K}{Z} {AES}{ER}
            string token2 = token.
                            Replace("{K0}", "").
                            Replace("{K1}", "").
                            Replace("{K2}", "").
                            Replace("{K3}", "").
                            Replace("{K4}", "").
                            Replace("{K5}", "").
                            Replace("{K6}", "").
                            Replace("{K7}", "").
                            Replace("{Z}", "").
                            Replace("{ER}", "").
                            Replace("{SAE}", "").
                            Replace("{1TO4}", "").
                            Replace("{1TO8}", "").
                            Replace("{1TO16}", "");

            this._str = token;

            Tuple <bool, Rn, int> t0 = RegisterTools.toRn(token2);

            if (t0.Item1)
            {
                this._type  = Ot.reg;
                this._rn    = t0.Item2;
                this._nBits = t0.Item3;
            }
            else
            {
                Tuple <bool, ulong, int> t1 = AsmSourceTools.toConstant(token2);
                if (t1.Item1)
                {
                    this._type  = Ot.imm;
                    this._imm   = t1.Item2;
                    this._nBits = t1.Item3;
                }
                else
                {
                    Tuple <bool, Rn, Rn, int, long, int> t2 = AsmSourceTools.parseMemOperand(token2);
                    if (t2.Item1)
                    {
                        this._type  = Ot.mem;
                        this._mem   = new Tuple <Rn, Rn, int, long>(t2.Item2, t2.Item3, t2.Item4, t2.Item5);
                        this._nBits = t2.Item6;
                    }
                    else
                    {
                        this._type  = Ot.UNKNOWN;
                        this._nBits = -1;
                    }
                }
            }
        }
예제 #2
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();

                (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
        }
예제 #3
0
        /// <summary>
        /// return Offset = Base + (Index * Scale) + Displacement
        /// </summary>
        public static (bool valid, Rn baseReg, Rn indexReg, int scale, long displacement, int nBits) ParseMemOperand(string token)
        {
            int length = token.Length;

            if (length < 3)
            {
                return(valid : false, baseReg : Rn.NOREG, indexReg : Rn.NOREG, scale : 0, displacement : 0, nBits : 0);
            }

            // 1] select everything between []
            int beginPos = length;

            for (int i = 0; i < length; ++i)
            {
                if (token[i] == '[')
                {
                    beginPos = i + 1;
                }
            }

            int nBits = GetNbitsMemOperand(token);

            int endPos = length;

            for (int i = beginPos; i < length; ++i)
            {
                if (token[i] == ']')
                {
                    endPos = i;
                }
            }

            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);
            }

            // 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 t2 = AsmSourceTools.ToConstant(y);
                if (t2.valid)
                {
                    if (foundDisplacement)
                    {
                        // found an second displacement, error
                        return(valid : false, baseReg : Rn.NOREG, indexReg : Rn.NOREG, scale : 0, displacement : 0, nBits : 0);
                    }
                    else
                    {
                        foundDisplacement = true;
                        displacement      = (negativeDisplacement) ? -(long)t2.value : (long)t2.value;
                    }
                }
                else
                {
                    Rn t1 = RegisterTools.ParseRn(y);
                    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();
                        Rn       z0r = RegisterTools.ParseRn(z0);
                        if (z0r != Rn.NOREG)
                        {
                            indexRn = z0r;
                            scale   = ParseScale(z1);
                        }
                        else
                        {
                            Rn z1r = RegisterTools.ParseRn(z1);
                            if (z1r != Rn.NOREG)
                            {
                                indexRn = z1r;
                                scale   = ParseScale(z0);
                            }
                        }
                    }
                }
            }

            if (scale == -1)
            {
                return(valid : false, baseReg : Rn.NOREG, indexReg : Rn.NOREG, scale : 0, displacement : 0, nBits : 0);
            }
            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);
                }
            }
            return(valid : true, baseReg : baseRn, indexReg : indexRn, scale : scale, displacement : displacement, nBits : nBits);
        }
예제 #4
0
 public static bool isRegister(string keyword)
 {
     return(RegisterTools.parseRn(keyword) != Rn.NOREG);
 }