Пример #1
0
        public VirtualMachine(int memorySize)
        {
            if (memorySize < 512 * 1024)
                throw new ArgumentOutOfRangeException("memorySize", "VM should have at least 512kB of memory");

            Registers = new int[(int)Register.Count];
            Memory = new byte[memorySize];

            IP = 0;
            SP = Memory.Length;

            Flags = VmFlags.None;
            IVT = 0;

            _instruction = new Instruction(this);
            _interruptsEnabled = false;
            _interrupted = false;
            _devices = new IDevice[16];

            Attach(this);

            _timer = new Devices.Timer();
            Attach(_timer);

            Attach(new Devices.SysCall());
        }
Пример #2
0
        private IEnumerable<Line> Disassemble(Computer target, int ip)
        {
            var machine = target.Vm;
            var debugInfo = target.Code.DebugInfo;
            var instruction = new Instruction(machine);
            var buffer = new byte[8];

            while (true)
            {
                var instrAddr = machine.IP;
                if (instrAddr >= machine.Memory.Length)
                    break;

                ShipDebug.Line? nextLine = null;

                if (debugInfo != null)
                {
                    var symbol = debugInfo.FindSymbol(instrAddr);
                    if (symbol.HasValue && symbol.Value.Address == instrAddr)
                        yield return new Line(instrAddr, string.Format("< {0} >", symbol.Value.Name), false, 1);

                    nextLine = debugInfo.FindLine(instrAddr, 1);
                }

                var decodeFailed = false;
                try
                {
                    instruction.Decode();
                }
                catch
                {
                    decodeFailed = true;
                }

                if (decodeFailed || !instruction.IsValid || (nextLine.HasValue && instrAddr + instruction.Length > nextLine.Value.Address))
                {
                    if (nextLine.HasValue)
                        machine.IP = nextLine.Value.Address;
                    else
                        machine.IP += 4;

                    var read = 0;
                    while (instrAddr <= machine.IP)
                    {
                        if (instrAddr >= machine.Memory.Length)
                            break;

                        buffer[read++] = machine.Memory[instrAddr++];

                        if (read == buffer.Length || instrAddr == machine.IP)
                        {
                            if (read > 0)
                            {
                                var bufferStr = string.Join(", ", buffer.Take(read).Select(v => string.Format("0x{0:X2}", v)));
                                yield return new Line(instrAddr - read, string.Format(" db {0}", bufferStr), false, 8);
                            }

                            read = 0;
                        }
                    }
                }
                else
                {
                    string sourceLine = null;

                    if (debugInfo != null)
                    {
                        var line = debugInfo.FindLine(instrAddr);
                        if (line.HasValue && line.Value.Address == instrAddr)
                            sourceLine = string.Format("{0}:{1}", line.Value.FileName, line.Value.LineNumber);
                    }

                    var fg = instrAddr == ip ? 4 : 0;
                    var bg = target.HasBreakpoint(instrAddr) ? 15 : 7;
                    yield return new Line(instrAddr, string.Format(" {0}", instruction), true, (byte)fg, (byte)bg, sourceLine);
                    machine.IP += instruction.Length;
                }
            }
        }