private static void PushDupPop(int times) { var compiler = new BytecodeCompiler(); for (int k = 0; k < times; k++) { compiler.Push(k); } compiler.Dup(times); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); DataWord value = new DataWord(times); Assert.AreEqual(DataWord.Zero, machine.Stack.Pop()); for (int k = 0; k < times; k++) { value = value.Subtract(DataWord.One); Assert.AreEqual(value, machine.Stack.Pop()); } Assert.AreEqual(0, machine.Stack.Size); }
public void GreaterThan() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(2); compiler.Push(2); compiler.GreaterThan(); compiler.Push(1); compiler.Push(0); compiler.GreaterThan(); compiler.Push(0); compiler.Push(1); compiler.GreaterThan(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(3, stack.Size); Assert.AreEqual(DataWord.Zero, stack.ElementAt(2)); Assert.AreEqual(DataWord.Zero, stack.ElementAt(1)); Assert.AreEqual(DataWord.One, stack.ElementAt(0)); }
public void MOV_Bonanza32() { var programText = new string[] { "section .text", "global _start", "_start:", "mov eax, 0x11112222 ; eax = 0x11112222", "mov ax, 0x3333 ; eax = 0x11113333 (works, only low 16 bits changed)", "mov al, 0x44 ; eax = 0x11113344 (works, only low 8 bits changed)", "mov ah, 0x55 ; eax = 0x11115544 (works, only high 8 bits changed)", "xor ah, ah ; eax = 0x11110044 (works, only high 8 bits cleared)", "mov eax, 0x11112222 ; eax = 0x11112222", "xor al, al ; eax = 0x11112200 (works, only low 8 bits cleared)", "mov eax, 0x11112222 ; eax = 0x11112222", "xor ax, ax ; eax = 0x11110000 (works, only low 16 bits cleared)" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11113333, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11113344, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11115544, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11110044, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112200, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); // Program should have terminated on the second tick ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11110000, agent.ReadExtendedRegister(Register.EAX)); // Program should have terminated on the second tick }
public void CompileReadKeyboardAsm() { var compiler = new BytecodeCompiler <UInt32>(); var sourceFileName = "./../../../../picovm/asm-src/read-keyboard32.asm"; Xunit.Assert.True(File.Exists(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)), $"Cannot find file {sourceFileName} for test, current directory: {System.Environment.CurrentDirectory}"); var compilation = compiler.Compile(sourceFileName); Xunit.Assert.Equal(0, compilation.Errors.Count); }
public void CompileHelloWorldLinux64Asm() { var compiler = new BytecodeCompiler <UInt64>(); var sourceFileName = "./../../../../picovm/asm-src/hello-world-linux64.asm"; Xunit.Assert.True(File.Exists(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)), $"Cannot find file {sourceFileName} for test, current directory: {System.Environment.CurrentDirectory}"); var compilation = compiler.Compile(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)); Xunit.Assert.Equal(0, compilation.Errors.Count); }
public void MOV_REG_CON_Overlayed() { var programText = new string[] { "section .text", "global _start", "_start:", "MOV EAX, 4294967295", // copy the value 11111111111111111111111111111111 into eax "MOV AX, 0", // copy the value 0000000000000000 into ax "MOV AH, 170", // copy the value 10101010 (0xAA) into ah "MOV AL, 85", // copy the value 01010101 (0x55) into al "MOV EAX, 0", // copy the value 11111111111111111111111111111111 into eax "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFFFFF, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((ushort)0xFFFF, agent.ReadRegister(Register.AX)); Xunit.Assert.Equal((byte)0xFF, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((byte)0xFF, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFF0000, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)0, agent.ReadRegister(Register.AX)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFAA00, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)170, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFAA55, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)170, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)85, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }
public void PUSH_POP_Overlayed() { var programText = new string[] { "section .text", "global _start", "_start:", "PUSH 4294945365", // push the value 1111 1111 1111 1111 1010 1010 0101 0101 (FFFF AA55) onto the stack "POP EAX", // pop it back into eax "PUSH 2863315917", // push the value 1010 1010 1010 1010 1011 1011 1100 1101 (AAAA BBCD) onto the stack "POP EAX", // pop it back into eax "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); Xunit.Assert.Equal((uint)65535, agent.StackPointer); var ret = agent.Tick(); // PUSH 4294945365 Xunit.Assert.Null(ret); agent.Dump(); Xunit.Assert.Equal((uint)(65535 - 4), agent.StackPointer); Xunit.Assert.Equal(4294945365, agent.StackPeek32()); Xunit.Assert.Equal((uint)0, agent.ReadExtendedRegister(Register.EAX)); // POP EAX #1 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535), agent.StackPointer); Xunit.Assert.Equal((uint)4294945365, agent.ReadExtendedRegister(Register.EAX)); // PUSH 2863315917 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535 - 4), agent.StackPointer); Xunit.Assert.Equal(2863315917, agent.StackPeek32()); Xunit.Assert.Equal((uint)4294945365, agent.ReadExtendedRegister(Register.EAX)); // POP EAX #2 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535), agent.StackPointer); Xunit.Assert.Equal((uint)2863315917, agent.ReadExtendedRegister(Register.EAX)); // END ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }
private static void PushPop(byte[] bytes) { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.CompileAdjust(Bytecodes.Push1, bytes.Length - 1, bytes); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); Assert.AreEqual(1, machine.Stack.Size); Assert.AreEqual(new DataWord(bytes), machine.Stack.Pop()); }
public void Stop() { Machine machine = new Machine(); BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Stop(); compiler.Push(1); compiler.Push(2); compiler.Push(3); machine.Execute(compiler.ToBytes()); Assert.AreEqual(0, machine.Stack.Size); }
public void Not() { DataWord dw1 = new DataWord(new byte[] { 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 }); DataWord dw2 = new DataWord(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f }); var compiler = new BytecodeCompiler(); compiler.Push(dw1); compiler.Not(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); Assert.AreEqual(dw2, machine.Stack.Pop()); }
private static Machine PushSwap(int nswap) { BytecodeCompiler compiler = new BytecodeCompiler(); for (int k = 0; k < 17; k++) { compiler.Push(k); } compiler.Swap(nswap); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); return(machine); }
public void StoreAndLoadDataWord() { var compiler = new BytecodeCompiler(); compiler.Push(257); compiler.Push(42); compiler.MStore(); compiler.Push(43); compiler.MLoad(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(new DataWord(257 << 8), stack.Pop()); }
public void PushPushPopPop() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(1); compiler.Push(2); compiler.Pop(); compiler.Pop(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(0, stack.Size); }
public void InvalidTooLargeJump() { var compiler = new BytecodeCompiler(); compiler.Push(10000); compiler.Jump(); compiler.Push(2); compiler.Push(3); compiler.Push(4); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(0, stack.Size); }
public void DivideByZero() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(0); compiler.Push(6); compiler.Divide(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(1, stack.Size); Assert.AreEqual(DataWord.Zero, stack.Pop()); }
public void MultiplyThreeTwo() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(2); compiler.Push(3); compiler.Multiply(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(1, stack.Size); Assert.AreEqual(new DataWord(6), stack.Pop()); }
public void SubtractThreeOne() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(1); compiler.Push(3); compiler.Subtract(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(1, stack.Size); Assert.AreEqual(DataWord.Two, stack.Pop()); }
public void MOV_Bonanza64() { var programText = new string[] { "section .text", "global _start", "_start:", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "mov eax, 0x55556666 ; actual: rax = 0x0000000055556666", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "mov ax, 0x7777 ; rax = 0x1111222233337777 (works!)", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "xor eax, eax ; actual: rax = 0x0000000000000000", " ; again, it wiped whole register" }; var compiler = new BytecodeCompiler <UInt64>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent64(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x0000000055556666, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233337777, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x0000000000000000, agent.ReadR64Register(Register.RAX)); }
public void StoreByte() { var compiler = new BytecodeCompiler(); compiler.Push(257); compiler.Push(42); compiler.MStore8(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var memory = machine.Memory; Assert.IsNotNull(memory); Assert.AreEqual(1, memory.GetByte(new DataWord(42))); Assert.AreEqual(0, memory.GetByte(new DataWord(41))); Assert.AreEqual(0, memory.GetByte(new DataWord(43))); }
public void JumpPushes() { var compiler = new BytecodeCompiler(); compiler.Push(9); compiler.Jump(); compiler.Push(2); compiler.Push(3); compiler.Push(4); compiler.JumpDest(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(0, stack.Size); }
public void ConditionalJumpWhenTrue() { var compiler = new BytecodeCompiler(); compiler.Push(1); compiler.Push(11); compiler.JumpI(); compiler.Push(2); compiler.Push(3); compiler.Push(4); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(0, stack.Size); }
public void GetCoinbase() { Address coinbase = new Address(); ProgramEnvironment environment = ProgramEnvironment.Builder().Coinbase(coinbase).Build(); var compiler = new BytecodeCompiler(); compiler.Coinbase(); Machine machine = new Machine(environment); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(1, stack.Size); Assert.AreEqual(new DataWord(coinbase.Bytes), stack.Pop()); }
public void PushesPc() { var compiler = new BytecodeCompiler(); compiler.Push(1); compiler.Push(2); compiler.Push(3); compiler.Pc(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(4, stack.Size); Assert.AreEqual(new DataWord(6), stack.Pop()); Assert.AreEqual(DataWord.Three, stack.Pop()); Assert.AreEqual(DataWord.Two, stack.Pop()); Assert.AreEqual(DataWord.One, stack.Pop()); }
public void InvalidTooLargeJump() { var compiler = new BytecodeCompiler(); compiler.Push(10000); compiler.Jump(); compiler.Push(2); compiler.Push(3); compiler.Push(4); Machine machine = new Machine(); try { machine.Execute(compiler.ToBytes()); } catch (InvalidOperationException ex) { Assert.AreEqual("Invalid jump destination", ex.Message); } }
public void ConditionalJumpWhenFalse() { var compiler = new BytecodeCompiler(); compiler.Push(0); compiler.Push(11); compiler.JumpI(); compiler.Push(2); compiler.Push(3); compiler.Push(4); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.AreEqual(3, stack.Size); Assert.AreEqual(new DataWord(4), stack.Pop()); Assert.AreEqual(new DataWord(3), stack.Pop()); Assert.AreEqual(new DataWord(2), stack.Pop()); }
public void StorageStoreLoad() { BytecodeCompiler compiler = new BytecodeCompiler(); compiler.Push(1); compiler.SLoad(); compiler.Push(2); compiler.Push(3); compiler.SStore(); compiler.Push(3); compiler.SLoad(); Machine machine = new Machine(); machine.Execute(compiler.ToBytes()); var stack = machine.Stack; Assert.IsNotNull(stack); Assert.AreEqual(2, stack.Size); Assert.AreEqual(DataWord.Two, stack.Pop()); Assert.AreEqual(DataWord.Zero, stack.Pop()); }
public void JumpWithoutJumpDest() { var compiler = new BytecodeCompiler(); compiler.Push(9); compiler.Jump(); compiler.Push(2); compiler.Push(3); compiler.Push(4); compiler.Push(5); Machine machine = new Machine(); try { machine.Execute(compiler.ToBytes()); Assert.Fail(); } catch (InvalidOperationException ex) { Assert.AreEqual("Invalid jump destination", ex.Message); } }
static void Main(string[] args) { var options = new Options(); if (!CommandLine.Parser.Default.ParseArguments(args, options)) { Environment.Exit(1); } var compiler = new BytecodeCompiler(); ExceptionOr <List <int> > result = Safe.Wrapper(compiler).FileToInstructions(options.InputFile); if (result.HasFailed()) { Console.Error.WriteLine("Failed to compile the instructions file: {0}", result.GetException().Message); Environment.Exit(2); } if (options.ShowOpcodes) { foreach (var op in result.GetValue()) { Console.Write("{0} ", op); } Console.WriteLine(); return; } if (options.ShowLayout) { var bytecode = new Bytecode(); int address = 0; int length = result.GetValue().Count; var opcodes = result.GetValue(); int i = 0; while (i < length) { var insName = bytecode.FindNameByOpcode(opcodes[i]); var numArgs = bytecode.GetNumArgs(opcodes[i]); Console.Write("{0:0000}:\t{1} ", i, insName); i++; for (int j = 0; j < numArgs; j++) { Console.Write("{0} ", opcodes[i]); i++; } Console.WriteLine(); } Console.WriteLine(); return; } var interpreter = new VM.Interpreter(); if (options.Debugger != null) { var monitor = new Monitor(); monitor.InsertNewLineBefore = true; interpreter.SetMonitor(monitor); switch (options.Debugger) { case "tracer": interpreter.Attach(new VM.Tracer()); break; case "singlestep": interpreter.Attach(new VM.SingleStepDebugger()); break; default: Console.Error.WriteLine("\"{0}\" is not a valid debugger. Use: \"tracer\", \"singlestep\"", options.Debugger); Environment.Exit(3); break; } } var ins = result.GetValue(); if (ins.Count > 0) { interpreter.Run(result.GetValue(), 0); } }
private NeoChunk Compile(ChunkNode ast) { var compiler = new BytecodeCompiler(ast); return(BuildNeoChunk(compiler.Compile())); }
public void MOV_REG_CON_Simple() { var programText = new string[] { "section .text", "global _start", "_start:", " MOV EAX, 4294967295 ; copy the value 11111111111111111111111111111111 into eax", " MOV AX, 0 ; copy the value 0000000000000000 into ax", " MOV AH, 170 ; copy the value 10101010 (0xAA) into ah", " MOV AL, 85 ; copy the value 01010101 (0x55) into al", " MOV EBX, 5 ; copy the value 5 into ebx", " MOV EAX, EBX ; copy the value in ebx into eax", " PUSH 4 ; push 4 on the stack", " PUSH EAX ; push eax (5) on the stack", " PUSH 6 ; push 6 on the stack", " POP EBX ; pop stack (6) into ebx", " POP EBX ; pop stack (5) into ebx", " POP [EBX] ; pop stack (4) into [ebx] memory location = 5", " ADD [EBX], 10 ; add 10 to the value in [ebx] which would change 4 to 14", " PUSH [EBX] ; push [ebx] memory location=5 value=14 onto the stack", "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal(4294967295, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Equal(0U, agent.ReadRegister(Register.AX)); ret = agent.Tick(); Xunit.Assert.Equal(170, agent.ReadHalfRegister(Register.AH)); ret = agent.Tick(); Xunit.Assert.Equal(85, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); Xunit.Assert.Equal(6U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }