public void ExecuteOpcode(Computer computer, byte opcode) { // Do your reflective invocation thing here... Type reflectionType = typeof(X86InstructionSet); // Turn 32-bit instruction opcode into instruction opcode. // Prep for 'reflective invoke' :-). int line = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; string methodName = "_" + computer.memory.virtualAddressSpace[line].value;//Encoding.ASCII.GetString(this.operands[0].value).Trim(new char[] { '\0' }); // Remove empty character bytes from opcode. MethodInfo info = reflectionType.GetMethod(methodName); ParameterInfo[] parameterInfos = info.GetParameters(); if (parameterInfos.Length > 0) { byte[] parameters = new byte[0]; Array.Resize(ref parameters, parameters.Count() + 1); parameters[parameters.Count() - 1] = computer.memory.virtualAddressSpace[line + 1].value; // Next byte is opcode's needed parameter. IInstructionSet instructions = new X86InstructionSet(computer); // todo <-- horrible hack creating a new instruction set on the fly, here... //computer.cPU.instructionSet; info.Invoke(instructions, new object[] { parameters }); // Turn byte array into object array with single byte array element. } else { IInstructionSet instructions = new X86InstructionSet(computer); // todo horrible hack creating a new instruction set on the fly, here... //computer.cPU.instructionSet; info.Invoke(instructions, null); // Turn byte array into object array with single byte array element. } }
private void RedrawMemory() { if (Singleton.GetSingleton().computer != null) { int instructionPointer = Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; int stackPointer = Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.STACK_POINTER), 0)[0]; if (this.uglyGlobalDirection == 1) { // Redraw virtual address space listBox2.Items.Clear(); for (int i = 0; i < Singleton.GetSingleton().computer.memory.virtualAddressSpace.Count; i++) { ListBoxItem lbix = new ListBoxItem(); lbix.Content = "[" + i.ToString() + "] " + Singleton.GetSingleton().computer.memory.virtualAddressSpace[i].value.ToString(); lbix.MouseDoubleClick += _MouseLeftButtonDown; if (i == instructionPointer) { lbix.Foreground = System.Windows.Media.Brushes.Yellow; lbix.Background = System.Windows.Media.Brushes.Aqua; } else if (i == stackPointer) { lbix.Foreground = System.Windows.Media.Brushes.Aqua; lbix.Background = System.Windows.Media.Brushes.Yellow; } else { lbix.Foreground = System.Windows.Media.Brushes.Red; lbix.Background = System.Windows.Media.Brushes.Lime; } listBox2.Items.Add(lbix); } } else if (this.uglyGlobalDirection == 2) { // Redraw virtual address space listBox2.Items.Clear(); for (int i = Singleton.GetSingleton().computer.memory.virtualAddressSpace.Count - 1; i >= 0; i--) { ListBoxItem lbix = new ListBoxItem(); lbix.Content = "[" + i.ToString() + "] " + Singleton.GetSingleton().computer.memory.virtualAddressSpace[i].value.ToString(); lbix.MouseDoubleClick += _MouseLeftButtonDown; listBox2.Items.Add(lbix); } listBox2.SelectedIndex = 31 - Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; } // Opcode-aligned memory. (you can't allow this to be edited (mouseclickevent), as the memory 'entries' are variable length). listBox4.Items.Clear(); X86InstructionSet instructions = new X86InstructionSet(Singleton.GetSingleton().computer); // todo Remove, as only instantiated for the ToSkip() call below. int loopipx2 = 0; for (loopipx2 = 0; loopipx2 < 15; loopipx2 += 0) // Replace loop iteration maximum constant with length of 'codeSegment' in 'Program'. { int toSkip2 = instructions.ToSkip(Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx2].value); // Number of parameters. string methodName = "_" + Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx2].value; string parameterGarbage = ""; // Loop through opcode's parameters. for (int x = 1; x < toSkip2; x++) { parameterGarbage = ""; parameterGarbage += Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx2 + x].value; } int ipx = Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; ListBoxItem lbix = new ListBoxItem(); lbix.Content = "[" + loopipx2.ToString() + "] " + Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx2].value.ToString() + " " + parameterGarbage; if (loopipx2 == ipx) { lbix.Foreground = System.Windows.Media.Brushes.Yellow; lbix.Background = System.Windows.Media.Brushes.Aqua; } else { lbix.Foreground = System.Windows.Media.Brushes.Red; lbix.Background = System.Windows.Media.Brushes.Lime; } listBox4.Items.Add(lbix); loopipx2 += toSkip2; } } }
private void button_Click(object sender, RoutedEventArgs e) { Singleton.GetSingleton().human.loader.Step(Singleton.GetSingleton().computer); int ipx = Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; // Redraw the assembly instructions. listBox1.Items.Clear(); // try and work out where to be... for (int i = 0; i < Singleton.GetSingleton().asmSource.Length; i++) { ListBoxItem lbix = new ListBoxItem(); lbix.Content = Singleton.GetSingleton().asmSource[i]; //lbix.MouseDoubleClick += _MouseLeftButtonDown; X86InstructionSet instructionsX = new X86InstructionSet(Singleton.GetSingleton().computer); int toSkip = instructionsX.ToSkip(Singleton.GetSingleton().computer.memory.virtualAddressSpace[ipx].value); // Number of parameters. if (i == ipx) { lbix.Foreground = System.Windows.Media.Brushes.Yellow; lbix.Background = System.Windows.Media.Brushes.Aqua; } else { lbix.Foreground = System.Windows.Media.Brushes.Red; lbix.Background = System.Windows.Media.Brushes.Lime; } listBox1.Items.Add(lbix); } // Redraw reverse assembly instructions. listBox3.Items.Clear(); X86InstructionSet instructions = new X86InstructionSet(Singleton.GetSingleton().computer); // todo Remove, as only instantiated for the ToSkip() call below. int loopipx = 0; int reverseAsmLineCounter = 0; for (loopipx = 0; loopipx < 15; loopipx += 0) // Replace loop iteration maximum constant with length of 'codeSegment' in 'Program'. { int toSkip = instructions.ToSkip(Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx].value); // Number of parameters. //int toSkip2 = toSkip + Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; string methodName = "_" + Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx].value; string parameterGarbage = ""; // Loop through opcode's parameters. for (int x = 1; x < toSkip; x++) { parameterGarbage = ""; parameterGarbage += Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx + x].value; } Singleton.GetSingleton().computer.memory.virtualAddressSpace[loopipx].reverseAsmLine = reverseAsmLineCounter; loopipx += toSkip; /*if (loopipx == 14) { List<Address> la = Singleton.GetSingleton().computer.memory.virtualAddressSpace; // todo DELETE ME }*/ reverseAsmLineCounter += 1; // toSkip may be more than 1, but asmLine bump will always be 1. ListBoxItem lbix2 = new ListBoxItem(); lbix2.Content = instructions.opcodes[methodName] + parameterGarbage; //if (loopipx == Singleton.GetSingleton().computer.memory.virtualAddressSpace[ipx].reverseAsmLine)// ( - (int)(sliderEntryPointer.Value)) - 1) if (loopipx == ipx)// ( - (int)(sliderEntryPointer.Value)) - 1) { lbix2.Foreground = System.Windows.Media.Brushes.Yellow; lbix2.Background = System.Windows.Media.Brushes.Aqua; } else { lbix2.Foreground = System.Windows.Media.Brushes.Red; lbix2.Background = System.Windows.Media.Brushes.Lime; } listBox3.Items.Add(lbix2); } byte[] modsvalue = Helper.GetHelper().PadWithBytes(Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.ACCUMULATOR), 0), 4); int inced = BitConverter.ToInt32(modsvalue, 0); label1.Content = inced.ToString(); modsvalue = Helper.GetHelper().PadWithBytes(Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.BASE), 0), 4); inced = BitConverter.ToInt32(modsvalue, 0); label2.Content = inced.ToString(); modsvalue = Helper.GetHelper().PadWithBytes(Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.STACK_POINTER), 0), 4); inced = BitConverter.ToInt32(modsvalue, 0); label3.Content = inced.ToString(); modsvalue = Helper.GetHelper().PadWithBytes(Singleton.GetSingleton().computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0), 4); inced = BitConverter.ToInt32(modsvalue, 0); label4.Content = inced.ToString(); RedrawMemory(); }
// * Constructor * public X86CPU(Computer computer) { this.x86InstructionSet = new X86InstructionSet(computer); this.x86Registers = new X86Registers(); }
public Tuple<List<byte>, List<int>> Tokenize(List<string> source) { Tuple<List<byte>, List<int>> t = new Tuple<List<byte>, List<int>>(new List<byte>(), new List<int>()); X86InstructionSet instructions = new X86InstructionSet(Singleton.GetSingleton().computer); // Split source by space character. List<string> splitSource = new List<string>(); foreach (string unsplitString in source) { string[] splitStrings = unsplitString.Split(new char[] {' ', ','}, StringSplitOptions.RemoveEmptyEntries); foreach (string splitString in splitStrings) { splitSource.Add(splitString); } } // Parse split source. int asmLine = 0; int i; for (i = 0; i < splitSource.Count; i++) { if (splitSource[i] == "mov") { if ((splitSource[i + 1] == "eax") || ((splitSource[i + 1] == "ebx"))) { if (splitSource[i + 2] == "10") { t.Item1.Add(184); // Byte. int toSkip = instructions.ToSkip(184); // Number of parameters. for (int j = 0; j < toSkip; j++) { if (j == 1) { t.Item1.Add(Byte.Parse(splitSource[i + j + 1])); } // Grab the second parameter only, for this opcode. t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } else if (splitSource[i + 2] == "eax") { t.Item1.Add(89); // Byte. int toSkip = instructions.ToSkip(89); // Number of parameters. for (int j = 0; j < toSkip; j++) { if (j == 1) { t.Item1.Add(195); } // X86 const value for EBX. t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } } } else if (splitSource[i] == "call") { t.Item1.Add(232); // Byte. int toSkip = instructions.ToSkip(232); // Number of parameters. for (int j = 0; j < toSkip; j++) { if (j == 1) { t.Item1.Add(8); } // todo - fix hardcoded line jump address, here. t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } else if (splitSource[i] == "inc") { if (splitSource[i + 1] == "eax") { t.Item1.Add(40); // Byte. int toSkip = instructions.ToSkip(40); // Number of parameters. for (int j = 0; j < toSkip; j++) { t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } } else if (splitSource[i] == "push") { if (splitSource[i + 1] == "eax") { t.Item1.Add(50); // Byte. int toSkip = instructions.ToSkip(50); // Number of parameters. for (int j = 0; j < toSkip; j++) { t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } else if (splitSource[i + 1] == "77") { t.Item1.Add(106); // Byte. int toSkip = instructions.ToSkip(106); // Number of parameters. for (int j = 0; j < toSkip; j++) { if (j == 1) { t.Item1.Add(Byte.Parse(splitSource[i + j])); } // Grab the first parameter only, for this opcode. t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } } else if (splitSource[i] == "pop") { if (splitSource[i + 1] == "eax") { t.Item1.Add(58); // Byte. int toSkip = instructions.ToSkip(58); // Number of parameters. for (int j = 0; j < toSkip; j++) { t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } } else if (splitSource[i].StartsWith("@@")) { asmLine += 1; } else if (splitSource[i] == "ret") { t.Item1.Add(195); // Byte. int toSkip = instructions.ToSkip(195); // Number of parameters. for (int j = 0; j < toSkip; j++) { t.Item2.Add(asmLine); // ASM line. } i += toSkip - 1; // Push loop past any parameters. asmLine += 1; } } return t; }
//public int line { get; set; } public void Step(Computer computer) { // Run the program. //for (i = 0; i < computer.memory.virtualAddressSpace.Count; i++) //{ //ExecuteOpcode(computer, computer.memory.virtualAddressSpace[line]); int castedIP = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; ExecuteOpcode(computer, computer.memory.virtualAddressSpace[castedIP].value); //this.line += ToSkip(computer.memory.virtualAddressSpace[castedIP]); // Get next opcode to instruction ready to read. // todo - Horrible hack to re-get the IP if it may have been changed by an instruction such as RET. castedIP = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; X86InstructionSet instructions = new X86InstructionSet(computer); // todo Remove, as only instantiated for the ToSkip() call below. int toSkip = instructions.ToSkip(computer.memory.virtualAddressSpace[castedIP].value); int toSkip2 = toSkip + computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; computer.cPU.GetRegisters().SetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0, Helper.GetHelper().PadWithBytes((byte)(toSkip2), 4)); // Get next opcode to instruction ready to read. }