[08] Finishes VM Implementation

Lots of different changes:

- modular code with lots of helper methods
- fixed the return jump address getting overridden bug
master
Nemo 2 years ago
parent 979976cb93
commit aed6f0a372
  1. 6
      NOTES.md
  2. 5
      README.md
  3. 12
      assembler/assembler.rb
  4. 50
      projects/07/MemoryAccess/BasicTest/BasicTest.asm
  5. 0
      projects/07/MemoryAccess/MemoryAccess.asm
  6. 30
      projects/07/MemoryAccess/PointerTest/PointerTest.asm
  7. 22
      projects/07/MemoryAccess/StaticTest/StaticTest.asm
  8. 52
      projects/07/StackArithmetic/SimpleAdd/SimpleAdd.asm
  9. 76
      projects/07/StackArithmetic/StackTest/StackTest.asm
  10. 4
      projects/07/StackArithmetic/StackTest/StackTest.out
  11. 860
      projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm
  12. 5
      projects/08/FunctionCalls/FibonacciElement/Sys.vm
  13. 564
      projects/08/FunctionCalls/NestedCall/NestedCall.asm
  14. 2
      projects/08/FunctionCalls/NestedCall/NestedCall.out
  15. 40
      projects/08/FunctionCalls/NestedCall/Sys.vm
  16. 132
      projects/08/FunctionCalls/SimpleFunction/Correct.asm
  17. 36
      projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm
  18. 2
      projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst
  19. 656
      projects/08/FunctionCalls/StaticsTest/StaticsTest.asm
  20. 2
      projects/08/FunctionCalls/StaticsTest/StaticsTest.out
  21. 30
      projects/08/ProgramFlow/BasicLoop/BasicLoop.asm
  22. 74
      projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm
  23. 379
      vm/CodeWriter.php
  24. 7
      vm/VMTranslator.php

@ -68,3 +68,9 @@ I think there are definitely some tricks with reducing lookup table sizes, but I
# VM (1)
See `vm/README.md` for more details. Observations go here, implementation notes are there.
# VM (2)
Learnt quite a lot. Interesting gotchas:
1. Stack manipuation is hard. Keeping track of registers is hard. I was going by the diagrams which always have "arguments" going from 0..n, which screws up the one case where you don't have arguments for a function, and ARG points to the same location where the return address is stored. In case the VM writes the return value to ARG[0], and you have zero arguments - it will also overwrite the return address, and your whole stack will go haywire (I got cool designs on my screen because of this).

@ -121,5 +121,6 @@ wc -l file.hack
## Function Calling Commands
- [x] `SimpleFunction.vm` (128)
- [ ] `FibonacciElement.vm`
- [ ] `StaticsTest.vm`
- [x] `FibonacciElement` (434)
- [x] `NestedCall.vm` (556)
- [x] `StaticsTest.vm` (664)

@ -94,9 +94,15 @@ class Code
end
def self.comp(str)
str.strip!
key = str.gsub(/[AM]/, 'Y')
(str.include?('M') ? '1' : '0') + COMP_MAP[key]
begin
str.strip!
key = str.gsub(/[AM]/, 'Y')
(str.include?('M') ? '1' : '0') + COMP_MAP[key]
rescue Exception => e
puts "failed at #{key}: #{str}"
exit
end
end
end

