Ejemplo n.º 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;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// return Offset = Base + (Index * Scale) + Displacement
        /// </summary>
        public static Tuple <bool, Rn, Rn, int, long, int> parseMemOperand(string token)
        {
            int length = token.Length;

            if (length < 3)
            {
                return(new Tuple <bool, Rn, Rn, int, long, int>(false, Rn.NOREG, Rn.NOREG, 0, 0, 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(new Tuple <bool, Rn, Rn, int, long, int>(false, Rn.NOREG, Rn.NOREG, 0, 0, 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.Item1)
                {
                    if (foundDisplacement)
                    {
                        // found an second displacement, error
                        return(new Tuple <bool, Rn, Rn, int, long, int>(false, Rn.NOREG, Rn.NOREG, 0, 0, 0));
                    }
                    else
                    {
                        foundDisplacement = true;
                        displacement      = (negativeDisplacement) ? -(long)t2.Item2 : (long)t2.Item2;
                    }
                }
                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(new Tuple <bool, Rn, Rn, int, long, int>(false, Rn.NOREG, Rn.NOREG, 0, 0, 0));
            }
            if ((baseRn != Rn.NOREG) && (indexRn != Rn.NOREG))
            {
                if (RegisterTools.nBits(baseRn) != RegisterTools.nBits(indexRn))
                {
                    return(new Tuple <bool, Rn, Rn, int, long, int>(false, Rn.NOREG, Rn.NOREG, 0, 0, 0));
                }
            }
            return(new Tuple <bool, Rn, Rn, int, long, int>(true, baseRn, indexRn, scale, displacement, nBits));
        }