What is NEOVM and how does it work
This article is written by Li Jianying(Light Li) in Chinese and translated into English by Robbie.
NEOVM is NEO’s VM.
It is clear that NEOVM is the virtual machine used in the Neo blockchain system.
- A simple explanation of the virtual machine
Virtual machines are virtual computers, and virtual machines we usually mention has two typical types.
1.1 One is a complete simulation of a computer
For example hyper-V,VMWare
There is also an arcade machine simulator
1.2 The other type only acts as an execution environment.
For example, JVM, dotnet framework and V8\lua
For developers, the implementation environment is divided into two major categories.
1.2.1 Public execution environment
For example, java c# python
1.2.2 One is the embedded execution environment
For example, lua is a typically embedded script.
Of course, there are cases where c# and js are used as embedded scripts through mono and v8.
2 What is NeoVM
NeoVM is in the form of 1.2.2 above. It’s similar to Lua and is an embedded execution environment.
NeoVM is a virtual machine based on the Turing machine mode, which realizes logical operations by changing the state of the head on the tape.
NeoVM is a separate system that does not rely on the Neo project. NeoVM only provides pure logic computing capabilities, uses scalable interoperability, and then inserts functions that virtual machines can call.
NeoVM is designed to be closer to a machine. The code segment that is executed is a block of memory that parses the data into instructions on the fly.
3 How is NeoVM executed
To explain this, we must review the Turing machine.
Please ignore my ugly handwriting.
I assume that you understand how tape music players work. Otherwise, head and tape would become concepts that are hard to understand.
1. Write instructions on tape.
2. The head is responsible for reading the current instruction.
3. The instruction set is known. Four instructions are shown in the figure.
Nop does nothing. Push [n] pushes a number into calcstack, from which add takes two values, adds them, and puts them back in calcstack. ret ends the current execution.
4. Register space manages state. For NeoVM, registers are two Stacks: CalcStack and AltStack
There is a tape, head, instruction set, and state space. This is a Turing machine.
4 talk is cheap
Let’s take a look at the code.
Code is in samples/turing01
Less than 100 lines of code simulate the execution of the Turing machine in that ugly picture
First, get the tape with code ready.
NOP
PUSH 1
PUSH 2
ADD
RET
Then scroll the tape and let the code roll down under the head
while(!vm.stop)
{
…
}
This involves the shutdown of the Turing machine; the ret command is to inform the shutdown. Otherwise, we will continue to scroll. Of course, you can also rely on the length of the paper tape to stop. In fact, NEOVM is designed to stop automatically when the paper tape runs out. I believe that no one will suspect that the retvalue obtained by this program is 3.
Let’s analyze what happened.
This is just a simulation program. Explain one problem at a time. We use the class head to represent the tape head and the List to represent the tape.
The rolling tape is accumulated by head.pos
The state space is the stop variable and the calcstack stack
The steps to execute the instruction are written in the function StepOne
The process of StepOne is 1. Read the code on the tape head 2. Execute code 3. Roll tape head.pos++;
Executing code is operating state space
NOP doesn’t do anything, but NOP is still one of the most important instructions, so just treat him as a blank.
RET directly causes downtime, and the head does not roll anymore, the head position is also part of the state space, and the command can cause the head position to change. This is important because the essence of flow control is the head position change. All logics including if, for, and while are finally changing the head position to VM
PUSH pushes a value onto calcstack
ADD takes two values from calcstack and adds them together and puts them back
If you run this program, breakpoints, StepOne step by step, observe calcstack, you will find:
1. After nop, nothing happens after
2. After push 1, calcstack is [1]
3. After push 2, calcstack is [2,1]
4. After add, calcstack is [3]
5. After ret, stop becomes true, so the loop ends.
That is how NEOVM works.
For NEOVM, .avm is the tape, the difference is that avm is byte[], not structured like the List we use here.
The purpose of this article is to explain what NEOVM is and how it works. I just used this simple procedure first for the explanation.
I will continue to explain more in the next article.
Please refer to the source code at https://github.com/lightszero/neovmbook/tree/master/samples/turing01