@ -4,27 +4,27 @@ D=A
A=M
M=D
@SP
M=M+1 // end push constant 10 (L0)
M=M+1
@SP // pop
AM=M-1
D=M
@LCL
A=M // Read @LCL to A (for local 0)
M=D // end pop local 0 (L1)
M=D // end pop local 0
@21 // push constant 21
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 21 (L2)
M=M+1
@22 // push constant 22
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 22 (L3)
M=M+1
@ARG // argument 2
D=M
@2 // write 2 to A
@ -36,7 +36,7 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for argument 2)
M=D // end pop argument 2 (L4)
M=D // end pop argument 2
@ARG // argument 1
D=M
@1 // write 1 to A
@ -48,14 +48,14 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for argument 1)
M=D // end pop argument 1 (L5)
M=D // end pop argument 1
@36 // push constant 36
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 36 (L6)
M=M+1
@THIS // this 6
D=M
@6 // write 6 to A
@ -67,21 +67,21 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for this 6)
M=D // end pop this 6 (L7)
M=D // end pop this 6
@42 // push constant 42
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 42 (L8)
M=M+1
@45 // push constant 45
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 45 (L9)
M=M+1
@THAT // that 5
D=M
@5 // write 5 to A
@ -93,7 +93,7 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for that 5)
M=D // end pop that 5 (L10)
M=D // end pop that 5
@THAT // that 2
D=M
@2 // write 2 to A
@ -105,19 +105,19 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for that 2)
M=D // end pop that 2 (L11)
M=D // end pop that 2
@510 // push constant 510
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 510 (L12)
M=M+1
@SP
AM=M-1
D=M
@R11
M=D // end pop temp 6 (L13)
M=D // end pop temp 6
@LCL
A=M
D=M
@ -125,7 +125,7 @@ D=M
A=M
M=D
@SP
M=M+1 // end push local 0 (L14)
M=M+1
@THAT // that 5
D=M
@5 // write 5 to A
@ -139,14 +139,14 @@ D=M
A=M
M=D
@SP
M=M+1 // end push that 5 (L15)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L16)
M=M-1 // end add
@ARG // argument 1
D=M
@1 // write 1 to A
@ -160,14 +160,14 @@ D=M
A=M
M=D
@SP
M=M+1 // end push argument 1 (L17)
M=M+1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1 // end sub (L18)
M=M-1 // end sub
@THIS // this 6
D=M
@6 // write 6 to A
@ -181,7 +181,7 @@ D=M
A=M
M=D
@SP
M=M+1 // end push this 6 (L19)
M=M+1
@THIS // this 6
D=M
@6 // write 6 to A
@ -195,34 +195,34 @@ D=M
A=M
M=D
@SP
M=M+1 // end push this 6 (L20)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L21)
M=M-1 // end add
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1 // end sub (L22)
M=M-1 // end sub
@R11 // temp 6
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push temp 6 (L23)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L24)
M=M-1 // end add
@227
0;JMP

@ -4,31 +4,31 @@ D=A
A=M
M=D
@SP
M=M+1 // end push constant 3030 (L0)
M=M+1
@SP // pop
AM=M-1
D=M
@THIS
M=D // (L1)
M=D //
@3040 // push constant 3040
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 3040 (L2)
M=M+1
@SP // pop
AM=M-1
D=M
@THAT
M=D // (L3)
M=D //
@32 // push constant 32
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32 (L4)
M=M+1
@THIS // this 2
D=M
@2 // write 2 to A
@ -40,14 +40,14 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for this 2)
M=D // end pop this 2 (L5)
M=D // end pop this 2
@46 // push constant 46
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 46 (L6)
M=M+1
@THAT // that 6
D=M
@6 // write 6 to A
@ -59,28 +59,28 @@ AM=M-1
D=M
@R13
A=M // Read @R13 to A (for that 6)
M=D // end pop that 6 (L7)
M=D // end pop that 6
@THIS // pointer 0
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push pointer 0 (L8)
M=M+1
@THAT // pointer 1
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push pointer 1 (L9)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L10)
M=M-1 // end add
@THIS // this 2
D=M
@2 // write 2 to A
@ -94,14 +94,14 @@ D=M
A=M
M=D
@SP
M=M+1 // end push this 2 (L11)
M=M+1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1 // end sub (L12)
M=M-1 // end sub
@THAT // that 6
D=M
@6 // write 6 to A
@ -115,13 +115,13 @@ D=M
A=M
M=D
@SP
M=M+1 // end push that 6 (L13)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L14)
M=M-1 // end add
@126
0;JMP

