Beispiel #1
0
    public X86Codes ConvertIL(MethodData md, ILCode il)
    {
        string mne = il.OpCode.Name;
        if (mne == null) return null;

        X86Codes ret = new X86Codes();
        ret.Address = il.Address;
        ret.IsBrTarget = il.IsBrTarget;
        if (il.Operand is byte)
        {
            ret.Comment = string.Format("{0} {1:X2}", mne, il.Operand);
        }
        else if (il.Operand is short)
        {
            ret.Comment = string.Format("{0} {1:X4}", mne, il.Operand);
        }
        else if (il.Operand is int)
        {
            ret.Comment = string.Format("{0} {1:X8}", mne, il.Operand);
        }
        else
        {
            ret.Comment = mne;
        }

        int mne_last = mne.Length < 1 ? 0 : (int)(mne[mne.Length - 1] - '0');
        int nOp = Util.GetOperandValue(il);
        switch (mne)
        {
            case "ldc.i4":
            case "ldc.i4.s":
            case "ldc.i4.0":
            case "ldc.i4.1":
            case "ldc.i4.2":
            case "ldc.i4.3":
            case "ldc.i4.4":
            case "ldc.i4.5":
            case "ldc.i4.6":
            case "ldc.i4.7":
            case "ldc.i4.8":
                ret.Codes.Add(new X86Code("mov", "ax", nOp.ToString()));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "ldloc":
            case "ldloc.s":
            case "ldloc.0":
            case "ldloc.1":
            case "ldloc.2":
            case "ldloc.3":
                ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
                break;
            case "ldloca":
            case "ldloca.s":
                ret.Codes.Add(new X86Code("mov", "ax", "bp"));
                ret.Codes.Add(new X86Code("sub", string.Format("ax, {0}", (nOp + 1) * 2)));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "stloc":
            case "stloc.s":
            case "stloc.0":
            case "stloc.1":
            case "stloc.2":
            case "stloc.3":
                ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
                break;
            case "ldarg":
            case "ldarg.s":
            case "ldarg.0":
            case "ldarg.1":
            case "ldarg.2":
            case "ldarg.3":
                ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
                break;
            case "starg":
            case "starg.s":
                ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
                break;
            case "ldstr":
            {
                int us = ((int)il.Operand) & 0xffffff;
                if (!this.listUS.Contains(us)) this.listUS.Add(us);
                ret.Codes.Add(new X86Code("mov", "ax", string.Format("US_{0:X8}", us)));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            }
            case "ldsfld":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                ret.Codes.Add(new X86Code("push", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
                break;
            }
            case "stsfld":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                ret.Codes.Add(new X86Code("pop", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
                break;
            }
            case "pop":
                ret.Codes.Add(new X86Code("pop", "ax"));
                break;
            case "br":
            case "br.s":
                ret.Codes.Add(new X86Code("jmp", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "beq":
            case "beq.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("je", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bne.un":
            case "bne.un.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jne", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bgt":
            case "bgt.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "blt":
            case "blt.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
                ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "ble":
            case "ble.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("jnc near", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "bge":
            case "bge.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
                ret.Codes.Add(new X86Code("jnc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "brfalse":
            case "brfalse.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("or", "ax", "ax"));
                ret.Codes.Add(new X86Code("jz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "brtrue":
            case "brtrue.s":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("or", "ax", "ax"));
                ret.Codes.Add(new X86Code("jnz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
                if (this.optimize > 0 && nOp == 0) ret.Ignore();
                break;
            case "call":
            {
                TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
                MethodData tb_md = tb.Tag as MethodData;
                ret.Codes.Add(new X86Code("call", string.Format("{0}", Util.MangleFunction(tb_md))));
                if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) ret.Codes.Add(new X86Code("push", "ax"));
                break;
            }
            //case "callvirt":
            //{
            //	TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            //	MethodData tb_md = tb.Tag as MethodData;
            //	string func = Util.MangleFunction(tb_md);
            //	if (func.StartsWith("instance__")) func = func.Substring(10, func.Length - 10);
            //	sw.WriteLine("\tcall _virtual__{0}", func);
            //	if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) sw.WriteLine("\tpush ax");
            //	break;
            //}
            case "ret":
                if (this.optimize == 0 || il == this.lastRet)
                {
                    if (md.RetType.Element != ELEMENT_TYPE.VOID)
                    {
                        ret.Codes.Add(new X86Code("pop", "ax"));
                    }
                    if (md.LocalVars != null || md.ParamCount > 0)
                    {
                        if (md.LocalVars != null) ret.Codes.Add(new X86Code("mov", "sp", "bp"));
                        ret.Codes.Add(new X86Code("pop", "bp"));
                    }
                    int st = Util.GetStackSize(md);
                    if (st == 0)
                    {
                        ret.Codes.Add(new X86Code("ret"));
                    }
                    else
                    {
                        ret.Codes.Add(new X86Code("ret", st.ToString()));
                    }
                }
                else
                {
                    X86Code x = new X86Code("jmp", string.Format("PE_{0:X8}", this.lastRet.Address));
                    x.Notes = "[optimize] modify";
                    ret.Codes.Add(x);
                    this.lastRet.IsBrTarget = true;
                }
                break;
            case "ceq":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
                ret.Codes.Add(new X86Code("je", string.Format("NM_{0:X8}", this.number)));
                ret.Codes.Add(new X86Code("xor", "ax", "ax"));
                ret.Codes.Add(new X86Code("jmp", string.Format("NM_{0:X8}", this.number + 1)));
                ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number), true, "ceq internal", "mov", "ax", "1"));
                ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number + 1), true, "ceq internal", "push", "ax"));
                this.number += 2;
                break;
            case "add":
            case "and":
            case "or":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code(mne, "ax", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "sub":
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("sub", "ax", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "mul":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("pop", "dx"));
                ret.Codes.Add(new X86Code("mul", "dx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "div":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("xor", "dx", "dx"));
                ret.Codes.Add(new X86Code("div", "cx"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "rem":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("xor", "dx", "dx"));
                ret.Codes.Add(new X86Code("div", "cx"));
                ret.Codes.Add(new X86Code("push", "dx"));
                break;
            case "neg":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("neg", "ax"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "shr":
            case "shl":
                ret.Codes.Add(new X86Code("pop", "cx"));
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code(mne, "ax", "cl"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "conv.u1":
                ret.Codes.Add(new X86Code("pop", "ax"));
                ret.Codes.Add(new X86Code("mov", "ah", "0"));
                ret.Codes.Add(new X86Code("push", "ax"));
                break;
            case "conv.i2":
            case "conv.u2":
            case "conv.i4":
            case "conv.u4":
                // ignore in 16bit
                return ret;
            //case "box":
            //{
            //	TypeRefTable t = this.pedata.idxm.GetTable((int)il.Operand) as TypeRefTable;
            //	sw.WriteLine("\tcall _box__{0}@4", GetTypeName(this.pedata.idxm.GetName(t)));
            //	sw.WriteLine("\tpush ax");
            //	break;
            //}
        }
        if (ret.Codes.Count < 1) return null;
        return ret;
    }
Beispiel #2
0
    public X86Codes ConvertIL(MethodData md, ILCode il)
    {
        string mne = il.OpCode.Name;

        if (mne == null)
        {
            return(null);
        }

        X86Codes ret = new X86Codes();

        ret.Address    = il.Address;
        ret.IsBrTarget = il.IsBrTarget;
        if (il.Operand is byte)
        {
            ret.Comment = string.Format("{0} {1:X2}", mne, il.Operand);
        }
        else if (il.Operand is short)
        {
            ret.Comment = string.Format("{0} {1:X4}", mne, il.Operand);
        }
        else if (il.Operand is int)
        {
            ret.Comment = string.Format("{0} {1:X8}", mne, il.Operand);
        }
        else
        {
            ret.Comment = mne;
        }

        int mne_last = mne.Length < 1 ? 0 : (int)(mne[mne.Length - 1] - '0');
        int nOp      = Util.GetOperandValue(il);

        switch (mne)
        {
        case "ldc.i4":
        case "ldc.i4.s":
        case "ldc.i4.0":
        case "ldc.i4.1":
        case "ldc.i4.2":
        case "ldc.i4.3":
        case "ldc.i4.4":
        case "ldc.i4.5":
        case "ldc.i4.6":
        case "ldc.i4.7":
        case "ldc.i4.8":
            ret.Codes.Add(new X86Code("mov", "ax", nOp.ToString()));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "ldloc":
        case "ldloc.s":
        case "ldloc.0":
        case "ldloc.1":
        case "ldloc.2":
        case "ldloc.3":
            ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
            break;

        case "ldloca":
        case "ldloca.s":
            ret.Codes.Add(new X86Code("mov", "ax", "bp"));
            ret.Codes.Add(new X86Code("sub", string.Format("ax, {0}", (nOp + 1) * 2)));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "stloc":
        case "stloc.s":
        case "stloc.0":
        case "stloc.1":
        case "stloc.2":
        case "stloc.3":
            ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp-{0}]", (nOp + 1) * 2)));
            break;

        case "ldarg":
        case "ldarg.s":
        case "ldarg.0":
        case "ldarg.1":
        case "ldarg.2":
        case "ldarg.3":
            ret.Codes.Add(new X86Code("push", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
            break;

        case "starg":
        case "starg.s":
            ret.Codes.Add(new X86Code("pop", string.Format("word [ss:bp+{0}]", Util.GetArgPos(md, nOp, this.optimize))));
            break;

        case "ldstr":
        {
            int us = ((int)il.Operand) & 0xffffff;
            if (!this.listUS.Contains(us))
            {
                this.listUS.Add(us);
            }
            ret.Codes.Add(new X86Code("mov", "ax", string.Format("US_{0:X8}", us)));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;
        }

        case "ldsfld":
        {
            TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            ret.Codes.Add(new X86Code("push", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
            break;
        }

        case "stsfld":
        {
            TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
            ret.Codes.Add(new X86Code("pop", string.Format("word [cs:{0}]", MangleField(tb as FieldTable))));
            break;
        }

        case "pop":
            ret.Codes.Add(new X86Code("pop", "ax"));
            break;

        case "br":
        case "br.s":
            ret.Codes.Add(new X86Code("jmp", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "beq":
        case "beq.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("je", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bne.un":
        case "bne.un.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jne", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bgt":
        case "bgt.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "blt":
        case "blt.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
            ret.Codes.Add(new X86Code("jc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "ble":
        case "ble.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("jnc near", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "bge":
        case "bge.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "dx", "ax"));
            ret.Codes.Add(new X86Code("jnc", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "brfalse":
        case "brfalse.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("or", "ax", "ax"));
            ret.Codes.Add(new X86Code("jz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "brtrue":
        case "brtrue.s":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("or", "ax", "ax"));
            ret.Codes.Add(new X86Code("jnz", string.Format("PE_{0:X8}", Girl.PEAnalyzer.Util.GetBrTarget(il))));
            if (this.optimize > 0 && nOp == 0)
            {
                ret.Ignore();
            }
            break;

        case "call":
        {
            TableBase  tb    = this.pedata.idxm.GetTable((int)il.Operand);
            MethodData tb_md = tb.Tag as MethodData;
            ret.Codes.Add(new X86Code("call", string.Format("{0}", Util.MangleFunction(tb_md))));
            if (tb_md.RetType.Element != ELEMENT_TYPE.VOID)
            {
                ret.Codes.Add(new X86Code("push", "ax"));
            }
            break;
        }

        //case "callvirt":
        //{
        //	TableBase tb = this.pedata.idxm.GetTable((int)il.Operand);
        //	MethodData tb_md = tb.Tag as MethodData;
        //	string func = Util.MangleFunction(tb_md);
        //	if (func.StartsWith("instance__")) func = func.Substring(10, func.Length - 10);
        //	sw.WriteLine("\tcall _virtual__{0}", func);
        //	if (tb_md.RetType.Element != ELEMENT_TYPE.VOID) sw.WriteLine("\tpush ax");
        //	break;
        //}
        case "ret":
            if (this.optimize == 0 || il == this.lastRet)
            {
                if (md.RetType.Element != ELEMENT_TYPE.VOID)
                {
                    ret.Codes.Add(new X86Code("pop", "ax"));
                }
                if (md.LocalVars != null || md.ParamCount > 0)
                {
                    if (md.LocalVars != null)
                    {
                        ret.Codes.Add(new X86Code("mov", "sp", "bp"));
                    }
                    ret.Codes.Add(new X86Code("pop", "bp"));
                }
                int st = Util.GetStackSize(md);
                if (st == 0)
                {
                    ret.Codes.Add(new X86Code("ret"));
                }
                else
                {
                    ret.Codes.Add(new X86Code("ret", st.ToString()));
                }
            }
            else
            {
                X86Code x = new X86Code("jmp", string.Format("PE_{0:X8}", this.lastRet.Address));
                x.Notes = "[optimize] modify";
                ret.Codes.Add(x);
                this.lastRet.IsBrTarget = true;
            }
            break;

        case "ceq":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("cmp", "ax", "dx"));
            ret.Codes.Add(new X86Code("je", string.Format("NM_{0:X8}", this.number)));
            ret.Codes.Add(new X86Code("xor", "ax", "ax"));
            ret.Codes.Add(new X86Code("jmp", string.Format("NM_{0:X8}", this.number + 1)));
            ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number), true, "ceq internal", "mov", "ax", "1"));
            ret.Codes.Add(new X86Code(string.Format("NM_{0:X8}", this.number + 1), true, "ceq internal", "push", "ax"));
            this.number += 2;
            break;

        case "add":
        case "and":
        case "or":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code(mne, "ax", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "sub":
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("sub", "ax", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "mul":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("pop", "dx"));
            ret.Codes.Add(new X86Code("mul", "dx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "div":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("xor", "dx", "dx"));
            ret.Codes.Add(new X86Code("div", "cx"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "rem":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("xor", "dx", "dx"));
            ret.Codes.Add(new X86Code("div", "cx"));
            ret.Codes.Add(new X86Code("push", "dx"));
            break;

        case "neg":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("neg", "ax"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "shr":
        case "shl":
            ret.Codes.Add(new X86Code("pop", "cx"));
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code(mne, "ax", "cl"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "conv.u1":
            ret.Codes.Add(new X86Code("pop", "ax"));
            ret.Codes.Add(new X86Code("mov", "ah", "0"));
            ret.Codes.Add(new X86Code("push", "ax"));
            break;

        case "conv.i2":
        case "conv.u2":
        case "conv.i4":
        case "conv.u4":
            // ignore in 16bit
            return(ret);
            //case "box":
            //{
            //	TypeRefTable t = this.pedata.idxm.GetTable((int)il.Operand) as TypeRefTable;
            //	sw.WriteLine("\tcall _box__{0}@4", GetTypeName(this.pedata.idxm.GetName(t)));
            //	sw.WriteLine("\tpush ax");
            //	break;
            //}
        }
        if (ret.Codes.Count < 1)
        {
            return(null);
        }
        return(ret);
    }