Exemple #1
0
        private V1Instruction[] disassemble()
        {
            if (readNextOp() != V1Opcode.PROC)
            {
                throw new Exception("Function does not start with PROC");
            }
            var insns = new List <V1Instruction>();

            while (cursor_ < cursor_limit_)
            {
                int address = cursor_;
                int op      = readNext();
                if (op == (int)V1Opcode.PROC || op == (int)V1Opcode.ENDPROC)
                {
                    break;
                }

                var insn = new V1Instruction();
                insn.Address = address;
                insn.Info    = opcode_list_[op];
                insns.Add(insn);

                // CASETBL is special in that it is variable-length.
                if (op == (int)V1Opcode.CASETBL)
                {
                    var ncases = readNext();
                    insn.Params    = new int[(ncases + 1) * 2];
                    insn.Params[0] = ncases;
                    insn.Params[1] = readNext();
                    for (var i = 0; i < ncases; i++)
                    {
                        insn.Params[2 + i * 2]     = readNext();
                        insn.Params[2 + i * 2 + 1] = readNext();
                    }
                    continue;
                }

                insn.Params = new int[insn.Info.Params.Length];
                for (var i = 0; i < insn.Info.Params.Length; i++)
                {
                    insn.Params[i] = readNext();
                }

                // Catch calls to unknown functions so they can be disassembled easily too.
                if (op == (int)V1Opcode.CALL)
                {
                    var addr = insn.Params[0];
                    if (!file_.IsFunctionAtAddress(addr))
                    {
                        file_.CalledFunctions.AddFunction((uint)addr);
                    }
                }
            }
            return(insns.ToArray());
        }