@ -4,70 +4,70 @@ D=A
A=M
M=D
@SP
M=M+1 // end push constant 111 (L0)
M=M+1
@333 // push constant 333
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 333 (L1)
M=M+1
@888 // push constant 888
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 888 (L2)
M=M+1
@SP //pop static 8
AM=M-1
D=M
@StaticTest.8
M=D // end pop static 8 (L3)
M=D // end pop static 8
@SP //pop static 3
AM=M-1
D=M
@StaticTest.3
M=D // end pop static 3 (L4)
M=D // end pop static 3
@SP //pop static 1
AM=M-1
D=M
@StaticTest.1
M=D // end pop static 1 (L5)
M=D // end pop static 1
@StaticTest.3
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push static 3 (L6)
M=M+1
@StaticTest.1
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push static 1 (L7)
M=M+1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1 // end sub (L8)
M=M-1 // end sub
@StaticTest.8
D=M
@SP
A=M
M=D
@SP
M=M+1 // end push static 8 (L9)
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1 // end add (L10)
M=M-1 // end add
@72
0;JMP

@ -1,29 +1,23 @@
// push constant 7
@7
D=A
@SP
A=M
M=D
@SP
M=M+1
// end push constant 7
// push constant 8
@8
D=A
@SP
A=M
M=D
@SP
M=M+1
// end push constant 8
// ==== add ====
// pop starts
@SP
A=M-1
D=M
// pop ends
// inner add starts
A=A-1
M=D+M
@SP
M=M-1
@7 // push constant 7 // (L0:0)
D=A // (L0:1)
@SP // (L0:2)
A=M // (L0:3)
M=D // (L0:4)
@SP // (L0:5)
M=M+1 // (L0:6)
@8 // push constant 8 // (L1:7)
D=A // (L1:8)
@SP // (L1:9)
A=M // (L1:10)
M=D // (L1:11)
@SP // (L1:12)
M=M+1 // (L1:13)
@SP // ==== add ==== // (L2:14)
A=M-1 // (L2:15)
D=M // (L2:16)
A=A-1 // (L2:17)
M=D+M // (L2:18)
@SP // (L2:19)
M=M-1 // end add // (L2:20)
@22 // (L3:21)
0;JMP // (L3:22)

@ -4,14 +4,14 @@ D=A
A=M
M=D
@SP
M=M+1 // end push constant 17
M=M+1
@17 // push constant 17
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 17
M=M+1
@SP // ==== eq ====
A=M-1
D=M
@ -26,21 +26,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end eq
@17 // push constant 17
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 17
M=M+1
@16 // push constant 16
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 16
M=M+1
@SP // ==== eq ====
A=M-1
D=M
@ -55,21 +55,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end eq
@16 // push constant 16
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 16
M=M+1
@17 // push constant 17
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 17
M=M+1
@SP // ==== eq ====
A=M-1
D=M
@ -84,21 +84,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end eq
@892 // push constant 892
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 892
M=M+1
@891 // push constant 891
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 891
M=M+1
@SP // ==== lt ====
A=M-1
D=M
@ -113,21 +113,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end lt
@891 // push constant 891
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 891
M=M+1
@892 // push constant 892
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 892
M=M+1
@SP // ==== lt ====
A=M-1
D=M
@ -142,21 +142,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end lt
@891 // push constant 891
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 891
M=M+1
@891 // push constant 891
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 891
M=M+1
@SP // ==== lt ====
A=M-1
D=M
@ -171,21 +171,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end lt
@32767 // push constant 32767
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32767
M=M+1
@32766 // push constant 32766
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32766
M=M+1
@SP // ==== gt ====
A=M-1
D=M
@ -200,21 +200,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end gt
@32766 // push constant 32766
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32766
M=M+1
@32767 // push constant 32767
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32767
M=M+1
@SP // ==== gt ====
A=M-1
D=M
@ -229,21 +229,21 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end gt
@32766 // push constant 32766
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32766
M=M+1
@32766 // push constant 32766
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 32766
M=M+1
@SP // ==== gt ====
A=M-1
D=M
@ -258,77 +258,77 @@ A=M-1
A=A-1
M=0
@SP
M=M-1
M=M-1 // end gt
@57 // push constant 57
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 57
M=M+1
@31 // push constant 31
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 31
M=M+1
@53 // push constant 53
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 53
M=M+1
@SP // ==== add ====
A=M-1
D=M
A=A-1
M=D+M
@SP
M=M-1
M=M-1 // end add
@112 // push constant 112
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 112
M=M+1
@SP // ==== sub ====
A=M-1
D=M
A=A-1
M=M-D
@SP
M=M-1
M=M-1 // end sub
@SP // ==== neg ====
A=M-1
D=M
M=-M
M=-M // end neg
@SP // ==== and ====
A=M-1
D=M
A=A-1
M=D&M
@SP
M=M-1
M=M-1 // end and
@82 // push constant 82
D=A
@SP
A=M
M=D
@SP
M=M+1 // end push constant 82
M=M+1
@SP // ==== or ====
A=M-1
D=M
A=A-1
M=D|M
@SP
M=M-1
M=M-1 // end or
@SP // ==== not ====
A=M-1
D=M
M=!M
M=!M // end not
@333
0;JMP

