Files
mvm/README.md

228 lines
8.5 KiB
Markdown

# MVM
## MVM Architecture
List of available instructions:
| Op. code | Op. mnemo | Description |
|:--------:|:-----------|:-------------------------------------------------------------------------------|
| ``0x00`` | ``NOP`` | No operation |
| ``0x01`` | ``HALT`` | Stop the program execution |
| ``0x02`` | ``PUSH x`` | Push number to stack |
| ``0x03`` | ``POP`` | Pop number from a stack |
| ``0x04`` | ``DUP`` | Duplicate the top stack element |
| ``0x05`` | ``SWAP`` | Swap first and second stack elements |
| ``0x06`` | ``ADD`` | Pop 1st and 2nd stack elements, add them and push to stack |
| ``0x07`` | ``SUB`` | Pop 1st and 2nd stack elements, subtract them and push to stack |
| ``0x08`` | ``MUL`` | Pop 1st and 2nd stack elements, multiply them and push to stack |
| ``0x09`` | ``DIV`` | Pop 1st and 2nd stack elements, divide them and push to stack |
| ``0x0A`` | ``NEG`` | Negate the top stack element |
| ``0x0B`` | ``NOT`` | Pop top stack element. If it's equal to ``0`` then push ``1``, else push ``0`` |
| ``0x0C`` | ``CALL x`` | Jump to the ``x`` address and push new stack frame |
| ``0x0D`` | ``RET`` | Return to the caller and pop the stack frame |
| ``0x0E`` | ``JMP x`` | Perform the unconditional jump to ``x`` address |
| ``0x0F`` | ``JE x`` | Jump to ``x`` **if** top element ``== 0`` |
| ``0x10`` | ``JNE x`` | Jump to ``x`` **if** top element ``!= 0`` |
| ``0x11`` | ``JG x`` | Jump to ``x`` **if** top element ``> 0 `` |
| ``0x12`` | ``JL x`` | Jump to ``x`` **if** top element ``< 0 `` |
| ``0x13`` | ``JGE x`` | Jump to ``x`` **if** top element ``>= 0`` |
| ``0x14`` | ``JLE x`` | Jump to ``x`` **if** top element ``<= 0`` |
| ``0x15`` | ``LDA x`` | Push local variable to stack |
| ``0x16`` | ``IN`` | Read input from stdin |
| ``0x17`` | ``OUT`` | Put top stack value to stdout as char |
| ``0x18`` | ``CLR x`` | Wipe out ``x`` values before the top value from the stack |
| ``0x19`` | ``OVER`` | Duplicate and push the second value from the top |
| ``0x1A`` | ``LDL x`` | Lift the ``x`` from the _fp_ variable to the top of the stack |
| ``0x1B`` | ``STL x`` | Store the top stack value under the ``x`` from the _fp_ variable |
## Example
### Example 1
The `2*3+5` formula written as the MVM assembly code:
```asm
main: push 2
push 3
call &prd
clr 2
push 5
call &sum
clr 2
halt
sum: lda 0
lda 1
add
ret
prd: lda 0
lda 1
mul
ret
```
The result of execution with the `debug = True` flag:
```
VM {_pc = 0, _fp = -1, _stack = fromList [], _halt = False, _debug = True}
0: Push 2
VM {_pc = 2, _fp = -1, _stack = fromList [2], _halt = False, _debug = True}
2: Push 3
VM {_pc = 4, _fp = -1, _stack = fromList [3,2], _halt = False, _debug = True}
4: Call 21
VM {_pc = 21, _fp = 2, _stack = fromList [6,-1,3,2], _halt = False, _debug = True}
21: Ld 0
VM {_pc = 23, _fp = 2, _stack = fromList [3,6,-1,3,2], _halt = False, _debug = True}
23: Ld 1
VM {_pc = 25, _fp = 2, _stack = fromList [2,3,6,-1,3,2], _halt = False, _debug = True}
25: Mul
VM {_pc = 26, _fp = 2, _stack = fromList [6,6,-1,3,2], _halt = False, _debug = True}
26: Ret
VM {_pc = 6, _fp = -1, _stack = fromList [6,3,2], _halt = False, _debug = True}
6: Clr 2
VM {_pc = 8, _fp = -1, _stack = fromList [6], _halt = False, _debug = True}
8: Push 5
VM {_pc = 10, _fp = -1, _stack = fromList [5,6], _halt = False, _debug = True}
10: Call 15
VM {_pc = 15, _fp = 2, _stack = fromList [12,-1,5,6], _halt = False, _debug = True}
15: Ld 0
VM {_pc = 17, _fp = 2, _stack = fromList [5,12,-1,5,6], _halt = False, _debug = True}
17: Ld 1
VM {_pc = 19, _fp = 2, _stack = fromList [6,5,12,-1,5,6], _halt = False, _debug = True}
19: Add
VM {_pc = 20, _fp = 2, _stack = fromList [11,12,-1,5,6], _halt = False, _debug = True}
20: Ret
VM {_pc = 12, _fp = -1, _stack = fromList [11,5,6], _halt = False, _debug = True}
12: Clr 2
VM {_pc = 14, _fp = -1, _stack = fromList [11], _halt = False, _debug = True}
14: Halt
Done:
VM {_pc = 14, _fp = -1, _stack = fromList [11], _halt = True, _debug = True}
```
### Example 2
The base I/O example - simple echo:
```asm
read: in
dup
out
push 0x0A
sub
jne &read ; loop until the input != new line (0x0A)
halt
```
The execution for the input string `Hello, world!`:
```
Hello, world!
Done:
VM {_pc = 8, _fp = -1, _stack = fromList [], _halt = True, _debug = False}
```
### Example 3
The power (`2^10`) computation - loop variant
```asm
push 2
push 10
call &pow
clr 2
halt
pow: lda 1 ; base
lda 0 ; exp
push 1 ; acc
; | Stack:
.loop: ldl 1 ; if exp == 0 | exp
je &.done ; then return | exp
pop ; |
; |
ldl 2 ; Evaluate | acc
ldl 0 ; next power | acc base
mul ; | acc*base
stl 2 ; |
; |
ldl 1 ; Decrement exp | exp
push 1 ; | exp 1
sub ; | exp-1
stl 1 ; |
jmp &.loop ; |
.done: ldl 2 ; | ... acc
ret ; | acc
```
The result of execution:
```
Done:
VM {_pc = 8, _fp = -1, _stack = fromList [1024], _halt = True, _debug = False}
```
### Example 4
The power (`2^10`) computation - recursive variant
```asm
push 2 ; base
push 10 ; exp
call &pow
clr 2
halt
pow: lda 1 ; base
lda 0 ; exp
ldl 1 ; push exp to top
je &.edge ; the edge case: if exp == 0 then return 1
pop ; pop exp
; | Stack:
ldl 0 ; | base
ldl 1 ; | base exp
push 1 ; | base exp 1
sub ; | base exp-1
call &pow ; | base exp-1 base^(exp-1)]
clr 1 ; | base base^(exp-1)
mul ; | base*base^(exp-1)
ret ; | base*base^(exp-1)
.edge: pop
push 1 ; return 1
ret
```
The result of execution:
```
Done:
VM {_pc = 8, _fp = -1, _stack = fromList [1024], _halt = True, _debug = False}
```
### Example 5
The `N`-th element of Fibbonaci sequence - recursive variant
```asm
push 6
call &fibb
clr 1
halt
fibb: lda 0 ; n | Stack:
ldl 0 ; n == 0 -> return 1 | n
je &.done0 ; | n
pop ; |
ldl 0 ; n == 1 -> return 1 | n
push 1 ; | n 1
sub ; | n-1
je &.done1 ; | n-1
dup ; Evaluate fibb | n-1 n-1
push 1 ; | n-1 n-1 1
sub ; | n-1 n-2
call &fibb ; | n-1 n-2 f(n-2)
clr 1 ; | n-1 f(n-2)
over ; | n-1 f(n-2) n-1
call &fibb ; | n-1 f(n-2) n-1 f(n-1)
clr 1 ; | n-1 f(n-2) f(n-1)
add ; | n-1 f(n-2)+f(n-1)
ret
.done1: pop
push 1
ret
.done0: pop
push 1
ret
```
The result of execution:
```
Done:
VM {_pc = 6, _fp = -1, _stack = fromList [13], _halt = True, _debug = False}
```