Example #1
0
        /// <summary>
        /// Performs a single processor step.
        /// </summary>
        private int Step()
        {
            reader.Address     = machine.PC;
            currentInstruction = reader.NextInstruction();

            var oldPC = machine.PC;

            OnStepping(oldPC);

            var newPC = machine.Step();

            // If the instruction just executed was a call, we should add the address to the
            // routine table. The address is packed inside the first operand value. Note that
            // we need to do this prior to calling firing the ProcessorStepped event to ensure
            // that the disassembly view gets updated with the new routine before attempting
            // to set the new IP.
            if (currentInstruction.Opcode.IsCall)
            {
                var callOpValue = machine.GetOperandValue(0);
                var callAddress = storyService.Story.UnpackRoutineAddress(callOpValue);
                if (callAddress != 0)
                {
                    routineService.Add(callAddress);
                }
            }

            OnStepped(oldPC, newPC);

            hasStepped = true;

            return(newPC);
        }
Example #2
0
        private void PopulateProfilerData()
        {
            if (profilerService.Profiler == null)
            {
                return;
            }

            Dispatch(() =>
            {
                callTreeRoot = new List <ICall>()
                {
                    profilerService.Profiler.RootCall
                };
                routines = profilerService.Profiler.Routines;

                var reader = new InstructionReader(0, storyService.Story.Memory);

                var instructions = profilerService.Profiler.InstructionTimings.Select(timing =>
                {
                    reader.Address = timing.Item1;
                    var i          = reader.NextInstruction();
                    return(new
                    {
                        Instruction = i,
                        Address = i.Address,
                        OpcodeName = i.Opcode.Name,
                        OperandCount = i.OperandCount,
                        TimesExecuted = timing.Item2.Item1,
                        TotalTime = timing.Item2.Item2
                    });
                });

                this.instructions = instructions.OrderByDescending(x => x.TotalTime).ToList();

                var opcodes = from i in instructions
                              group i by i.Instruction.Opcode.Name into g
                              select new
                {
                    Name          = g.Key,
                    TotalTime     = g.Aggregate(TimeSpan.Zero, (r, t) => r + t.TotalTime),
                    Count         = g.Sum(x => x.TimesExecuted),
                    AverageILSize = profilerService.Profiler.GetAverageOpcodeILSize(g.Key)
                };

                this.opcodes = opcodes.OrderByDescending(x => x.TotalTime).ToList();

                AllPropertiesChanged();
            });
        }
Example #3
0
        private static Instruction[] ReadInstructions(int address, byte[] memory, InstructionCache cache)
        {
            var reader           = new InstructionReader(address, memory, cache);
            var instructions     = new List <Instruction>();
            var lastKnownAddress = address;

            while (true)
            {
                var i = reader.NextInstruction();

                instructions.Add(i);

                if ((i.Opcode.IsReturn || i.Opcode.IsQuit) && reader.Address > lastKnownAddress)
                {
                    break;
                }
                else if (i.Opcode.IsJump)
                {
                    var jumpOffset  = (short)i.Operands[0].Value;
                    var jumpAddress = reader.Address + jumpOffset - 2;
                    if (jumpAddress > lastKnownAddress)
                    {
                        lastKnownAddress = jumpAddress;
                    }

                    if (reader.Address > lastKnownAddress)
                    {
                        break;
                    }
                }
                else if (i.HasBranch && i.Branch.Kind == BranchKind.Address)
                {
                    var branchAddress = reader.Address + i.Branch.Offset - 2;
                    if (branchAddress > lastKnownAddress)
                    {
                        lastKnownAddress = branchAddress;
                    }
                }
            }

            return(instructions.ToArray());
        }
        public void FirstInstruction()
        {
            var story     = LoadStory();
            var initialPC = Header.ReadInitialPC(story.Memory);

            var ireader = new InstructionReader(initialPC, story.Memory, null);

            var i = ireader.NextInstruction();

            Assert.That(i, Is.Not.Null, "null check");
            Assert.That(i.Address, Is.EqualTo(0xa31d), "address check");
            Assert.That(i.Length, Is.EqualTo(3), "length check");
            Assert.That(i.Opcode.Kind, Is.EqualTo(OpcodeKind.OneOp), "opcode kind check");
            Assert.That(i.Opcode.Number, Is.EqualTo(0x0f), "opcode number check");
            Assert.That(i.OperandCount, Is.EqualTo(1), "operand count check");
            Assert.That(i.Operands[0].Kind, Is.EqualTo(OperandKind.LargeConstant), "operand kind check");
            Assert.That(i.Operands[0].Value, Is.EqualTo(0x34ce), "operand value check");
            Assert.That(i.HasStoreVariable, Is.False, "store variable check");
            Assert.That(i.HasBranch, Is.False, "branch check");
            Assert.That(i.HasZText, Is.False, "ztext check");
        }