@ -0,0 +1,4 @@
| RAM[0] | RAM[256] | RAM[257] | RAM[258] | RAM[259] | RAM[260] |
| 266 | -1 | 0 | 0 | 0 | -1 |
| RAM[261] | RAM[262] | RAM[263] | RAM[264] | RAM[265] |
| 0 | -1 | 0 | 0 | -91 |

@ -1,417 +1,443 @@
@256 // init starts // (L0:0)
D=A // (L0:1)
@SP // (L0:2)
M=D // initialized SP to 256 // (L0:3)
@3000 // (L0:4)
D=A // (L0:5)
@LCL // (L0:6)
M=D // initialized @LCL to 3000 // (L0:7)
@4000 // (L0:8)
D=A // (L0:9)
@ARG // (L0:10)
M=D // initialized @ARG to 4000, init ends // (L0:11)
@18d95170022c2d762027b64da6c88d0a // call Sys.init 0 start // (L0:12)
D=A // (L0:13)
@SP // (L0:14)
A=M // (L0:15)
M=D // (L0:16)
@SP // (L0:17)
M=M+1 // (L0:18)
@LCL // Read @LCL to A // (L0:19)
D=M // Put @LCL to D // (L0:20)
@SP // (L0:21)
A=M // (L0:22)
M=D // Save @LCL to SP // (L0:23)
@SP // (L0:24)
M=M+1 // end @LCL pushed to SP // (L0:25)
@ARG // Read @ARG to A // (L0:26)
D=M // Put @ARG to D // (L0:27)
@SP // (L0:28)
A=M // (L0:29)
M=D // Save @ARG to SP // (L0:30)
@SP // (L0:31)
M=M+1 // end @ARG pushed to SP // (L0:32)
@THIS // Read @THIS to A // (L0:33)
D=M // Put @THIS to D // (L0:34)
@SP // (L0:35)
A=M // (L0:36)
M=D // Save @THIS to SP // (L0:37)
@SP // (L0:38)
M=M+1 // end @THIS pushed to SP // (L0:39)
@THAT // Read @THAT to A // (L0:40)
D=M // Put @THAT to D // (L0:41)
@SP // (L0:42)
A=M // (L0:43)
M=D // Save @THAT to SP // (L0:44)
@SP // (L0:45)
M=M+1 // end @THAT pushed to SP // (L0:46)
@SP // (L0:47)
D=M // (L0:48)
@LCL // (L0:49)
M=D // Update LCL=SP // (L0:50)
D=D-1 // should repeat 5 times // (L0:51)
D=D-1 // should repeat 5 times // (L0:52)
D=D-1 // should repeat 5 times // (L0:53)
D=D-1 // should repeat 5 times // (L0:54)
D=D-1 // should repeat 5 times // (L0:55)
@ARG // write D to ARG // (L0:56)
M=D // (L0:57)
@Sys.init // Jump to Sys.init // (L0:58)
0;JMP // (L0:59)
(18d95170022c2d762027b64da6c88d0a) // return back from function here (CALL ENDS) // (L0:60)
(Main.fibonacci) // function Main.fibonacci 0 // (L0:60)
@ARG // (L1:60)
A=M // (L1:61)
D=M // (L1:62)
@SP // (L1:63)
A=M // (L1:64)
M=D // (L1:65)
@SP // (L1:66)
M=M+1 // end push argument 0 // (L1:67)
@2 // push constant 2 // (L2:68)
D=A // (L2:69)
@SP // (L2:70)
A=M // (L2:71)
M=D // (L2:72)
@SP // (L2:73)
M=M+1 // end push constant 2 // (L2:74)
@SP // ==== lt ==== // (L3:75)
A=M-1 // (L3:76)
D=M // (L3:77)
A=A-1 // (L3:78)
D=M-D // (L3:79)
M=0 // (L3:80)
M=M-1 // (L3:81)
@89 // (L3:82)
D;JLT // (L3:83)
@SP // (L3:84)
A=M-1 // (L3:85)
A=A-1 // (L3:86)
M=0 // (L3:87)
@SP // (L3:88)
M=M-1 // end lt // (L3:89)
@SP // (L4:90)
AM=M-1 // (L4:91)
D=M // (L4:92)
@Main.fibonacciIF_TRUE // (L4:93)
D;JNE // end if-goto IF_TRUE // (L4:94)
@Main.fibonacciIF_FALSE // (L5:95)
0;JMP // end goto IF_FALSE // (L5:96)
(Main.fibonacciIF_TRUE) // end label IF_TRUE // (L6:97)
@ARG // (L7:97)
A=M // (L7:98)
D=M // (L7:99)
@SP // (L7:100)
A=M // (L7:101)
M=D // (L7:102)
@SP // (L7:103)
M=M+1 // end push argument 0 // (L7:104)
@SP // (L8:105)
A=M-1 // (L8:106)
D=M // (L8:107)
@ARG // (L8:108)
A=M // (L8:109)
M=D // (L8:110)
@ARG // (L8:111)
D=M+1 // (L8:112)
@SP // (L8:113)
M=D // @SP = ARG+1 // (L8:114)
@LCL // (L8:115)
D=M // (L8:116)
@R13 // (L8:117)
M=D // Save LCL to R13 // (L8:118)
A=D-1 // A=*LCL-1 // (L8:119)
D=M // D=*(*LCL-1) // (L8:120)
@THAT // A=THAT // (L8:121)
M=D // *that = *(*lcl-1) // (L8:122)
@R13 // (L8:123)
A=M-1 // (L8:124)
A=A-1 // A=*LCL-2 // (L8:125)
D=M // D=*(*LCL-2) // (L8:126)
@THIS // A=THIS // (L8:127)
M=D // *THIS = *(*lcl-2) // (L8:128)
@R13 // (L8:129)
A=M-1 // (L8:130)
A=A-1 // (L8:131)
A=A-1 // A=*LCL-3 // (L8:132)
D=M // D=*(*LCL-3) // (L8:133)
@ARG // A=ARG // (L8:134)
M=D // *ARG = *(*lcl-3) // (L8:135)
@R13 // (L8:136)
A=M-1 // (L8:137)
A=A-1 // (L8:138)
A=A-1 // (L8:139)
A=A-1 // A=*LCL-4 // (L8:140)
D=M // D=*(*LCL-4) // (L8:141)
@LCL // A=LCL // (L8:142)
M=D // *LCL = *(*lcl-4) // (L8:143)
@R13 // (L8:144)
A=M-1 // (L8:145)
A=A-1 // (L8:146)
A=A-1 // (L8:147)
A=A-1 // (L8:148)
A=A-1 // A=*LCL-5 // (L8:149)
A=M // A=*(*LCL-5) // (L8:150)
0;JMP // Jump to *(LCL-5) // (L8:151)
(Main.fibonacciIF_FALSE) // end label IF_FALSE // (L9:152)
@ARG // (L10:152)
A=M // (L10:153)
D=M // (L10:154)
@SP // (L10:155)
A=M // (L10:156)
M=D // (L10:157)
@SP // (L10:158)
M=M+1 // end push argument 0 // (L10:159)
@2 // push constant 2 // (L11:160)
D=A // (L11:161)
@SP // (L11:162)
A=M // (L11:163)
M=D // (L11:164)
@SP // (L11:165)
M=M+1 // end push constant 2 // (L11:166)
@SP // ==== sub ==== // (L12:167)
A=M-1 // (L12:168)
D=M // (L12:169)
A=A-1 // (L12:170)
M=M-D // (L12:171)
@SP // (L12:172)
M=M-1 // end sub // (L12:173)
@a3b7fa05917ee725f45e2c66ce232f37 // call Main.fibonacci 1 start // (L13:174)
D=A // (L13:175)
@SP // (L13:176)
A=M // (L13:177)
M=D // (L13:178)
@SP // (L13:179)
M=M+1 // (L13:180)
@LCL // Read @LCL to A // (L13:181)
D=M // Put @LCL to D // (L13:182)
@SP // (L13:183)
A=M // (L13:184)
M=D // Save @LCL to SP // (L13:185)
@SP // (L13:186)
M=M+1 // end @LCL pushed to SP // (L13:187)
@ARG // Read @ARG to A // (L13:188)
D=M // Put @ARG to D // (L13:189)
@SP // (L13:190)
A=M // (L13:191)
M=D // Save @ARG to SP // (L13:192)
@SP // (L13:193)
M=M+1 // end @ARG pushed to SP // (L13:194)
@THIS // Read @THIS to A // (L13:195)
D=M // Put @THIS to D // (L13:196)
@SP // (L13:197)
A=M // (L13:198)
M=D // Save @THIS to SP // (L13:199)
@SP // (L13:200)
M=M+1 // end @THIS pushed to SP // (L13:201)
@THAT // Read @THAT to A // (L13:202)
D=M // Put @THAT to D // (L13:203)
@SP // (L13:204)
A=M // (L13:205)
M=D // Save @THAT to SP // (L13:206)
@SP // (L13:207)
M=M+1 // end @THAT pushed to SP // (L13:208)
@SP // (L13:209)
D=M // (L13:210)
@LCL // (L13:211)
M=D // Update LCL=SP // (L13:212)
D=D-1 // should repeat 6 times // (L13:213)
D=D-1 // should repeat 6 times // (L13:214)
D=D-1 // should repeat 6 times // (L13:215)
D=D-1 // should repeat 6 times // (L13:216)
D=D-1 // should repeat 6 times // (L13:217)
D=D-1 // should repeat 6 times // (L13:218)
@ARG // write D to ARG // (L13:219)
M=D // (L13:220)
@Main.fibonacci // Jump to Main.fibonacci // (L13:221)
0;JMP // (L13:222)
(a3b7fa05917ee725f45e2c66ce232f37) // return back from function here (CALL ENDS) // (L13:223)
@ARG // (L14:223)
A=M // (L14:224)
D=M // (L14:225)
@SP // (L14:226)
A=M // (L14:227)
M=D // (L14:228)
@SP // (L14:229)
M=M+1 // end push argument 0 // (L14:230)
@1 // push constant 1 // (L15:231)
D=A // (L15:232)
@SP // (L15:233)
A=M // (L15:234)
M=D // (L15:235)
@SP // (L15:236)
M=M+1 // end push constant 1 // (L15:237)
@SP // ==== sub ==== // (L16:238)
A=M-1 // (L16:239)
D=M // (L16:240)
A=A-1 // (L16:241)
M=M-D // (L16:242)
@SP // (L16:243)
M=M-1 // end sub // (L16:244)
@59c3e1ed914ff5e6e713615a6bb2a5e2 // call Main.fibonacci 1 start // (L17:245)
D=A // (L17:246)
@SP // (L17:247)
A=M // (L17:248)
M=D // (L17:249)
@SP // (L17:250)
M=M+1 // (L17:251)
@LCL // Read @LCL to A // (L17:252)
D=M // Put @LCL to D // (L17:253)
@SP // (L17:254)
A=M // (L17:255)
M=D // Save @LCL to SP // (L17:256)
@SP // (L17:257)
M=M+1 // end @LCL pushed to SP // (L17:258)
@ARG // Read @ARG to A // (L17:259)
D=M // Put @ARG to D // (L17:260)
@SP // (L17:261)
A=M // (L17:262)
M=D // Save @ARG to SP // (L17:263)
@SP // (L17:264)
M=M+1 // end @ARG pushed to SP // (L17:265)
@THIS // Read @THIS to A // (L17:266)
D=M // Put @THIS to D // (L17:267)
@SP // (L17:268)
A=M // (L17:269)
M=D // Save @THIS to SP // (L17:270)
@SP // (L17:271)
M=M+1 // end @THIS pushed to SP // (L17:272)
@THAT // Read @THAT to A // (L17:273)
D=M // Put @THAT to D // (L17:274)
@SP // (L17:275)
A=M // (L17:276)
M=D // Save @THAT to SP // (L17:277)
@SP // (L17:278)
M=M+1 // end @THAT pushed to SP // (L17:279)
@SP // (L17:280)
D=M // (L17:281)
@LCL // (L17:282)
M=D // Update LCL=SP // (L17:283)
D=D-1 // should repeat 6 times // (L17:284)
D=D-1 // should repeat 6 times // (L17:285)
D=D-1 // should repeat 6 times // (L17:286)
D=D-1 // should repeat 6 times // (L17:287)
D=D-1 // should repeat 6 times // (L17:288)
D=D-1 // should repeat 6 times // (L17:289)
@ARG // write D to ARG // (L17:290)
M=D // (L17:291)
@Main.fibonacci // Jump to Main.fibonacci // (L17:292)
0;JMP // (L17:293)
(59c3e1ed914ff5e6e713615a6bb2a5e2) // return back from function here (CALL ENDS) // (L17:294)
@SP // ==== add ==== // (L18:294)
A=M-1 // (L18:295)
D=M // (L18:296)
A=A-1 // (L18:297)
M=D+M // (L18:298)
@SP // (L18:299)
M=M-1 // end add // (L18:300)
@SP // (L19:301)
A=M-1 // (L19:302)
D=M // (L19:303)
@ARG // (L19:304)
A=M // (L19:305)
M=D // (L19:306)
@ARG // (L19:307)
D=M+1 // (L19:308)
@SP // (L19:309)
M=D // @SP = ARG+1 // (L19:310)
@LCL // (L19:311)
D=M // (L19:312)
@R13 // (L19:313)
M=D // Save LCL to R13 // (L19:314)
A=D-1 // A=*LCL-1 // (L19:315)
D=M // D=*(*LCL-1) // (L19:316)
@THAT // A=THAT // (L19:317)
M=D // *that = *(*lcl-1) // (L19:318)
@R13 // (L19:319)
A=M-1 // (L19:320)
A=A-1 // A=*LCL-2 // (L19:321)
D=M // D=*(*LCL-2) // (L19:322)
@THIS // A=THIS // (L19:323)
M=D // *THIS = *(*lcl-2) // (L19:324)
@R13 // (L19:325)
A=M-1 // (L19:326)
A=A-1 // (L19:327)
A=A-1 // A=*LCL-3 // (L19:328)
D=M // D=*(*LCL-3) // (L19:329)
@ARG // A=ARG // (L19:330)
M=D // *ARG = *(*lcl-3) // (L19:331)
@R13 // (L19:332)
A=M-1 // (L19:333)
A=A-1 // (L19:334)
A=A-1 // (L19:335)
A=A-1 // A=*LCL-4 // (L19:336)
D=M // D=*(*LCL-4) // (L19:337)
@LCL // A=LCL // (L19:338)
M=D // *LCL = *(*lcl-4) // (L19:339)
@R13 // (L19:340)
A=M-1 // (L19:341)
A=A-1 // (L19:342)
A=A-1 // (L19:343)
A=A-1 // (L19:344)
A=A-1 // A=*LCL-5 // (L19:345)
A=M // A=*(*LCL-5) // (L19:346)
0;JMP // Jump to *(LCL-5) // (L19:347)
(Sys.init) // function Sys.init 0 // (L20:348)
@4 // push constant 4 // (L21:348)
D=A // (L21:349)
@SP // (L21:350)
A=M // (L21:351)
M=D // (L21:352)
@SP // (L21:353)
M=M+1 // end push constant 4 // (L21:354)
@c28123f096da12e9e9a4357d4823b8d2 // call Main.fibonacci 1 start // (L22:355)
D=A // (L22:356)
@SP // (L22:357)
A=M // (L22:358)
M=D // (L22:359)
@SP // (L22:360)
M=M+1 // (L22:361)
@LCL // Read @LCL to A // (L22:362)
D=M // Put @LCL to D // (L22:363)
@SP // (L22:364)
A=M // (L22:365)
M=D // Save @LCL to SP // (L22:366)
@SP // (L22:367)
M=M+1 // end @LCL pushed to SP // (L22:368)
@ARG // Read @ARG to A // (L22:369)
D=M // Put @ARG to D // (L22:370)
@SP // (L22:371)
A=M // (L22:372)
M=D // Save @ARG to SP // (L22:373)
@SP // (L22:374)
M=M+1 // end @ARG pushed to SP // (L22:375)
@THIS // Read @THIS to A // (L22:376)
D=M // Put @THIS to D // (L22:377)
@SP // (L22:378)
A=M // (L22:379)
M=D // Save @THIS to SP // (L22:380)
@SP // (L22:381)
M=M+1 // end @THIS pushed to SP // (L22:382)
@THAT // Read @THAT to A // (L22:383)
D=M // Put @THAT to D // (L22:384)
@SP // (L22:385)
A=M // (L22:386)
M=D // Save @THAT to SP // (L22:387)
@SP // (L22:388)
M=M+1 // end @THAT pushed to SP // (L22:389)
@SP // (L22:390)
D=M // (L22:391)
@LCL // (L22:392)
M=D // Update LCL=SP // (L22:393)
D=D-1 // should repeat 6 times // (L22:394)
D=D-1 // should repeat 6 times // (L22:395)
D=D-1 // should repeat 6 times // (L22:396)
D=D-1 // should repeat 6 times // (L22:397)
D=D-1 // should repeat 6 times // (L22:398)
D=D-1 // should repeat 6 times // (L22:399)
@ARG // write D to ARG // (L22:400)
M=D // (L22:401)
@Main.fibonacci // Jump to Main.fibonacci // (L22:402)
0;JMP // (L22:403)
(c28123f096da12e9e9a4357d4823b8d2) // return back from function here (CALL ENDS) // (L22:404)