From aed6f0a3725589e14fe718eaa5130001fb06b2d4 Mon Sep 17 00:00:00 2001 From: Nemo Date: Thu, 4 Jun 2020 21:05:02 +0530 Subject: [PATCH] [08] Finishes VM Implementation Lots of different changes: - modular code with lots of helper methods - fixed the return jump address getting overridden bug --- NOTES.md | 6 + README.md | 5 +- assembler/assembler.rb | 12 +- .../07/MemoryAccess/BasicTest/BasicTest.asm | 50 +- projects/07/MemoryAccess/MemoryAccess.asm | 0 .../MemoryAccess/PointerTest/PointerTest.asm | 30 +- .../07/MemoryAccess/StaticTest/StaticTest.asm | 22 +- .../StackArithmetic/SimpleAdd/SimpleAdd.asm | 52 +- .../StackArithmetic/StackTest/StackTest.asm | 76 +- .../StackArithmetic/StackTest/StackTest.out | 4 + .../FibonacciElement/FibonacciElement.asm | 860 +++++++++--------- .../08/FunctionCalls/FibonacciElement/Sys.vm | 5 +- .../FunctionCalls/NestedCall/NestedCall.asm | 564 ++++++++++++ .../FunctionCalls/NestedCall/NestedCall.out | 2 + projects/08/FunctionCalls/NestedCall/Sys.vm | 40 +- .../FunctionCalls/SimpleFunction/Correct.asm | 132 +++ .../SimpleFunction/SimpleFunction.asm | 36 +- .../SimpleFunction/SimpleFunction.tst | 2 +- .../FunctionCalls/StaticsTest/StaticsTest.asm | 656 +++++++++++++ .../FunctionCalls/StaticsTest/StaticsTest.out | 2 + .../08/ProgramFlow/BasicLoop/BasicLoop.asm | 30 +- .../FibonacciSeries/FibonacciSeries.asm | 74 +- vm/CodeWriter.php | 385 ++++---- vm/VMTranslator.php | 7 + 24 files changed, 2243 insertions(+), 809 deletions(-) create mode 100644 projects/07/MemoryAccess/MemoryAccess.asm create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCall.asm create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCall.out create mode 100644 projects/08/FunctionCalls/SimpleFunction/Correct.asm create mode 100644 projects/08/FunctionCalls/StaticsTest/StaticsTest.asm create mode 100644 projects/08/FunctionCalls/StaticsTest/StaticsTest.out diff --git a/NOTES.md b/NOTES.md index 7fa5552..8d1459e 100644 --- a/NOTES.md +++ b/NOTES.md @@ -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). diff --git a/README.md b/README.md index b149060..33ca3ff 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/assembler/assembler.rb b/assembler/assembler.rb index d4aaa86..47380b4 100644 --- a/assembler/assembler.rb +++ b/assembler/assembler.rb @@ -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 diff --git a/projects/07/MemoryAccess/BasicTest/BasicTest.asm b/projects/07/MemoryAccess/BasicTest/BasicTest.asm index 2c67438..1e6a303 100644 --- a/projects/07/MemoryAccess/BasicTest/BasicTest.asm +++ b/projects/07/MemoryAccess/BasicTest/BasicTest.asm @@ -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 diff --git a/projects/07/MemoryAccess/MemoryAccess.asm b/projects/07/MemoryAccess/MemoryAccess.asm new file mode 100644 index 0000000..e69de29 diff --git a/projects/07/MemoryAccess/PointerTest/PointerTest.asm b/projects/07/MemoryAccess/PointerTest/PointerTest.asm index 420b30f..76fd09e 100644 --- a/projects/07/MemoryAccess/PointerTest/PointerTest.asm +++ b/projects/07/MemoryAccess/PointerTest/PointerTest.asm @@ -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 diff --git a/projects/07/MemoryAccess/StaticTest/StaticTest.asm b/projects/07/MemoryAccess/StaticTest/StaticTest.asm index 754a1a1..e889156 100644 --- a/projects/07/MemoryAccess/StaticTest/StaticTest.asm +++ b/projects/07/MemoryAccess/StaticTest/StaticTest.asm @@ -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 diff --git a/projects/07/StackArithmetic/SimpleAdd/SimpleAdd.asm b/projects/07/StackArithmetic/SimpleAdd/SimpleAdd.asm index 9307c85..98774d2 100644 --- a/projects/07/StackArithmetic/SimpleAdd/SimpleAdd.asm +++ b/projects/07/StackArithmetic/SimpleAdd/SimpleAdd.asm @@ -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) diff --git a/projects/07/StackArithmetic/StackTest/StackTest.asm b/projects/07/StackArithmetic/StackTest/StackTest.asm index 7c4a6ac..1185dc4 100644 --- a/projects/07/StackArithmetic/StackTest/StackTest.asm +++ b/projects/07/StackArithmetic/StackTest/StackTest.asm @@ -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 diff --git a/projects/07/StackArithmetic/StackTest/StackTest.out b/projects/07/StackArithmetic/StackTest/StackTest.out index e69de29..cb182ec 100644 --- a/projects/07/StackArithmetic/StackTest/StackTest.out +++ b/projects/07/StackArithmetic/StackTest/StackTest.out @@ -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 | diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm index c923bd7..86400c7 100644 --- a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm @@ -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) -(Sys.initWHILE) // end label WHILE // (L23:404) -@Sys.initWHILE // (L24:404) -0;JMP // end goto WHILE // (L24:405) -@407 // (L25:406) -0;JMP // (L25:407) +@256 // (L0:0) (writeConstantToRegister(SP, 256):256) +D=A // (L0:1) (writeConstantToRegister(SP, 256):256) +@SP // (L0:2) (writeConstantToRegister(SP, 256):261) +M=D // initialized SP to 256 // (L0:3) (writeConstantToRegister(SP, 256):261) +@1 // (L0:4) (writeConstantToRegister(LCL, 1):249) +D=-A // (L0:5) (writeConstantToRegister(LCL, 1):249) +@LCL // (L0:6) (writeConstantToRegister(LCL, 1):261) +M=D // initialized LCL to 1 // (L0:7) (writeConstantToRegister(LCL, 1):261) +@2 // (L0:8) (writeConstantToRegister(ARG, 2):249) +D=-A // (L0:9) (writeConstantToRegister(ARG, 2):249) +@ARG // (L0:10) (writeConstantToRegister(ARG, 2):261) +M=D // initialized ARG to 2 // (L0:11) (writeConstantToRegister(ARG, 2):261) +@3 // (L0:12) (writeConstantToRegister(THIS, 3):249) +D=-A // (L0:13) (writeConstantToRegister(THIS, 3):249) +@THIS // (L0:14) (writeConstantToRegister(THIS, 3):261) +M=D // initialized THIS to 3 // (L0:15) (writeConstantToRegister(THIS, 3):261) +@4 // (L0:16) (writeConstantToRegister(THAT, 4):249) +D=-A // (L0:17) (writeConstantToRegister(THAT, 4):249) +@THAT // (L0:18) (writeConstantToRegister(THAT, 4):261) +M=D // initialized THAT to 4 // (L0:19) (writeConstantToRegister(THAT, 4):261) +@6e7326e08d60c5537dbe2d92224d7534 // (L0:20) (push(label, 6e7326e08d60c5537dbe2d92224d7534):53) +D=A // (L0:21) (push(label, 6e7326e08d60c5537dbe2d92224d7534):53) +@SP // (L0:22) (writeDtoSPAndBump():62) +A=M // (L0:23) (writeDtoSPAndBump():62) +M=D // (L0:24) (writeDtoSPAndBump():62) +@SP // (L0:25) (increaseSP():72) +M=M+1 // (L0:26) (increaseSP():72) +@LCL // (L0:27) (push(register, LCL, 1):42) +AD=M // (L0:28) (push(register, LCL, 1):42) +@SP // (L0:29) (writeDtoSPAndBump():62) +A=M // (L0:30) (writeDtoSPAndBump():62) +M=D // (L0:31) (writeDtoSPAndBump():62) +@SP // (L0:32) (increaseSP():72) +M=M+1 // (L0:33) (increaseSP():72) +@ARG // (L0:34) (push(register, ARG, 1):42) +AD=M // (L0:35) (push(register, ARG, 1):42) +@SP // (L0:36) (writeDtoSPAndBump():62) +A=M // (L0:37) (writeDtoSPAndBump():62) +M=D // (L0:38) (writeDtoSPAndBump():62) +@SP // (L0:39) (increaseSP():72) +M=M+1 // (L0:40) (increaseSP():72) +@THIS // (L0:41) (push(register, THIS, 1):42) +AD=M // (L0:42) (push(register, THIS, 1):42) +@SP // (L0:43) (writeDtoSPAndBump():62) +A=M // (L0:44) (writeDtoSPAndBump():62) +M=D // (L0:45) (writeDtoSPAndBump():62) +@SP // (L0:46) (increaseSP():72) +M=M+1 // (L0:47) (increaseSP():72) +@THAT // (L0:48) (push(register, THAT, 1):42) +AD=M // (L0:49) (push(register, THAT, 1):42) +@SP // (L0:50) (writeDtoSPAndBump():62) +A=M // (L0:51) (writeDtoSPAndBump():62) +M=D // (L0:52) (writeDtoSPAndBump():62) +@SP // (L0:53) (increaseSP():72) +M=M+1 // (L0:54) (increaseSP():72) +@SP // (L0:55) (copy(SP, LCL):186) +D=M // (L0:56) (copy(SP, LCL):186) +@LCL // (L0:57) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L0:58) (copy(SP, LCL):186) +@SP // (L0:59) (loadOffsetToD(SP, 5, -):193) +D=M // (L0:60) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L0:61) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:62) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:63) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:64) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:65) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L0:66) (writeCall(Sys.init, 0):230) +M=D // (L0:67) (writeCall(Sys.init, 0):230) +@Sys.init // Jump to Sys.init // (L0:68) (writeCall(Sys.init, 0):230) +0;JMP // (L0:69) (writeCall(Sys.init, 0):230) +(6e7326e08d60c5537dbe2d92224d7534) // return back from function here (CALL ENDS) // (L0:70) (writeCall(Sys.init, 0):230) +(__GLOBAL_TERMINATE__) // (L0:70) (writeCall(Sys.init, 0):237) +@__GLOBAL_TERMINATE__ // (L0:70) (writeCall(Sys.init, 0):237) +0;JMP // (L0:71) (writeCall(Sys.init, 0):237) +(Main.fibonacci) // function Main.fibonacci 0 // (L0:72) (writeFunction(Main.fibonacci, 0):156) +@ARG // (L1:72) (writePush(argument, 0):494) +A=M // (L1:73) (writePush(argument, 0):494) +D=M // (L1:74) (writePush(argument, 0):494) +@SP // (L1:75) (writeDtoSPAndBump():62) +A=M // (L1:76) (writeDtoSPAndBump():62) +M=D // (L1:77) (writeDtoSPAndBump():62) +@SP // (L1:78) (increaseSP():72) +M=M+1 // (L1:79) (increaseSP():72) +@2 // push constant 2 // (L2:80) (writePush(constant, 2):479) +D=A // (L2:81) (writePush(constant, 2):479) +@SP // (L2:82) (writeDtoSPAndBump():62) +A=M // (L2:83) (writeDtoSPAndBump():62) +M=D // (L2:84) (writeDtoSPAndBump():62) +@SP // (L2:85) (increaseSP():72) +M=M+1 // (L2:86) (increaseSP():72) +@SP // ==== lt ==== // (L3:87) (writeArithmetic(lt):408) +A=M-1 // (L3:88) (writeArithmetic(lt):408) +D=M // (L3:89) (writeArithmetic(lt):408) +A=A-1 // (L3:90) (booleanCompare(LT):398) +D=M-D // (L3:91) (booleanCompare(LT):398) +M=0 // (L3:92) (booleanCompare(LT):398) +M=M-1 // (L3:93) (booleanCompare(LT):398) +@100 // (L3:94) (booleanCompare(LT):398) +D;JLT // (L3:95) (booleanCompare(LT):398) +@SP // (L3:96) (booleanCompare(LT):398) +A=M-1 // (L3:97) (booleanCompare(LT):398) +A=A-1 // (L3:98) (booleanCompare(LT):398) +M=0 // (L3:99) (booleanCompare(LT):398) +@SP // (L3:100) (writeArithmetic(lt):441) +M=M-1 // end lt // (L3:101) (writeArithmetic(lt):441) +@SP // (L4:102) (writeIf(IF_TRUE):346) +AM=M-1 // (L4:103) (writeIf(IF_TRUE):346) +D=M // (L4:104) (writeIf(IF_TRUE):346) +@Main.fibonacciIF_TRUE // (L4:105) (writeIf(IF_TRUE):346) +D;JNE // end if-goto IF_TRUE // (L4:106) (writeIf(IF_TRUE):346) +@Main.fibonacciIF_FALSE // (L5:107) (writeGoto(IF_FALSE):329) +0;JMP // end goto IF_FALSE // (L5:108) (writeGoto(IF_FALSE):329) +(Main.fibonacciIF_TRUE) // end label IF_TRUE // (L6:109) (writeLabel(IF_TRUE):308) +@ARG // (L7:109) (writePush(argument, 0):494) +A=M // (L7:110) (writePush(argument, 0):494) +D=M // (L7:111) (writePush(argument, 0):494) +@SP // (L7:112) (writeDtoSPAndBump():62) +A=M // (L7:113) (writeDtoSPAndBump():62) +M=D // (L7:114) (writeDtoSPAndBump():62) +@SP // (L7:115) (increaseSP():72) +M=M+1 // (L7:116) (increaseSP():72) +@LCL // save return address first // (L8:117) (writeReturn():143) +A=M-1 // (L8:118) (writeReturn():143) +A=A-1 // (L8:119) (writeReturn():143) +A=A-1 // (L8:120) (writeReturn():143) +A=A-1 // (L8:121) (writeReturn():143) +A=A-1 // (L8:122) (writeReturn():143) +D=M // D now holds the return address // (L8:123) (writeReturn():143) +@R14 // (L8:124) (writeReturn():143) +M=D // Wrote the return address to R14 // (L8:125) (writeReturn():143) +@SP // return for Main.fibonacci starts // (L8:126) (writeReturn():143) +A=M-1 // (L8:127) (writeReturn():143) +D=M // (L8:128) (writeReturn():143) +@ARG // (L8:129) (writeReturn():143) +A=M // (L8:130) (writeReturn():143) +M=D // (L8:131) (writeReturn():143) +@ARG // (L8:132) (writeReturn():143) +D=M+1 // (L8:133) (writeReturn():143) +@SP // (L8:134) (writeReturn():143) +M=D // @SP = ARG+1 // (L8:135) (writeReturn():143) +@LCL // (L8:136) (writeReturn():143) +D=M // (L8:137) (writeReturn():143) +@R13 // (L8:138) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L8:139) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L8:140) (writeReturn():143) +D=M // D=*(*LCL-1) // (L8:141) (writeReturn():143) +@THAT // A=THAT // (L8:142) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L8:143) (writeReturn():143) +@R13 // (L8:144) (writeReturn():143) +A=M-1 // (L8:145) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L8:146) (writeReturn():143) +D=M // D=*(*LCL-2) // (L8:147) (writeReturn():143) +@THIS // A=THIS // (L8:148) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L8:149) (writeReturn():143) +@R13 // (L8:150) (writeReturn():143) +A=M-1 // (L8:151) (writeReturn():143) +A=A-1 // (L8:152) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L8:153) (writeReturn():143) +D=M // D=*(*LCL-3) // (L8:154) (writeReturn():143) +@ARG // A=ARG // (L8:155) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L8:156) (writeReturn():143) +@R13 // (L8:157) (writeReturn():143) +A=M-1 // (L8:158) (writeReturn():143) +A=A-1 // (L8:159) (writeReturn():143) +A=A-1 // (L8:160) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L8:161) (writeReturn():143) +D=M // D=*(*LCL-4) // (L8:162) (writeReturn():143) +@LCL // A=LCL // (L8:163) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L8:164) (writeReturn():143) +@R14 // (L8:165) (writeReturn():143) +A=M // (L8:166) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L8:167) (writeReturn():143) +(Main.fibonacciIF_FALSE) // end label IF_FALSE // (L9:168) (writeLabel(IF_FALSE):308) +@ARG // (L10:168) (writePush(argument, 0):494) +A=M // (L10:169) (writePush(argument, 0):494) +D=M // (L10:170) (writePush(argument, 0):494) +@SP // (L10:171) (writeDtoSPAndBump():62) +A=M // (L10:172) (writeDtoSPAndBump():62) +M=D // (L10:173) (writeDtoSPAndBump():62) +@SP // (L10:174) (increaseSP():72) +M=M+1 // (L10:175) (increaseSP():72) +@2 // push constant 2 // (L11:176) (writePush(constant, 2):479) +D=A // (L11:177) (writePush(constant, 2):479) +@SP // (L11:178) (writeDtoSPAndBump():62) +A=M // (L11:179) (writeDtoSPAndBump():62) +M=D // (L11:180) (writeDtoSPAndBump():62) +@SP // (L11:181) (increaseSP():72) +M=M+1 // (L11:182) (increaseSP():72) +@SP // ==== sub ==== // (L12:183) (writeArithmetic(sub):408) +A=M-1 // (L12:184) (writeArithmetic(sub):408) +D=M // (L12:185) (writeArithmetic(sub):408) +A=A-1 // (L12:186) (binaryMath(sub):362) +M=D-M // (L12:187) (binaryMath(sub):362) +M=-M // (L12:188) (binaryMath(sub):367) +@SP // (L12:189) (writeArithmetic(sub):441) +M=M-1 // end sub // (L12:190) (writeArithmetic(sub):441) +@6d2922146084c2a55380cd1ec9a8cea5 // (L13:191) (push(label, 6d2922146084c2a55380cd1ec9a8cea5):53) +D=A // (L13:192) (push(label, 6d2922146084c2a55380cd1ec9a8cea5):53) +@SP // (L13:193) (writeDtoSPAndBump():62) +A=M // (L13:194) (writeDtoSPAndBump():62) +M=D // (L13:195) (writeDtoSPAndBump():62) +@SP // (L13:196) (increaseSP():72) +M=M+1 // (L13:197) (increaseSP():72) +@LCL // (L13:198) (push(register, LCL, 1):42) +AD=M // (L13:199) (push(register, LCL, 1):42) +@SP // (L13:200) (writeDtoSPAndBump():62) +A=M // (L13:201) (writeDtoSPAndBump():62) +M=D // (L13:202) (writeDtoSPAndBump():62) +@SP // (L13:203) (increaseSP():72) +M=M+1 // (L13:204) (increaseSP():72) +@ARG // (L13:205) (push(register, ARG, 1):42) +AD=M // (L13:206) (push(register, ARG, 1):42) +@SP // (L13:207) (writeDtoSPAndBump():62) +A=M // (L13:208) (writeDtoSPAndBump():62) +M=D // (L13:209) (writeDtoSPAndBump():62) +@SP // (L13:210) (increaseSP():72) +M=M+1 // (L13:211) (increaseSP():72) +@THIS // (L13:212) (push(register, THIS, 1):42) +AD=M // (L13:213) (push(register, THIS, 1):42) +@SP // (L13:214) (writeDtoSPAndBump():62) +A=M // (L13:215) (writeDtoSPAndBump():62) +M=D // (L13:216) (writeDtoSPAndBump():62) +@SP // (L13:217) (increaseSP():72) +M=M+1 // (L13:218) (increaseSP():72) +@THAT // (L13:219) (push(register, THAT, 1):42) +AD=M // (L13:220) (push(register, THAT, 1):42) +@SP // (L13:221) (writeDtoSPAndBump():62) +A=M // (L13:222) (writeDtoSPAndBump():62) +M=D // (L13:223) (writeDtoSPAndBump():62) +@SP // (L13:224) (increaseSP():72) +M=M+1 // (L13:225) (increaseSP():72) +@SP // (L13:226) (copy(SP, LCL):186) +D=M // (L13:227) (copy(SP, LCL):186) +@LCL // (L13:228) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L13:229) (copy(SP, LCL):186) +@SP // (L13:230) (loadOffsetToD(SP, 6, -):193) +D=M // (L13:231) (loadOffsetToD(SP, 6, -):193) +D=D-1 // should repeat 6 times // (L13:232) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L13:233) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L13:234) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L13:235) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L13:236) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L13:237) (loadOffsetToD(SP, 6, -):198) +@ARG // write SP-$offset to ARG // (L13:238) (writeCall(Main.fibonacci, 1):230) +M=D // (L13:239) (writeCall(Main.fibonacci, 1):230) +@Main.fibonacci // Jump to Main.fibonacci // (L13:240) (writeCall(Main.fibonacci, 1):230) +0;JMP // (L13:241) (writeCall(Main.fibonacci, 1):230) +(6d2922146084c2a55380cd1ec9a8cea5) // return back from function here (CALL ENDS) // (L13:242) (writeCall(Main.fibonacci, 1):230) +@ARG // (L14:242) (writePush(argument, 0):494) +A=M // (L14:243) (writePush(argument, 0):494) +D=M // (L14:244) (writePush(argument, 0):494) +@SP // (L14:245) (writeDtoSPAndBump():62) +A=M // (L14:246) (writeDtoSPAndBump():62) +M=D // (L14:247) (writeDtoSPAndBump():62) +@SP // (L14:248) (increaseSP():72) +M=M+1 // (L14:249) (increaseSP():72) +@1 // push constant 1 // (L15:250) (writePush(constant, 1):479) +D=A // (L15:251) (writePush(constant, 1):479) +@SP // (L15:252) (writeDtoSPAndBump():62) +A=M // (L15:253) (writeDtoSPAndBump():62) +M=D // (L15:254) (writeDtoSPAndBump():62) +@SP // (L15:255) (increaseSP():72) +M=M+1 // (L15:256) (increaseSP():72) +@SP // ==== sub ==== // (L16:257) (writeArithmetic(sub):408) +A=M-1 // (L16:258) (writeArithmetic(sub):408) +D=M // (L16:259) (writeArithmetic(sub):408) +A=A-1 // (L16:260) (binaryMath(sub):362) +M=D-M // (L16:261) (binaryMath(sub):362) +M=-M // (L16:262) (binaryMath(sub):367) +@SP // (L16:263) (writeArithmetic(sub):441) +M=M-1 // end sub // (L16:264) (writeArithmetic(sub):441) +@a7aac510d992984b8f917d1b5a72010a // (L17:265) (push(label, a7aac510d992984b8f917d1b5a72010a):53) +D=A // (L17:266) (push(label, a7aac510d992984b8f917d1b5a72010a):53) +@SP // (L17:267) (writeDtoSPAndBump():62) +A=M // (L17:268) (writeDtoSPAndBump():62) +M=D // (L17:269) (writeDtoSPAndBump():62) +@SP // (L17:270) (increaseSP():72) +M=M+1 // (L17:271) (increaseSP():72) +@LCL // (L17:272) (push(register, LCL, 1):42) +AD=M // (L17:273) (push(register, LCL, 1):42) +@SP // (L17:274) (writeDtoSPAndBump():62) +A=M // (L17:275) (writeDtoSPAndBump():62) +M=D // (L17:276) (writeDtoSPAndBump():62) +@SP // (L17:277) (increaseSP():72) +M=M+1 // (L17:278) (increaseSP():72) +@ARG // (L17:279) (push(register, ARG, 1):42) +AD=M // (L17:280) (push(register, ARG, 1):42) +@SP // (L17:281) (writeDtoSPAndBump():62) +A=M // (L17:282) (writeDtoSPAndBump():62) +M=D // (L17:283) (writeDtoSPAndBump():62) +@SP // (L17:284) (increaseSP():72) +M=M+1 // (L17:285) (increaseSP():72) +@THIS // (L17:286) (push(register, THIS, 1):42) +AD=M // (L17:287) (push(register, THIS, 1):42) +@SP // (L17:288) (writeDtoSPAndBump():62) +A=M // (L17:289) (writeDtoSPAndBump():62) +M=D // (L17:290) (writeDtoSPAndBump():62) +@SP // (L17:291) (increaseSP():72) +M=M+1 // (L17:292) (increaseSP():72) +@THAT // (L17:293) (push(register, THAT, 1):42) +AD=M // (L17:294) (push(register, THAT, 1):42) +@SP // (L17:295) (writeDtoSPAndBump():62) +A=M // (L17:296) (writeDtoSPAndBump():62) +M=D // (L17:297) (writeDtoSPAndBump():62) +@SP // (L17:298) (increaseSP():72) +M=M+1 // (L17:299) (increaseSP():72) +@SP // (L17:300) (copy(SP, LCL):186) +D=M // (L17:301) (copy(SP, LCL):186) +@LCL // (L17:302) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L17:303) (copy(SP, LCL):186) +@SP // (L17:304) (loadOffsetToD(SP, 6, -):193) +D=M // (L17:305) (loadOffsetToD(SP, 6, -):193) +D=D-1 // should repeat 6 times // (L17:306) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L17:307) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L17:308) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L17:309) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L17:310) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L17:311) (loadOffsetToD(SP, 6, -):198) +@ARG // write SP-$offset to ARG // (L17:312) (writeCall(Main.fibonacci, 1):230) +M=D // (L17:313) (writeCall(Main.fibonacci, 1):230) +@Main.fibonacci // Jump to Main.fibonacci // (L17:314) (writeCall(Main.fibonacci, 1):230) +0;JMP // (L17:315) (writeCall(Main.fibonacci, 1):230) +(a7aac510d992984b8f917d1b5a72010a) // return back from function here (CALL ENDS) // (L17:316) (writeCall(Main.fibonacci, 1):230) +@SP // ==== add ==== // (L18:316) (writeArithmetic(add):408) +A=M-1 // (L18:317) (writeArithmetic(add):408) +D=M // (L18:318) (writeArithmetic(add):408) +A=A-1 // (L18:319) (binaryMath(add):362) +M=D+M // (L18:320) (binaryMath(add):362) +@SP // (L18:321) (writeArithmetic(add):441) +M=M-1 // end add // (L18:322) (writeArithmetic(add):441) +@LCL // save return address first // (L19:323) (writeReturn():143) +A=M-1 // (L19:324) (writeReturn():143) +A=A-1 // (L19:325) (writeReturn():143) +A=A-1 // (L19:326) (writeReturn():143) +A=A-1 // (L19:327) (writeReturn():143) +A=A-1 // (L19:328) (writeReturn():143) +D=M // D now holds the return address // (L19:329) (writeReturn():143) +@R14 // (L19:330) (writeReturn():143) +M=D // Wrote the return address to R14 // (L19:331) (writeReturn():143) +@SP // return for Main.fibonacci starts // (L19:332) (writeReturn():143) +A=M-1 // (L19:333) (writeReturn():143) +D=M // (L19:334) (writeReturn():143) +@ARG // (L19:335) (writeReturn():143) +A=M // (L19:336) (writeReturn():143) +M=D // (L19:337) (writeReturn():143) +@ARG // (L19:338) (writeReturn():143) +D=M+1 // (L19:339) (writeReturn():143) +@SP // (L19:340) (writeReturn():143) +M=D // @SP = ARG+1 // (L19:341) (writeReturn():143) +@LCL // (L19:342) (writeReturn():143) +D=M // (L19:343) (writeReturn():143) +@R13 // (L19:344) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L19:345) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L19:346) (writeReturn():143) +D=M // D=*(*LCL-1) // (L19:347) (writeReturn():143) +@THAT // A=THAT // (L19:348) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L19:349) (writeReturn():143) +@R13 // (L19:350) (writeReturn():143) +A=M-1 // (L19:351) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L19:352) (writeReturn():143) +D=M // D=*(*LCL-2) // (L19:353) (writeReturn():143) +@THIS // A=THIS // (L19:354) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L19:355) (writeReturn():143) +@R13 // (L19:356) (writeReturn():143) +A=M-1 // (L19:357) (writeReturn():143) +A=A-1 // (L19:358) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L19:359) (writeReturn():143) +D=M // D=*(*LCL-3) // (L19:360) (writeReturn():143) +@ARG // A=ARG // (L19:361) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L19:362) (writeReturn():143) +@R13 // (L19:363) (writeReturn():143) +A=M-1 // (L19:364) (writeReturn():143) +A=A-1 // (L19:365) (writeReturn():143) +A=A-1 // (L19:366) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L19:367) (writeReturn():143) +D=M // D=*(*LCL-4) // (L19:368) (writeReturn():143) +@LCL // A=LCL // (L19:369) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L19:370) (writeReturn():143) +@R14 // (L19:371) (writeReturn():143) +A=M // (L19:372) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L19:373) (writeReturn():143) +(Sys.init) // function Sys.init 0 // (L20:374) (writeFunction(Sys.init, 0):156) +@4 // push constant 4 // (L21:374) (writePush(constant, 4):479) +D=A // (L21:375) (writePush(constant, 4):479) +@SP // (L21:376) (writeDtoSPAndBump():62) +A=M // (L21:377) (writeDtoSPAndBump():62) +M=D // (L21:378) (writeDtoSPAndBump():62) +@SP // (L21:379) (increaseSP():72) +M=M+1 // (L21:380) (increaseSP():72) +@cec5690d4862446080b0f0423fc92b55 // (L22:381) (push(label, cec5690d4862446080b0f0423fc92b55):53) +D=A // (L22:382) (push(label, cec5690d4862446080b0f0423fc92b55):53) +@SP // (L22:383) (writeDtoSPAndBump():62) +A=M // (L22:384) (writeDtoSPAndBump():62) +M=D // (L22:385) (writeDtoSPAndBump():62) +@SP // (L22:386) (increaseSP():72) +M=M+1 // (L22:387) (increaseSP():72) +@LCL // (L22:388) (push(register, LCL, 1):42) +AD=M // (L22:389) (push(register, LCL, 1):42) +@SP // (L22:390) (writeDtoSPAndBump():62) +A=M // (L22:391) (writeDtoSPAndBump():62) +M=D // (L22:392) (writeDtoSPAndBump():62) +@SP // (L22:393) (increaseSP():72) +M=M+1 // (L22:394) (increaseSP():72) +@ARG // (L22:395) (push(register, ARG, 1):42) +AD=M // (L22:396) (push(register, ARG, 1):42) +@SP // (L22:397) (writeDtoSPAndBump():62) +A=M // (L22:398) (writeDtoSPAndBump():62) +M=D // (L22:399) (writeDtoSPAndBump():62) +@SP // (L22:400) (increaseSP():72) +M=M+1 // (L22:401) (increaseSP():72) +@THIS // (L22:402) (push(register, THIS, 1):42) +AD=M // (L22:403) (push(register, THIS, 1):42) +@SP // (L22:404) (writeDtoSPAndBump():62) +A=M // (L22:405) (writeDtoSPAndBump():62) +M=D // (L22:406) (writeDtoSPAndBump():62) +@SP // (L22:407) (increaseSP():72) +M=M+1 // (L22:408) (increaseSP():72) +@THAT // (L22:409) (push(register, THAT, 1):42) +AD=M // (L22:410) (push(register, THAT, 1):42) +@SP // (L22:411) (writeDtoSPAndBump():62) +A=M // (L22:412) (writeDtoSPAndBump():62) +M=D // (L22:413) (writeDtoSPAndBump():62) +@SP // (L22:414) (increaseSP():72) +M=M+1 // (L22:415) (increaseSP():72) +@SP // (L22:416) (copy(SP, LCL):186) +D=M // (L22:417) (copy(SP, LCL):186) +@LCL // (L22:418) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L22:419) (copy(SP, LCL):186) +@SP // (L22:420) (loadOffsetToD(SP, 6, -):193) +D=M // (L22:421) (loadOffsetToD(SP, 6, -):193) +D=D-1 // should repeat 6 times // (L22:422) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L22:423) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L22:424) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L22:425) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L22:426) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L22:427) (loadOffsetToD(SP, 6, -):198) +@ARG // write SP-$offset to ARG // (L22:428) (writeCall(Main.fibonacci, 1):230) +M=D // (L22:429) (writeCall(Main.fibonacci, 1):230) +@Main.fibonacci // Jump to Main.fibonacci // (L22:430) (writeCall(Main.fibonacci, 1):230) +0;JMP // (L22:431) (writeCall(Main.fibonacci, 1):230) +(cec5690d4862446080b0f0423fc92b55) // return back from function here (CALL ENDS) // (L22:432) (writeCall(Main.fibonacci, 1):230) +@433 // (L23:432) (close():298) +0;JMP // (L23:433) (close():298) diff --git a/projects/08/FunctionCalls/FibonacciElement/Sys.vm b/projects/08/FunctionCalls/FibonacciElement/Sys.vm index 4cd3dc4..e82a3a7 100644 --- a/projects/08/FunctionCalls/FibonacciElement/Sys.vm +++ b/projects/08/FunctionCalls/FibonacciElement/Sys.vm @@ -5,11 +5,10 @@ // Pushes a constant, say n, onto the stack, and calls the Main.fibonacii // function, which computes the n'th element of the Fibonacci series. -// Note that by convention, the Sys.init function is called "automatically" +// Note that by convention, the Sys.init function is called "automatically" // by the bootstrap code. function Sys.init 0 push constant 4 call Main.fibonacci 1 // computes the 4'th fibonacci element -label WHILE -goto WHILE // loops infinitely + diff --git a/projects/08/FunctionCalls/NestedCall/NestedCall.asm b/projects/08/FunctionCalls/NestedCall/NestedCall.asm new file mode 100644 index 0000000..dee27d7 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCall.asm @@ -0,0 +1,564 @@ +@256 // (L0:0) (writeConstantToRegister(SP, 256):256) +D=A // (L0:1) (writeConstantToRegister(SP, 256):256) +@SP // (L0:2) (writeConstantToRegister(SP, 256):261) +M=D // initialized SP to 256 // (L0:3) (writeConstantToRegister(SP, 256):261) +@1 // (L0:4) (writeConstantToRegister(LCL, 1):249) +D=-A // (L0:5) (writeConstantToRegister(LCL, 1):249) +@LCL // (L0:6) (writeConstantToRegister(LCL, 1):261) +M=D // initialized LCL to 1 // (L0:7) (writeConstantToRegister(LCL, 1):261) +@2 // (L0:8) (writeConstantToRegister(ARG, 2):249) +D=-A // (L0:9) (writeConstantToRegister(ARG, 2):249) +@ARG // (L0:10) (writeConstantToRegister(ARG, 2):261) +M=D // initialized ARG to 2 // (L0:11) (writeConstantToRegister(ARG, 2):261) +@3 // (L0:12) (writeConstantToRegister(THIS, 3):249) +D=-A // (L0:13) (writeConstantToRegister(THIS, 3):249) +@THIS // (L0:14) (writeConstantToRegister(THIS, 3):261) +M=D // initialized THIS to 3 // (L0:15) (writeConstantToRegister(THIS, 3):261) +@4 // (L0:16) (writeConstantToRegister(THAT, 4):249) +D=-A // (L0:17) (writeConstantToRegister(THAT, 4):249) +@THAT // (L0:18) (writeConstantToRegister(THAT, 4):261) +M=D // initialized THAT to 4 // (L0:19) (writeConstantToRegister(THAT, 4):261) +@0b03b426552100ee665057636aa828eb // (L0:20) (push(label, 0b03b426552100ee665057636aa828eb):53) +D=A // (L0:21) (push(label, 0b03b426552100ee665057636aa828eb):53) +@SP // (L0:22) (writeDtoSPAndBump():62) +A=M // (L0:23) (writeDtoSPAndBump():62) +M=D // (L0:24) (writeDtoSPAndBump():62) +@SP // (L0:25) (increaseSP():72) +M=M+1 // (L0:26) (increaseSP():72) +@LCL // (L0:27) (push(register, LCL, 1):42) +AD=M // (L0:28) (push(register, LCL, 1):42) +@SP // (L0:29) (writeDtoSPAndBump():62) +A=M // (L0:30) (writeDtoSPAndBump():62) +M=D // (L0:31) (writeDtoSPAndBump():62) +@SP // (L0:32) (increaseSP():72) +M=M+1 // (L0:33) (increaseSP():72) +@ARG // (L0:34) (push(register, ARG, 1):42) +AD=M // (L0:35) (push(register, ARG, 1):42) +@SP // (L0:36) (writeDtoSPAndBump():62) +A=M // (L0:37) (writeDtoSPAndBump():62) +M=D // (L0:38) (writeDtoSPAndBump():62) +@SP // (L0:39) (increaseSP():72) +M=M+1 // (L0:40) (increaseSP():72) +@THIS // (L0:41) (push(register, THIS, 1):42) +AD=M // (L0:42) (push(register, THIS, 1):42) +@SP // (L0:43) (writeDtoSPAndBump():62) +A=M // (L0:44) (writeDtoSPAndBump():62) +M=D // (L0:45) (writeDtoSPAndBump():62) +@SP // (L0:46) (increaseSP():72) +M=M+1 // (L0:47) (increaseSP():72) +@THAT // (L0:48) (push(register, THAT, 1):42) +AD=M // (L0:49) (push(register, THAT, 1):42) +@SP // (L0:50) (writeDtoSPAndBump():62) +A=M // (L0:51) (writeDtoSPAndBump():62) +M=D // (L0:52) (writeDtoSPAndBump():62) +@SP // (L0:53) (increaseSP():72) +M=M+1 // (L0:54) (increaseSP():72) +@SP // (L0:55) (copy(SP, LCL):186) +D=M // (L0:56) (copy(SP, LCL):186) +@LCL // (L0:57) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L0:58) (copy(SP, LCL):186) +@SP // (L0:59) (loadOffsetToD(SP, 5, -):193) +D=M // (L0:60) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L0:61) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:62) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:63) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:64) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:65) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L0:66) (writeCall(Sys.init, 0):230) +M=D // (L0:67) (writeCall(Sys.init, 0):230) +@Sys.init // Jump to Sys.init // (L0:68) (writeCall(Sys.init, 0):230) +0;JMP // (L0:69) (writeCall(Sys.init, 0):230) +(0b03b426552100ee665057636aa828eb) // return back from function here (CALL ENDS) // (L0:70) (writeCall(Sys.init, 0):230) +(__GLOBAL_TERMINATE__) // (L0:70) (writeCall(Sys.init, 0):237) +@__GLOBAL_TERMINATE__ // (L0:70) (writeCall(Sys.init, 0):237) +0;JMP // (L0:71) (writeCall(Sys.init, 0):237) +(Sys.init) // function Sys.init 0 // (L0:72) (writeFunction(Sys.init, 0):156) +@4000 // push constant 4000 // (L1:72) (writePush(constant, 4000):479) +D=A // (L1:73) (writePush(constant, 4000):479) +@SP // (L1:74) (writeDtoSPAndBump():62) +A=M // (L1:75) (writeDtoSPAndBump():62) +M=D // (L1:76) (writeDtoSPAndBump():62) +@SP // (L1:77) (increaseSP():72) +M=M+1 // (L1:78) (increaseSP():72) +@SP // pop // (L2:79) (writePop(pointer, 0):610) +AM=M-1 // (L2:80) (writePop(pointer, 0):610) +D=M // (L2:81) (writePop(pointer, 0):610) +@THIS // (L2:82) (writePop(pointer, 0):610) +M=D // // (L2:83) (writePop(pointer, 0):610) +@5000 // push constant 5000 // (L3:84) (writePush(constant, 5000):479) +D=A // (L3:85) (writePush(constant, 5000):479) +@SP // (L3:86) (writeDtoSPAndBump():62) +A=M // (L3:87) (writeDtoSPAndBump():62) +M=D // (L3:88) (writeDtoSPAndBump():62) +@SP // (L3:89) (increaseSP():72) +M=M+1 // (L3:90) (increaseSP():72) +@SP // pop // (L4:91) (writePop(pointer, 1):610) +AM=M-1 // (L4:92) (writePop(pointer, 1):610) +D=M // (L4:93) (writePop(pointer, 1):610) +@THAT // (L4:94) (writePop(pointer, 1):610) +M=D // // (L4:95) (writePop(pointer, 1):610) +@85ac01c7c3896175d6727eb9db079220 // (L5:96) (push(label, 85ac01c7c3896175d6727eb9db079220):53) +D=A // (L5:97) (push(label, 85ac01c7c3896175d6727eb9db079220):53) +@SP // (L5:98) (writeDtoSPAndBump():62) +A=M // (L5:99) (writeDtoSPAndBump():62) +M=D // (L5:100) (writeDtoSPAndBump():62) +@SP // (L5:101) (increaseSP():72) +M=M+1 // (L5:102) (increaseSP():72) +@LCL // (L5:103) (push(register, LCL, 1):42) +AD=M // (L5:104) (push(register, LCL, 1):42) +@SP // (L5:105) (writeDtoSPAndBump():62) +A=M // (L5:106) (writeDtoSPAndBump():62) +M=D // (L5:107) (writeDtoSPAndBump():62) +@SP // (L5:108) (increaseSP():72) +M=M+1 // (L5:109) (increaseSP():72) +@ARG // (L5:110) (push(register, ARG, 1):42) +AD=M // (L5:111) (push(register, ARG, 1):42) +@SP // (L5:112) (writeDtoSPAndBump():62) +A=M // (L5:113) (writeDtoSPAndBump():62) +M=D // (L5:114) (writeDtoSPAndBump():62) +@SP // (L5:115) (increaseSP():72) +M=M+1 // (L5:116) (increaseSP():72) +@THIS // (L5:117) (push(register, THIS, 1):42) +AD=M // (L5:118) (push(register, THIS, 1):42) +@SP // (L5:119) (writeDtoSPAndBump():62) +A=M // (L5:120) (writeDtoSPAndBump():62) +M=D // (L5:121) (writeDtoSPAndBump():62) +@SP // (L5:122) (increaseSP():72) +M=M+1 // (L5:123) (increaseSP():72) +@THAT // (L5:124) (push(register, THAT, 1):42) +AD=M // (L5:125) (push(register, THAT, 1):42) +@SP // (L5:126) (writeDtoSPAndBump():62) +A=M // (L5:127) (writeDtoSPAndBump():62) +M=D // (L5:128) (writeDtoSPAndBump():62) +@SP // (L5:129) (increaseSP():72) +M=M+1 // (L5:130) (increaseSP():72) +@SP // (L5:131) (copy(SP, LCL):186) +D=M // (L5:132) (copy(SP, LCL):186) +@LCL // (L5:133) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L5:134) (copy(SP, LCL):186) +@SP // (L5:135) (loadOffsetToD(SP, 5, -):193) +D=M // (L5:136) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L5:137) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L5:138) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L5:139) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L5:140) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L5:141) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L5:142) (writeCall(Sys.main, 0):230) +M=D // (L5:143) (writeCall(Sys.main, 0):230) +@Sys.main // Jump to Sys.main // (L5:144) (writeCall(Sys.main, 0):230) +0;JMP // (L5:145) (writeCall(Sys.main, 0):230) +(85ac01c7c3896175d6727eb9db079220) // return back from function here (CALL ENDS) // (L5:146) (writeCall(Sys.main, 0):230) +@SP // (L6:146) (writePop(temp, 1):621) +AM=M-1 // (L6:147) (writePop(temp, 1):621) +D=M // (L6:148) (writePop(temp, 1):621) +@R6 // (L6:149) (writePop(temp, 1):621) +M=D // end pop temp 1 // (L6:150) (writePop(temp, 1):621) +(Sys.initLOOP) // end label LOOP // (L7:151) (writeLabel(LOOP):308) +@Sys.initLOOP // (L8:151) (writeGoto(LOOP):329) +0;JMP // end goto LOOP // (L8:152) (writeGoto(LOOP):329) +(Sys.main) // function Sys.main 5 // (L9:153) (writeFunction(Sys.main, 5):156) +@SP // (L9:153) (writeFunction(Sys.main, 5):165) +A=M // (L9:154) (writeFunction(Sys.main, 5):165) +M=0 // (L9:155) (writeFunction(Sys.main, 5):174) +@SP // (L9:156) (writeFunction(Sys.main, 5):174) +AM=M+1 // (L9:157) (writeFunction(Sys.main, 5):174) +M=0 // (L9:158) (writeFunction(Sys.main, 5):174) +@SP // (L9:159) (writeFunction(Sys.main, 5):174) +AM=M+1 // (L9:160) (writeFunction(Sys.main, 5):174) +M=0 // (L9:161) (writeFunction(Sys.main, 5):174) +@SP // (L9:162) (writeFunction(Sys.main, 5):174) +AM=M+1 // (L9:163) (writeFunction(Sys.main, 5):174) +M=0 // (L9:164) (writeFunction(Sys.main, 5):174) +@SP // (L9:165) (writeFunction(Sys.main, 5):174) +AM=M+1 // (L9:166) (writeFunction(Sys.main, 5):174) +M=0 // (L9:167) (writeFunction(Sys.main, 5):174) +@SP // (L9:168) (writeFunction(Sys.main, 5):174) +AM=M+1 // (L9:169) (writeFunction(Sys.main, 5):174) +@4001 // push constant 4001 // (L10:170) (writePush(constant, 4001):479) +D=A // (L10:171) (writePush(constant, 4001):479) +@SP // (L10:172) (writeDtoSPAndBump():62) +A=M // (L10:173) (writeDtoSPAndBump():62) +M=D // (L10:174) (writeDtoSPAndBump():62) +@SP // (L10:175) (increaseSP():72) +M=M+1 // (L10:176) (increaseSP():72) +@SP // pop // (L11:177) (writePop(pointer, 0):610) +AM=M-1 // (L11:178) (writePop(pointer, 0):610) +D=M // (L11:179) (writePop(pointer, 0):610) +@THIS // (L11:180) (writePop(pointer, 0):610) +M=D // // (L11:181) (writePop(pointer, 0):610) +@5001 // push constant 5001 // (L12:182) (writePush(constant, 5001):479) +D=A // (L12:183) (writePush(constant, 5001):479) +@SP // (L12:184) (writeDtoSPAndBump():62) +A=M // (L12:185) (writeDtoSPAndBump():62) +M=D // (L12:186) (writeDtoSPAndBump():62) +@SP // (L12:187) (increaseSP():72) +M=M+1 // (L12:188) (increaseSP():72) +@SP // pop // (L13:189) (writePop(pointer, 1):610) +AM=M-1 // (L13:190) (writePop(pointer, 1):610) +D=M // (L13:191) (writePop(pointer, 1):610) +@THAT // (L13:192) (writePop(pointer, 1):610) +M=D // // (L13:193) (writePop(pointer, 1):610) +@200 // push constant 200 // (L14:194) (writePush(constant, 200):479) +D=A // (L14:195) (writePush(constant, 200):479) +@SP // (L14:196) (writeDtoSPAndBump():62) +A=M // (L14:197) (writeDtoSPAndBump():62) +M=D // (L14:198) (writeDtoSPAndBump():62) +@SP // (L14:199) (increaseSP():72) +M=M+1 // (L14:200) (increaseSP():72) +@LCL // local 1 // (L15:201) (resolveSegmentToR13(local, 1):555) +D=M // (L15:202) (resolveSegmentToR13(local, 1):555) +@1 // write 1 to A // (L15:203) (resolveSegmentToR13(local, 1):555) +D=D+A // D = segment+index // (L15:204) (resolveSegmentToR13(local, 1):555) +@R13 // save it to R13 // (L15:205) (resolveSegmentToR13(local, 1):555) +M=D // write @LCL+1 to R13 // (L15:206) (resolveSegmentToR13(local, 1):555) +@SP // pop // (L15:207) (writePop(local, 1):587) +AM=M-1 // (L15:208) (writePop(local, 1):587) +D=M // (L15:209) (writePop(local, 1):587) +@R13 // (L15:210) (writePop(local, 1):587) +A=M // Read @R13 to A (for local 1) // (L15:211) (writePop(local, 1):587) +M=D // end pop local 1 // (L15:212) (writePop(local, 1):587) +@40 // push constant 40 // (L16:213) (writePush(constant, 40):479) +D=A // (L16:214) (writePush(constant, 40):479) +@SP // (L16:215) (writeDtoSPAndBump():62) +A=M // (L16:216) (writeDtoSPAndBump():62) +M=D // (L16:217) (writeDtoSPAndBump():62) +@SP // (L16:218) (increaseSP():72) +M=M+1 // (L16:219) (increaseSP():72) +@LCL // local 2 // (L17:220) (resolveSegmentToR13(local, 2):555) +D=M // (L17:221) (resolveSegmentToR13(local, 2):555) +@2 // write 2 to A // (L17:222) (resolveSegmentToR13(local, 2):555) +D=D+A // D = segment+index // (L17:223) (resolveSegmentToR13(local, 2):555) +@R13 // save it to R13 // (L17:224) (resolveSegmentToR13(local, 2):555) +M=D // write @LCL+2 to R13 // (L17:225) (resolveSegmentToR13(local, 2):555) +@SP // pop // (L17:226) (writePop(local, 2):587) +AM=M-1 // (L17:227) (writePop(local, 2):587) +D=M // (L17:228) (writePop(local, 2):587) +@R13 // (L17:229) (writePop(local, 2):587) +A=M // Read @R13 to A (for local 2) // (L17:230) (writePop(local, 2):587) +M=D // end pop local 2 // (L17:231) (writePop(local, 2):587) +@6 // push constant 6 // (L18:232) (writePush(constant, 6):479) +D=A // (L18:233) (writePush(constant, 6):479) +@SP // (L18:234) (writeDtoSPAndBump():62) +A=M // (L18:235) (writeDtoSPAndBump():62) +M=D // (L18:236) (writeDtoSPAndBump():62) +@SP // (L18:237) (increaseSP():72) +M=M+1 // (L18:238) (increaseSP():72) +@LCL // local 3 // (L19:239) (resolveSegmentToR13(local, 3):555) +D=M // (L19:240) (resolveSegmentToR13(local, 3):555) +@3 // write 3 to A // (L19:241) (resolveSegmentToR13(local, 3):555) +D=D+A // D = segment+index // (L19:242) (resolveSegmentToR13(local, 3):555) +@R13 // save it to R13 // (L19:243) (resolveSegmentToR13(local, 3):555) +M=D // write @LCL+3 to R13 // (L19:244) (resolveSegmentToR13(local, 3):555) +@SP // pop // (L19:245) (writePop(local, 3):587) +AM=M-1 // (L19:246) (writePop(local, 3):587) +D=M // (L19:247) (writePop(local, 3):587) +@R13 // (L19:248) (writePop(local, 3):587) +A=M // Read @R13 to A (for local 3) // (L19:249) (writePop(local, 3):587) +M=D // end pop local 3 // (L19:250) (writePop(local, 3):587) +@123 // push constant 123 // (L20:251) (writePush(constant, 123):479) +D=A // (L20:252) (writePush(constant, 123):479) +@SP // (L20:253) (writeDtoSPAndBump():62) +A=M // (L20:254) (writeDtoSPAndBump():62) +M=D // (L20:255) (writeDtoSPAndBump():62) +@SP // (L20:256) (increaseSP():72) +M=M+1 // (L20:257) (increaseSP():72) +@60517bb2dffc36cf816c79655b05da50 // (L21:258) (push(label, 60517bb2dffc36cf816c79655b05da50):53) +D=A // (L21:259) (push(label, 60517bb2dffc36cf816c79655b05da50):53) +@SP // (L21:260) (writeDtoSPAndBump():62) +A=M // (L21:261) (writeDtoSPAndBump():62) +M=D // (L21:262) (writeDtoSPAndBump():62) +@SP // (L21:263) (increaseSP():72) +M=M+1 // (L21:264) (increaseSP():72) +@LCL // (L21:265) (push(register, LCL, 1):42) +AD=M // (L21:266) (push(register, LCL, 1):42) +@SP // (L21:267) (writeDtoSPAndBump():62) +A=M // (L21:268) (writeDtoSPAndBump():62) +M=D // (L21:269) (writeDtoSPAndBump():62) +@SP // (L21:270) (increaseSP():72) +M=M+1 // (L21:271) (increaseSP():72) +@ARG // (L21:272) (push(register, ARG, 1):42) +AD=M // (L21:273) (push(register, ARG, 1):42) +@SP // (L21:274) (writeDtoSPAndBump():62) +A=M // (L21:275) (writeDtoSPAndBump():62) +M=D // (L21:276) (writeDtoSPAndBump():62) +@SP // (L21:277) (increaseSP():72) +M=M+1 // (L21:278) (increaseSP():72) +@THIS // (L21:279) (push(register, THIS, 1):42) +AD=M // (L21:280) (push(register, THIS, 1):42) +@SP // (L21:281) (writeDtoSPAndBump():62) +A=M // (L21:282) (writeDtoSPAndBump():62) +M=D // (L21:283) (writeDtoSPAndBump():62) +@SP // (L21:284) (increaseSP():72) +M=M+1 // (L21:285) (increaseSP():72) +@THAT // (L21:286) (push(register, THAT, 1):42) +AD=M // (L21:287) (push(register, THAT, 1):42) +@SP // (L21:288) (writeDtoSPAndBump():62) +A=M // (L21:289) (writeDtoSPAndBump():62) +M=D // (L21:290) (writeDtoSPAndBump():62) +@SP // (L21:291) (increaseSP():72) +M=M+1 // (L21:292) (increaseSP():72) +@SP // (L21:293) (copy(SP, LCL):186) +D=M // (L21:294) (copy(SP, LCL):186) +@LCL // (L21:295) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L21:296) (copy(SP, LCL):186) +@SP // (L21:297) (loadOffsetToD(SP, 6, -):193) +D=M // (L21:298) (loadOffsetToD(SP, 6, -):193) +D=D-1 // should repeat 6 times // (L21:299) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L21:300) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L21:301) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L21:302) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L21:303) (loadOffsetToD(SP, 6, -):198) +D=D-1 // should repeat 6 times // (L21:304) (loadOffsetToD(SP, 6, -):198) +@ARG // write SP-$offset to ARG // (L21:305) (writeCall(Sys.add12, 1):230) +M=D // (L21:306) (writeCall(Sys.add12, 1):230) +@Sys.add12 // Jump to Sys.add12 // (L21:307) (writeCall(Sys.add12, 1):230) +0;JMP // (L21:308) (writeCall(Sys.add12, 1):230) +(60517bb2dffc36cf816c79655b05da50) // return back from function here (CALL ENDS) // (L21:309) (writeCall(Sys.add12, 1):230) +@SP // (L22:309) (writePop(temp, 0):621) +AM=M-1 // (L22:310) (writePop(temp, 0):621) +D=M // (L22:311) (writePop(temp, 0):621) +@R5 // (L22:312) (writePop(temp, 0):621) +M=D // end pop temp 0 // (L22:313) (writePop(temp, 0):621) +@LCL // (L23:314) (writePush(local, 0):494) +A=M // (L23:315) (writePush(local, 0):494) +D=M // (L23:316) (writePush(local, 0):494) +@SP // (L23:317) (writeDtoSPAndBump():62) +A=M // (L23:318) (writeDtoSPAndBump():62) +M=D // (L23:319) (writeDtoSPAndBump():62) +@SP // (L23:320) (increaseSP():72) +M=M+1 // (L23:321) (increaseSP():72) +@LCL // local 1 // (L24:322) (resolveSegmentToR13(local, 1):555) +D=M // (L24:323) (resolveSegmentToR13(local, 1):555) +@1 // write 1 to A // (L24:324) (resolveSegmentToR13(local, 1):555) +D=D+A // D = segment+index // (L24:325) (resolveSegmentToR13(local, 1):555) +@R13 // save it to R13 // (L24:326) (resolveSegmentToR13(local, 1):555) +M=D // write @LCL+1 to R13 // (L24:327) (resolveSegmentToR13(local, 1):555) +@R13 // (L24:328) (writePush(local, 1):494) +A=M // (L24:329) (writePush(local, 1):494) +D=M // (L24:330) (writePush(local, 1):494) +@SP // (L24:331) (writeDtoSPAndBump():62) +A=M // (L24:332) (writeDtoSPAndBump():62) +M=D // (L24:333) (writeDtoSPAndBump():62) +@SP // (L24:334) (increaseSP():72) +M=M+1 // (L24:335) (increaseSP():72) +@LCL // local 2 // (L25:336) (resolveSegmentToR13(local, 2):555) +D=M // (L25:337) (resolveSegmentToR13(local, 2):555) +@2 // write 2 to A // (L25:338) (resolveSegmentToR13(local, 2):555) +D=D+A // D = segment+index // (L25:339) (resolveSegmentToR13(local, 2):555) +@R13 // save it to R13 // (L25:340) (resolveSegmentToR13(local, 2):555) +M=D // write @LCL+2 to R13 // (L25:341) (resolveSegmentToR13(local, 2):555) +@R13 // (L25:342) (writePush(local, 2):494) +A=M // (L25:343) (writePush(local, 2):494) +D=M // (L25:344) (writePush(local, 2):494) +@SP // (L25:345) (writeDtoSPAndBump():62) +A=M // (L25:346) (writeDtoSPAndBump():62) +M=D // (L25:347) (writeDtoSPAndBump():62) +@SP // (L25:348) (increaseSP():72) +M=M+1 // (L25:349) (increaseSP():72) +@LCL // local 3 // (L26:350) (resolveSegmentToR13(local, 3):555) +D=M // (L26:351) (resolveSegmentToR13(local, 3):555) +@3 // write 3 to A // (L26:352) (resolveSegmentToR13(local, 3):555) +D=D+A // D = segment+index // (L26:353) (resolveSegmentToR13(local, 3):555) +@R13 // save it to R13 // (L26:354) (resolveSegmentToR13(local, 3):555) +M=D // write @LCL+3 to R13 // (L26:355) (resolveSegmentToR13(local, 3):555) +@R13 // (L26:356) (writePush(local, 3):494) +A=M // (L26:357) (writePush(local, 3):494) +D=M // (L26:358) (writePush(local, 3):494) +@SP // (L26:359) (writeDtoSPAndBump():62) +A=M // (L26:360) (writeDtoSPAndBump():62) +M=D // (L26:361) (writeDtoSPAndBump():62) +@SP // (L26:362) (increaseSP():72) +M=M+1 // (L26:363) (increaseSP():72) +@LCL // local 4 // (L27:364) (resolveSegmentToR13(local, 4):555) +D=M // (L27:365) (resolveSegmentToR13(local, 4):555) +@4 // write 4 to A // (L27:366) (resolveSegmentToR13(local, 4):555) +D=D+A // D = segment+index // (L27:367) (resolveSegmentToR13(local, 4):555) +@R13 // save it to R13 // (L27:368) (resolveSegmentToR13(local, 4):555) +M=D // write @LCL+4 to R13 // (L27:369) (resolveSegmentToR13(local, 4):555) +@R13 // (L27:370) (writePush(local, 4):494) +A=M // (L27:371) (writePush(local, 4):494) +D=M // (L27:372) (writePush(local, 4):494) +@SP // (L27:373) (writeDtoSPAndBump():62) +A=M // (L27:374) (writeDtoSPAndBump():62) +M=D // (L27:375) (writeDtoSPAndBump():62) +@SP // (L27:376) (increaseSP():72) +M=M+1 // (L27:377) (increaseSP():72) +@SP // ==== add ==== // (L28:378) (writeArithmetic(add):408) +A=M-1 // (L28:379) (writeArithmetic(add):408) +D=M // (L28:380) (writeArithmetic(add):408) +A=A-1 // (L28:381) (binaryMath(add):362) +M=D+M // (L28:382) (binaryMath(add):362) +@SP // (L28:383) (writeArithmetic(add):441) +M=M-1 // end add // (L28:384) (writeArithmetic(add):441) +@SP // ==== add ==== // (L29:385) (writeArithmetic(add):408) +A=M-1 // (L29:386) (writeArithmetic(add):408) +D=M // (L29:387) (writeArithmetic(add):408) +A=A-1 // (L29:388) (binaryMath(add):362) +M=D+M // (L29:389) (binaryMath(add):362) +@SP // (L29:390) (writeArithmetic(add):441) +M=M-1 // end add // (L29:391) (writeArithmetic(add):441) +@SP // ==== add ==== // (L30:392) (writeArithmetic(add):408) +A=M-1 // (L30:393) (writeArithmetic(add):408) +D=M // (L30:394) (writeArithmetic(add):408) +A=A-1 // (L30:395) (binaryMath(add):362) +M=D+M // (L30:396) (binaryMath(add):362) +@SP // (L30:397) (writeArithmetic(add):441) +M=M-1 // end add // (L30:398) (writeArithmetic(add):441) +@SP // ==== add ==== // (L31:399) (writeArithmetic(add):408) +A=M-1 // (L31:400) (writeArithmetic(add):408) +D=M // (L31:401) (writeArithmetic(add):408) +A=A-1 // (L31:402) (binaryMath(add):362) +M=D+M // (L31:403) (binaryMath(add):362) +@SP // (L31:404) (writeArithmetic(add):441) +M=M-1 // end add // (L31:405) (writeArithmetic(add):441) +@LCL // save return address first // (L32:406) (writeReturn():143) +A=M-1 // (L32:407) (writeReturn():143) +A=A-1 // (L32:408) (writeReturn():143) +A=A-1 // (L32:409) (writeReturn():143) +A=A-1 // (L32:410) (writeReturn():143) +A=A-1 // (L32:411) (writeReturn():143) +D=M // D now holds the return address // (L32:412) (writeReturn():143) +@R14 // (L32:413) (writeReturn():143) +M=D // Wrote the return address to R14 // (L32:414) (writeReturn():143) +@SP // return for Sys.main starts // (L32:415) (writeReturn():143) +A=M-1 // (L32:416) (writeReturn():143) +D=M // (L32:417) (writeReturn():143) +@ARG // (L32:418) (writeReturn():143) +A=M // (L32:419) (writeReturn():143) +M=D // (L32:420) (writeReturn():143) +@ARG // (L32:421) (writeReturn():143) +D=M+1 // (L32:422) (writeReturn():143) +@SP // (L32:423) (writeReturn():143) +M=D // @SP = ARG+1 // (L32:424) (writeReturn():143) +@LCL // (L32:425) (writeReturn():143) +D=M // (L32:426) (writeReturn():143) +@R13 // (L32:427) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L32:428) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L32:429) (writeReturn():143) +D=M // D=*(*LCL-1) // (L32:430) (writeReturn():143) +@THAT // A=THAT // (L32:431) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L32:432) (writeReturn():143) +@R13 // (L32:433) (writeReturn():143) +A=M-1 // (L32:434) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L32:435) (writeReturn():143) +D=M // D=*(*LCL-2) // (L32:436) (writeReturn():143) +@THIS // A=THIS // (L32:437) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L32:438) (writeReturn():143) +@R13 // (L32:439) (writeReturn():143) +A=M-1 // (L32:440) (writeReturn():143) +A=A-1 // (L32:441) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L32:442) (writeReturn():143) +D=M // D=*(*LCL-3) // (L32:443) (writeReturn():143) +@ARG // A=ARG // (L32:444) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L32:445) (writeReturn():143) +@R13 // (L32:446) (writeReturn():143) +A=M-1 // (L32:447) (writeReturn():143) +A=A-1 // (L32:448) (writeReturn():143) +A=A-1 // (L32:449) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L32:450) (writeReturn():143) +D=M // D=*(*LCL-4) // (L32:451) (writeReturn():143) +@LCL // A=LCL // (L32:452) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L32:453) (writeReturn():143) +@R14 // (L32:454) (writeReturn():143) +A=M // (L32:455) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L32:456) (writeReturn():143) +(Sys.add12) // function Sys.add12 0 // (L33:457) (writeFunction(Sys.add12, 0):156) +@4002 // push constant 4002 // (L34:457) (writePush(constant, 4002):479) +D=A // (L34:458) (writePush(constant, 4002):479) +@SP // (L34:459) (writeDtoSPAndBump():62) +A=M // (L34:460) (writeDtoSPAndBump():62) +M=D // (L34:461) (writeDtoSPAndBump():62) +@SP // (L34:462) (increaseSP():72) +M=M+1 // (L34:463) (increaseSP():72) +@SP // pop // (L35:464) (writePop(pointer, 0):610) +AM=M-1 // (L35:465) (writePop(pointer, 0):610) +D=M // (L35:466) (writePop(pointer, 0):610) +@THIS // (L35:467) (writePop(pointer, 0):610) +M=D // // (L35:468) (writePop(pointer, 0):610) +@5002 // push constant 5002 // (L36:469) (writePush(constant, 5002):479) +D=A // (L36:470) (writePush(constant, 5002):479) +@SP // (L36:471) (writeDtoSPAndBump():62) +A=M // (L36:472) (writeDtoSPAndBump():62) +M=D // (L36:473) (writeDtoSPAndBump():62) +@SP // (L36:474) (increaseSP():72) +M=M+1 // (L36:475) (increaseSP():72) +@SP // pop // (L37:476) (writePop(pointer, 1):610) +AM=M-1 // (L37:477) (writePop(pointer, 1):610) +D=M // (L37:478) (writePop(pointer, 1):610) +@THAT // (L37:479) (writePop(pointer, 1):610) +M=D // // (L37:480) (writePop(pointer, 1):610) +@ARG // (L38:481) (writePush(argument, 0):494) +A=M // (L38:482) (writePush(argument, 0):494) +D=M // (L38:483) (writePush(argument, 0):494) +@SP // (L38:484) (writeDtoSPAndBump():62) +A=M // (L38:485) (writeDtoSPAndBump():62) +M=D // (L38:486) (writeDtoSPAndBump():62) +@SP // (L38:487) (increaseSP():72) +M=M+1 // (L38:488) (increaseSP():72) +@12 // push constant 12 // (L39:489) (writePush(constant, 12):479) +D=A // (L39:490) (writePush(constant, 12):479) +@SP // (L39:491) (writeDtoSPAndBump():62) +A=M // (L39:492) (writeDtoSPAndBump():62) +M=D // (L39:493) (writeDtoSPAndBump():62) +@SP // (L39:494) (increaseSP():72) +M=M+1 // (L39:495) (increaseSP():72) +@SP // ==== add ==== // (L40:496) (writeArithmetic(add):408) +A=M-1 // (L40:497) (writeArithmetic(add):408) +D=M // (L40:498) (writeArithmetic(add):408) +A=A-1 // (L40:499) (binaryMath(add):362) +M=D+M // (L40:500) (binaryMath(add):362) +@SP // (L40:501) (writeArithmetic(add):441) +M=M-1 // end add // (L40:502) (writeArithmetic(add):441) +@LCL // save return address first // (L41:503) (writeReturn():143) +A=M-1 // (L41:504) (writeReturn():143) +A=A-1 // (L41:505) (writeReturn():143) +A=A-1 // (L41:506) (writeReturn():143) +A=A-1 // (L41:507) (writeReturn():143) +A=A-1 // (L41:508) (writeReturn():143) +D=M // D now holds the return address // (L41:509) (writeReturn():143) +@R14 // (L41:510) (writeReturn():143) +M=D // Wrote the return address to R14 // (L41:511) (writeReturn():143) +@SP // return for Sys.add12 starts // (L41:512) (writeReturn():143) +A=M-1 // (L41:513) (writeReturn():143) +D=M // (L41:514) (writeReturn():143) +@ARG // (L41:515) (writeReturn():143) +A=M // (L41:516) (writeReturn():143) +M=D // (L41:517) (writeReturn():143) +@ARG // (L41:518) (writeReturn():143) +D=M+1 // (L41:519) (writeReturn():143) +@SP // (L41:520) (writeReturn():143) +M=D // @SP = ARG+1 // (L41:521) (writeReturn():143) +@LCL // (L41:522) (writeReturn():143) +D=M // (L41:523) (writeReturn():143) +@R13 // (L41:524) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L41:525) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L41:526) (writeReturn():143) +D=M // D=*(*LCL-1) // (L41:527) (writeReturn():143) +@THAT // A=THAT // (L41:528) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L41:529) (writeReturn():143) +@R13 // (L41:530) (writeReturn():143) +A=M-1 // (L41:531) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L41:532) (writeReturn():143) +D=M // D=*(*LCL-2) // (L41:533) (writeReturn():143) +@THIS // A=THIS // (L41:534) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L41:535) (writeReturn():143) +@R13 // (L41:536) (writeReturn():143) +A=M-1 // (L41:537) (writeReturn():143) +A=A-1 // (L41:538) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L41:539) (writeReturn():143) +D=M // D=*(*LCL-3) // (L41:540) (writeReturn():143) +@ARG // A=ARG // (L41:541) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L41:542) (writeReturn():143) +@R13 // (L41:543) (writeReturn():143) +A=M-1 // (L41:544) (writeReturn():143) +A=A-1 // (L41:545) (writeReturn():143) +A=A-1 // (L41:546) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L41:547) (writeReturn():143) +D=M // D=*(*LCL-4) // (L41:548) (writeReturn():143) +@LCL // A=LCL // (L41:549) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L41:550) (writeReturn():143) +@R14 // (L41:551) (writeReturn():143) +A=M // (L41:552) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L41:553) (writeReturn():143) +@555 // (L42:554) (close():298) +0;JMP // (L42:555) (close():298) diff --git a/projects/08/FunctionCalls/NestedCall/NestedCall.out b/projects/08/FunctionCalls/NestedCall/NestedCall.out new file mode 100644 index 0000000..978405d --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCall.out @@ -0,0 +1,2 @@ +| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] | RAM[5] | RAM[6] | +| 261 | 261 | 256 | 4000 | 5000 | 135 | 246 | diff --git a/projects/08/FunctionCalls/NestedCall/Sys.vm b/projects/08/FunctionCalls/NestedCall/Sys.vm index 646b6d3..cb91fa2 100644 --- a/projects/08/FunctionCalls/NestedCall/Sys.vm +++ b/projects/08/FunctionCalls/NestedCall/Sys.vm @@ -5,15 +5,15 @@ // Calls Sys.main() and stores return value in temp 1. // Does not return. (Enters infinite loop.) -function Sys.init 0 +function Sys.init 0 // L1 push constant 4000 // test THIS and THAT context save -pop pointer 0 +pop pointer 0 // L3 push constant 5000 -pop pointer 1 +pop pointer 1 // L5 call Sys.main 0 -pop temp 1 +pop temp 1 // L7 label LOOP -goto LOOP +goto LOOP // L9 // Sys.main() // @@ -23,41 +23,41 @@ goto LOOP // Returns local 0 + local 1 + local 2 + local 3 + local 4 (456) to confirm // that locals were not mangled by function call. -function Sys.main 5 +function Sys.main 5 // L10 push constant 4001 pop pointer 0 -push constant 5001 +push constant 5001 // L13 pop pointer 1 -push constant 200 +push constant 200 // L15 pop local 1 -push constant 40 +push constant 40 // L17 pop local 2 -push constant 6 +push constant 6 // L19 pop local 3 push constant 123 -call Sys.add12 1 +call Sys.add12 1 // L22 pop temp 0 -push local 0 +push local 0 // L24 push local 1 push local 2 -push local 3 +push local 3 // L27 push local 4 add +add // L30 add -add -add -return +add // L32 +return // L33 // Sys.add12(int n) // // Returns n+12. -function Sys.add12 0 +function Sys.add12 0 // L34 push constant 4002 pop pointer 0 -push constant 5002 +push constant 5002 // L37 pop pointer 1 push argument 0 -push constant 12 +push constant 12 // L40 add -return +return // L42 diff --git a/projects/08/FunctionCalls/SimpleFunction/Correct.asm b/projects/08/FunctionCalls/SimpleFunction/Correct.asm new file mode 100644 index 0000000..6850d70 --- /dev/null +++ b/projects/08/FunctionCalls/SimpleFunction/Correct.asm @@ -0,0 +1,132 @@ +(SimpleFunction.test) +@SP +A=M +M=0 +@SP +AM=M+1 +M=0 +@SP +AM=M+1 +@LCL +A=M +D=M +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@1 +D=D+A +@R13 +M=D +@R13 +A=M +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +A=M-1 +D=M +A=A-1 +M=D+M +@SP +M=M-1 +@SP +A=M-1 +D=M +M=!M +@ARG +A=M +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +A=M-1 +D=M +A=A-1 +M=D+M +@SP +M=M-1 +@ARG +D=M +@1 +D=D+A +@R13 +M=D +@R13 +A=M +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +A=M-1 +D=M +A=A-1 +M=M-D +@SP +M=M-1 +@SP +A=M-1 +D=M +@ARG +A=M +M=D +@ARG +D=M+1 +@SP +M=D +@LCL +D=M +@R13 +M=D +A=D-1 +D=M +@THAT +M=D +@R13 +A=M-1 +A=A-1 +D=M +@THIS +M=D +@R13 +A=M-1 +A=A-1 +A=A-1 +D=M +@ARG +M=D +@R13 +A=M-1 +A=A-1 +A=A-1 +A=A-1 +D=M +@LCL +M=D +@R13 +A=M-1 +A=A-1 +A=A-1 +A=A-1 +A=A-1 +D=M +@R15 +M=D +M=D +@R15 +A=M +0;JMP +@128 +0;JMP diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm index 232a58d..7f67270 100644 --- a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm @@ -1,14 +1,12 @@ (SimpleFunction.test) // function SimpleFunction.test 2 @SP A=M -M=D +M=0 @SP -M=M+1 +AM=M+1 +M=0 @SP -A=M -M=D -@SP -M=M+1 +AM=M+1 @LCL A=M D=M @@ -16,7 +14,7 @@ D=M A=M M=D @SP -M=M+1 // end push local 0 (L1) +M=M+1 @LCL // local 1 D=M @1 // write 1 to A @@ -30,18 +28,18 @@ D=M A=M M=D @SP -M=M+1 // end push local 1 (L2) +M=M+1 @SP // ==== add ==== A=M-1 D=M A=A-1 M=D+M @SP -M=M-1 // end add (L3) +M=M-1 // end add @SP // ==== not ==== A=M-1 D=M -M=!M // end not (L4) +M=!M // end not @ARG A=M D=M @@ -49,14 +47,14 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L5) +M=M+1 @SP // ==== add ==== A=M-1 D=M A=A-1 M=D+M @SP -M=M-1 // end add (L6) +M=M-1 // end add @ARG // argument 1 D=M @1 // write 1 to A @@ -70,15 +68,15 @@ D=M A=M M=D @SP -M=M+1 // end push argument 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) -@SP +M=M-1 // end sub +@SP // return for SimpleFunction.test starts A=M-1 D=M @ARG @@ -91,7 +89,7 @@ M=D // @SP = ARG+1 @LCL D=M @R13 -M=D // Save LCL to R13 +M=D // Save LCL to R13 = FRAME A=D-1 // A=*LCL-1 D=M // D=*(*LCL-1) @THAT // A=THAT @@ -123,7 +121,7 @@ A=A-1 A=A-1 A=A-1 A=A-1 // A=*LCL-5 -A=M // A=*(*LCL-5) -0;JMP // Jump to *(LCL-5) -@128 +A=M // A now holds the return address +0;JMP // HyperJump to *(LCL-5) +@125 0;JMP diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst index a0083bb..8a87888 100644 --- a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst @@ -6,7 +6,7 @@ load SimpleFunction.asm, output-file SimpleFunction.out, compare-to SimpleFunction.cmp, -output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 +output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[310]%D1.6.1; set RAM[0] 317, diff --git a/projects/08/FunctionCalls/StaticsTest/StaticsTest.asm b/projects/08/FunctionCalls/StaticsTest/StaticsTest.asm new file mode 100644 index 0000000..1e6a448 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/StaticsTest.asm @@ -0,0 +1,656 @@ +@256 // (L0:0) (writeConstantToRegister(SP, 256):256) +D=A // (L0:1) (writeConstantToRegister(SP, 256):256) +@SP // (L0:2) (writeConstantToRegister(SP, 256):261) +M=D // initialized SP to 256 // (L0:3) (writeConstantToRegister(SP, 256):261) +@1 // (L0:4) (writeConstantToRegister(LCL, 1):249) +D=-A // (L0:5) (writeConstantToRegister(LCL, 1):249) +@LCL // (L0:6) (writeConstantToRegister(LCL, 1):261) +M=D // initialized LCL to 1 // (L0:7) (writeConstantToRegister(LCL, 1):261) +@2 // (L0:8) (writeConstantToRegister(ARG, 2):249) +D=-A // (L0:9) (writeConstantToRegister(ARG, 2):249) +@ARG // (L0:10) (writeConstantToRegister(ARG, 2):261) +M=D // initialized ARG to 2 // (L0:11) (writeConstantToRegister(ARG, 2):261) +@3 // (L0:12) (writeConstantToRegister(THIS, 3):249) +D=-A // (L0:13) (writeConstantToRegister(THIS, 3):249) +@THIS // (L0:14) (writeConstantToRegister(THIS, 3):261) +M=D // initialized THIS to 3 // (L0:15) (writeConstantToRegister(THIS, 3):261) +@4 // (L0:16) (writeConstantToRegister(THAT, 4):249) +D=-A // (L0:17) (writeConstantToRegister(THAT, 4):249) +@THAT // (L0:18) (writeConstantToRegister(THAT, 4):261) +M=D // initialized THAT to 4 // (L0:19) (writeConstantToRegister(THAT, 4):261) +@33b1f99614b7ceb21fb78d26e579bf9e // (L0:20) (push(label, 33b1f99614b7ceb21fb78d26e579bf9e):53) +D=A // (L0:21) (push(label, 33b1f99614b7ceb21fb78d26e579bf9e):53) +@SP // (L0:22) (writeDtoSPAndBump():62) +A=M // (L0:23) (writeDtoSPAndBump():62) +M=D // (L0:24) (writeDtoSPAndBump():62) +@SP // (L0:25) (increaseSP():72) +M=M+1 // (L0:26) (increaseSP():72) +@LCL // (L0:27) (push(register, LCL, 1):42) +AD=M // (L0:28) (push(register, LCL, 1):42) +@SP // (L0:29) (writeDtoSPAndBump():62) +A=M // (L0:30) (writeDtoSPAndBump():62) +M=D // (L0:31) (writeDtoSPAndBump():62) +@SP // (L0:32) (increaseSP():72) +M=M+1 // (L0:33) (increaseSP():72) +@ARG // (L0:34) (push(register, ARG, 1):42) +AD=M // (L0:35) (push(register, ARG, 1):42) +@SP // (L0:36) (writeDtoSPAndBump():62) +A=M // (L0:37) (writeDtoSPAndBump():62) +M=D // (L0:38) (writeDtoSPAndBump():62) +@SP // (L0:39) (increaseSP():72) +M=M+1 // (L0:40) (increaseSP():72) +@THIS // (L0:41) (push(register, THIS, 1):42) +AD=M // (L0:42) (push(register, THIS, 1):42) +@SP // (L0:43) (writeDtoSPAndBump():62) +A=M // (L0:44) (writeDtoSPAndBump():62) +M=D // (L0:45) (writeDtoSPAndBump():62) +@SP // (L0:46) (increaseSP():72) +M=M+1 // (L0:47) (increaseSP():72) +@THAT // (L0:48) (push(register, THAT, 1):42) +AD=M // (L0:49) (push(register, THAT, 1):42) +@SP // (L0:50) (writeDtoSPAndBump():62) +A=M // (L0:51) (writeDtoSPAndBump():62) +M=D // (L0:52) (writeDtoSPAndBump():62) +@SP // (L0:53) (increaseSP():72) +M=M+1 // (L0:54) (increaseSP():72) +@SP // (L0:55) (copy(SP, LCL):186) +D=M // (L0:56) (copy(SP, LCL):186) +@LCL // (L0:57) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L0:58) (copy(SP, LCL):186) +@SP // (L0:59) (loadOffsetToD(SP, 5, -):193) +D=M // (L0:60) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L0:61) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:62) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:63) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:64) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L0:65) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L0:66) (writeCall(Sys.init, 0):230) +M=D // (L0:67) (writeCall(Sys.init, 0):230) +@Sys.init // Jump to Sys.init // (L0:68) (writeCall(Sys.init, 0):230) +0;JMP // (L0:69) (writeCall(Sys.init, 0):230) +(33b1f99614b7ceb21fb78d26e579bf9e) // return back from function here (CALL ENDS) // (L0:70) (writeCall(Sys.init, 0):230) +(__GLOBAL_TERMINATE__) // (L0:70) (writeCall(Sys.init, 0):237) +@__GLOBAL_TERMINATE__ // (L0:70) (writeCall(Sys.init, 0):237) +0;JMP // (L0:71) (writeCall(Sys.init, 0):237) +(Class1.set) // function Class1.set 0 // (L0:72) (writeFunction(Class1.set, 0):156) +@ARG // (L1:72) (writePush(argument, 0):494) +A=M // (L1:73) (writePush(argument, 0):494) +D=M // (L1:74) (writePush(argument, 0):494) +@SP // (L1:75) (writeDtoSPAndBump():62) +A=M // (L1:76) (writeDtoSPAndBump():62) +M=D // (L1:77) (writeDtoSPAndBump():62) +@SP // (L1:78) (increaseSP():72) +M=M+1 // (L1:79) (increaseSP():72) +@SP //pop static 0 // (L2:80) (writePop(static, 0):598) +AM=M-1 // (L2:81) (writePop(static, 0):598) +D=M // (L2:82) (writePop(static, 0):598) +@Class1.0 // (L2:83) (writePop(static, 0):598) +M=D // end pop static 0 // (L2:84) (writePop(static, 0):598) +@ARG // argument 1 // (L3:85) (resolveSegmentToR13(argument, 1):555) +D=M // (L3:86) (resolveSegmentToR13(argument, 1):555) +@1 // write 1 to A // (L3:87) (resolveSegmentToR13(argument, 1):555) +D=D+A // D = segment+index // (L3:88) (resolveSegmentToR13(argument, 1):555) +@R13 // save it to R13 // (L3:89) (resolveSegmentToR13(argument, 1):555) +M=D // write @ARG+1 to R13 // (L3:90) (resolveSegmentToR13(argument, 1):555) +@R13 // (L3:91) (writePush(argument, 1):494) +A=M // (L3:92) (writePush(argument, 1):494) +D=M // (L3:93) (writePush(argument, 1):494) +@SP // (L3:94) (writeDtoSPAndBump():62) +A=M // (L3:95) (writeDtoSPAndBump():62) +M=D // (L3:96) (writeDtoSPAndBump():62) +@SP // (L3:97) (increaseSP():72) +M=M+1 // (L3:98) (increaseSP():72) +@SP //pop static 1 // (L4:99) (writePop(static, 1):598) +AM=M-1 // (L4:100) (writePop(static, 1):598) +D=M // (L4:101) (writePop(static, 1):598) +@Class1.1 // (L4:102) (writePop(static, 1):598) +M=D // end pop static 1 // (L4:103) (writePop(static, 1):598) +@0 // push constant 0 // (L5:104) (writePush(constant, 0):479) +D=A // (L5:105) (writePush(constant, 0):479) +@SP // (L5:106) (writeDtoSPAndBump():62) +A=M // (L5:107) (writeDtoSPAndBump():62) +M=D // (L5:108) (writeDtoSPAndBump():62) +@SP // (L5:109) (increaseSP():72) +M=M+1 // (L5:110) (increaseSP():72) +@LCL // save return address first // (L6:111) (writeReturn():143) +A=M-1 // (L6:112) (writeReturn():143) +A=A-1 // (L6:113) (writeReturn():143) +A=A-1 // (L6:114) (writeReturn():143) +A=A-1 // (L6:115) (writeReturn():143) +A=A-1 // (L6:116) (writeReturn():143) +D=M // D now holds the return address // (L6:117) (writeReturn():143) +@R14 // (L6:118) (writeReturn():143) +M=D // Wrote the return address to R14 // (L6:119) (writeReturn():143) +@SP // return for Class1.set starts // (L6:120) (writeReturn():143) +A=M-1 // (L6:121) (writeReturn():143) +D=M // (L6:122) (writeReturn():143) +@ARG // (L6:123) (writeReturn():143) +A=M // (L6:124) (writeReturn():143) +M=D // (L6:125) (writeReturn():143) +@ARG // (L6:126) (writeReturn():143) +D=M+1 // (L6:127) (writeReturn():143) +@SP // (L6:128) (writeReturn():143) +M=D // @SP = ARG+1 // (L6:129) (writeReturn():143) +@LCL // (L6:130) (writeReturn():143) +D=M // (L6:131) (writeReturn():143) +@R13 // (L6:132) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L6:133) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L6:134) (writeReturn():143) +D=M // D=*(*LCL-1) // (L6:135) (writeReturn():143) +@THAT // A=THAT // (L6:136) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L6:137) (writeReturn():143) +@R13 // (L6:138) (writeReturn():143) +A=M-1 // (L6:139) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L6:140) (writeReturn():143) +D=M // D=*(*LCL-2) // (L6:141) (writeReturn():143) +@THIS // A=THIS // (L6:142) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L6:143) (writeReturn():143) +@R13 // (L6:144) (writeReturn():143) +A=M-1 // (L6:145) (writeReturn():143) +A=A-1 // (L6:146) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L6:147) (writeReturn():143) +D=M // D=*(*LCL-3) // (L6:148) (writeReturn():143) +@ARG // A=ARG // (L6:149) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L6:150) (writeReturn():143) +@R13 // (L6:151) (writeReturn():143) +A=M-1 // (L6:152) (writeReturn():143) +A=A-1 // (L6:153) (writeReturn():143) +A=A-1 // (L6:154) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L6:155) (writeReturn():143) +D=M // D=*(*LCL-4) // (L6:156) (writeReturn():143) +@LCL // A=LCL // (L6:157) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L6:158) (writeReturn():143) +@R14 // (L6:159) (writeReturn():143) +A=M // (L6:160) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L6:161) (writeReturn():143) +(Class1.get) // function Class1.get 0 // (L7:162) (writeFunction(Class1.get, 0):156) +@Class1.0 // (L8:162) (writePush(static, 0):502) +D=M // (L8:163) (writePush(static, 0):502) +@SP // (L8:164) (writeDtoSPAndBump():62) +A=M // (L8:165) (writeDtoSPAndBump():62) +M=D // (L8:166) (writeDtoSPAndBump():62) +@SP // (L8:167) (increaseSP():72) +M=M+1 // (L8:168) (increaseSP():72) +@Class1.1 // (L9:169) (writePush(static, 1):502) +D=M // (L9:170) (writePush(static, 1):502) +@SP // (L9:171) (writeDtoSPAndBump():62) +A=M // (L9:172) (writeDtoSPAndBump():62) +M=D // (L9:173) (writeDtoSPAndBump():62) +@SP // (L9:174) (increaseSP():72) +M=M+1 // (L9:175) (increaseSP():72) +@SP // ==== sub ==== // (L10:176) (writeArithmetic(sub):408) +A=M-1 // (L10:177) (writeArithmetic(sub):408) +D=M // (L10:178) (writeArithmetic(sub):408) +A=A-1 // (L10:179) (binaryMath(sub):362) +M=D-M // (L10:180) (binaryMath(sub):362) +M=-M // (L10:181) (binaryMath(sub):367) +@SP // (L10:182) (writeArithmetic(sub):441) +M=M-1 // end sub // (L10:183) (writeArithmetic(sub):441) +@LCL // save return address first // (L11:184) (writeReturn():143) +A=M-1 // (L11:185) (writeReturn():143) +A=A-1 // (L11:186) (writeReturn():143) +A=A-1 // (L11:187) (writeReturn():143) +A=A-1 // (L11:188) (writeReturn():143) +A=A-1 // (L11:189) (writeReturn():143) +D=M // D now holds the return address // (L11:190) (writeReturn():143) +@R14 // (L11:191) (writeReturn():143) +M=D // Wrote the return address to R14 // (L11:192) (writeReturn():143) +@SP // return for Class1.get starts // (L11:193) (writeReturn():143) +A=M-1 // (L11:194) (writeReturn():143) +D=M // (L11:195) (writeReturn():143) +@ARG // (L11:196) (writeReturn():143) +A=M // (L11:197) (writeReturn():143) +M=D // (L11:198) (writeReturn():143) +@ARG // (L11:199) (writeReturn():143) +D=M+1 // (L11:200) (writeReturn():143) +@SP // (L11:201) (writeReturn():143) +M=D // @SP = ARG+1 // (L11:202) (writeReturn():143) +@LCL // (L11:203) (writeReturn():143) +D=M // (L11:204) (writeReturn():143) +@R13 // (L11:205) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L11:206) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L11:207) (writeReturn():143) +D=M // D=*(*LCL-1) // (L11:208) (writeReturn():143) +@THAT // A=THAT // (L11:209) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L11:210) (writeReturn():143) +@R13 // (L11:211) (writeReturn():143) +A=M-1 // (L11:212) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L11:213) (writeReturn():143) +D=M // D=*(*LCL-2) // (L11:214) (writeReturn():143) +@THIS // A=THIS // (L11:215) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L11:216) (writeReturn():143) +@R13 // (L11:217) (writeReturn():143) +A=M-1 // (L11:218) (writeReturn():143) +A=A-1 // (L11:219) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L11:220) (writeReturn():143) +D=M // D=*(*LCL-3) // (L11:221) (writeReturn():143) +@ARG // A=ARG // (L11:222) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L11:223) (writeReturn():143) +@R13 // (L11:224) (writeReturn():143) +A=M-1 // (L11:225) (writeReturn():143) +A=A-1 // (L11:226) (writeReturn():143) +A=A-1 // (L11:227) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L11:228) (writeReturn():143) +D=M // D=*(*LCL-4) // (L11:229) (writeReturn():143) +@LCL // A=LCL // (L11:230) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L11:231) (writeReturn():143) +@R14 // (L11:232) (writeReturn():143) +A=M // (L11:233) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L11:234) (writeReturn():143) +(Class2.set) // function Class2.set 0 // (L12:235) (writeFunction(Class2.set, 0):156) +@ARG // (L13:235) (writePush(argument, 0):494) +A=M // (L13:236) (writePush(argument, 0):494) +D=M // (L13:237) (writePush(argument, 0):494) +@SP // (L13:238) (writeDtoSPAndBump():62) +A=M // (L13:239) (writeDtoSPAndBump():62) +M=D // (L13:240) (writeDtoSPAndBump():62) +@SP // (L13:241) (increaseSP():72) +M=M+1 // (L13:242) (increaseSP():72) +@SP //pop static 0 // (L14:243) (writePop(static, 0):598) +AM=M-1 // (L14:244) (writePop(static, 0):598) +D=M // (L14:245) (writePop(static, 0):598) +@Class2.0 // (L14:246) (writePop(static, 0):598) +M=D // end pop static 0 // (L14:247) (writePop(static, 0):598) +@ARG // argument 1 // (L15:248) (resolveSegmentToR13(argument, 1):555) +D=M // (L15:249) (resolveSegmentToR13(argument, 1):555) +@1 // write 1 to A // (L15:250) (resolveSegmentToR13(argument, 1):555) +D=D+A // D = segment+index // (L15:251) (resolveSegmentToR13(argument, 1):555) +@R13 // save it to R13 // (L15:252) (resolveSegmentToR13(argument, 1):555) +M=D // write @ARG+1 to R13 // (L15:253) (resolveSegmentToR13(argument, 1):555) +@R13 // (L15:254) (writePush(argument, 1):494) +A=M // (L15:255) (writePush(argument, 1):494) +D=M // (L15:256) (writePush(argument, 1):494) +@SP // (L15:257) (writeDtoSPAndBump():62) +A=M // (L15:258) (writeDtoSPAndBump():62) +M=D // (L15:259) (writeDtoSPAndBump():62) +@SP // (L15:260) (increaseSP():72) +M=M+1 // (L15:261) (increaseSP():72) +@SP //pop static 1 // (L16:262) (writePop(static, 1):598) +AM=M-1 // (L16:263) (writePop(static, 1):598) +D=M // (L16:264) (writePop(static, 1):598) +@Class2.1 // (L16:265) (writePop(static, 1):598) +M=D // end pop static 1 // (L16:266) (writePop(static, 1):598) +@0 // push constant 0 // (L17:267) (writePush(constant, 0):479) +D=A // (L17:268) (writePush(constant, 0):479) +@SP // (L17:269) (writeDtoSPAndBump():62) +A=M // (L17:270) (writeDtoSPAndBump():62) +M=D // (L17:271) (writeDtoSPAndBump():62) +@SP // (L17:272) (increaseSP():72) +M=M+1 // (L17:273) (increaseSP():72) +@LCL // save return address first // (L18:274) (writeReturn():143) +A=M-1 // (L18:275) (writeReturn():143) +A=A-1 // (L18:276) (writeReturn():143) +A=A-1 // (L18:277) (writeReturn():143) +A=A-1 // (L18:278) (writeReturn():143) +A=A-1 // (L18:279) (writeReturn():143) +D=M // D now holds the return address // (L18:280) (writeReturn():143) +@R14 // (L18:281) (writeReturn():143) +M=D // Wrote the return address to R14 // (L18:282) (writeReturn():143) +@SP // return for Class2.set starts // (L18:283) (writeReturn():143) +A=M-1 // (L18:284) (writeReturn():143) +D=M // (L18:285) (writeReturn():143) +@ARG // (L18:286) (writeReturn():143) +A=M // (L18:287) (writeReturn():143) +M=D // (L18:288) (writeReturn():143) +@ARG // (L18:289) (writeReturn():143) +D=M+1 // (L18:290) (writeReturn():143) +@SP // (L18:291) (writeReturn():143) +M=D // @SP = ARG+1 // (L18:292) (writeReturn():143) +@LCL // (L18:293) (writeReturn():143) +D=M // (L18:294) (writeReturn():143) +@R13 // (L18:295) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L18:296) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L18:297) (writeReturn():143) +D=M // D=*(*LCL-1) // (L18:298) (writeReturn():143) +@THAT // A=THAT // (L18:299) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L18:300) (writeReturn():143) +@R13 // (L18:301) (writeReturn():143) +A=M-1 // (L18:302) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L18:303) (writeReturn():143) +D=M // D=*(*LCL-2) // (L18:304) (writeReturn():143) +@THIS // A=THIS // (L18:305) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L18:306) (writeReturn():143) +@R13 // (L18:307) (writeReturn():143) +A=M-1 // (L18:308) (writeReturn():143) +A=A-1 // (L18:309) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L18:310) (writeReturn():143) +D=M // D=*(*LCL-3) // (L18:311) (writeReturn():143) +@ARG // A=ARG // (L18:312) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L18:313) (writeReturn():143) +@R13 // (L18:314) (writeReturn():143) +A=M-1 // (L18:315) (writeReturn():143) +A=A-1 // (L18:316) (writeReturn():143) +A=A-1 // (L18:317) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L18:318) (writeReturn():143) +D=M // D=*(*LCL-4) // (L18:319) (writeReturn():143) +@LCL // A=LCL // (L18:320) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L18:321) (writeReturn():143) +@R14 // (L18:322) (writeReturn():143) +A=M // (L18:323) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L18:324) (writeReturn():143) +(Class2.get) // function Class2.get 0 // (L19:325) (writeFunction(Class2.get, 0):156) +@Class2.0 // (L20:325) (writePush(static, 0):502) +D=M // (L20:326) (writePush(static, 0):502) +@SP // (L20:327) (writeDtoSPAndBump():62) +A=M // (L20:328) (writeDtoSPAndBump():62) +M=D // (L20:329) (writeDtoSPAndBump():62) +@SP // (L20:330) (increaseSP():72) +M=M+1 // (L20:331) (increaseSP():72) +@Class2.1 // (L21:332) (writePush(static, 1):502) +D=M // (L21:333) (writePush(static, 1):502) +@SP // (L21:334) (writeDtoSPAndBump():62) +A=M // (L21:335) (writeDtoSPAndBump():62) +M=D // (L21:336) (writeDtoSPAndBump():62) +@SP // (L21:337) (increaseSP():72) +M=M+1 // (L21:338) (increaseSP():72) +@SP // ==== sub ==== // (L22:339) (writeArithmetic(sub):408) +A=M-1 // (L22:340) (writeArithmetic(sub):408) +D=M // (L22:341) (writeArithmetic(sub):408) +A=A-1 // (L22:342) (binaryMath(sub):362) +M=D-M // (L22:343) (binaryMath(sub):362) +M=-M // (L22:344) (binaryMath(sub):367) +@SP // (L22:345) (writeArithmetic(sub):441) +M=M-1 // end sub // (L22:346) (writeArithmetic(sub):441) +@LCL // save return address first // (L23:347) (writeReturn():143) +A=M-1 // (L23:348) (writeReturn():143) +A=A-1 // (L23:349) (writeReturn():143) +A=A-1 // (L23:350) (writeReturn():143) +A=A-1 // (L23:351) (writeReturn():143) +A=A-1 // (L23:352) (writeReturn():143) +D=M // D now holds the return address // (L23:353) (writeReturn():143) +@R14 // (L23:354) (writeReturn():143) +M=D // Wrote the return address to R14 // (L23:355) (writeReturn():143) +@SP // return for Class2.get starts // (L23:356) (writeReturn():143) +A=M-1 // (L23:357) (writeReturn():143) +D=M // (L23:358) (writeReturn():143) +@ARG // (L23:359) (writeReturn():143) +A=M // (L23:360) (writeReturn():143) +M=D // (L23:361) (writeReturn():143) +@ARG // (L23:362) (writeReturn():143) +D=M+1 // (L23:363) (writeReturn():143) +@SP // (L23:364) (writeReturn():143) +M=D // @SP = ARG+1 // (L23:365) (writeReturn():143) +@LCL // (L23:366) (writeReturn():143) +D=M // (L23:367) (writeReturn():143) +@R13 // (L23:368) (writeReturn():143) +M=D // Save LCL to R13 = FRAME // (L23:369) (writeReturn():143) +A=D-1 // A=*LCL-1 // (L23:370) (writeReturn():143) +D=M // D=*(*LCL-1) // (L23:371) (writeReturn():143) +@THAT // A=THAT // (L23:372) (writeReturn():143) +M=D // *that = *(*lcl-1) // (L23:373) (writeReturn():143) +@R13 // (L23:374) (writeReturn():143) +A=M-1 // (L23:375) (writeReturn():143) +A=A-1 // A=*LCL-2 // (L23:376) (writeReturn():143) +D=M // D=*(*LCL-2) // (L23:377) (writeReturn():143) +@THIS // A=THIS // (L23:378) (writeReturn():143) +M=D // *THIS = *(*lcl-2) // (L23:379) (writeReturn():143) +@R13 // (L23:380) (writeReturn():143) +A=M-1 // (L23:381) (writeReturn():143) +A=A-1 // (L23:382) (writeReturn():143) +A=A-1 // A=*LCL-3 // (L23:383) (writeReturn():143) +D=M // D=*(*LCL-3) // (L23:384) (writeReturn():143) +@ARG // A=ARG // (L23:385) (writeReturn():143) +M=D // *ARG = *(*lcl-3) // (L23:386) (writeReturn():143) +@R13 // (L23:387) (writeReturn():143) +A=M-1 // (L23:388) (writeReturn():143) +A=A-1 // (L23:389) (writeReturn():143) +A=A-1 // (L23:390) (writeReturn():143) +A=A-1 // A=*LCL-4 // (L23:391) (writeReturn():143) +D=M // D=*(*LCL-4) // (L23:392) (writeReturn():143) +@LCL // A=LCL // (L23:393) (writeReturn():143) +M=D // *LCL = *(*lcl-4) // (L23:394) (writeReturn():143) +@R14 // (L23:395) (writeReturn():143) +A=M // (L23:396) (writeReturn():143) +0;JMP // HyperJump to *(LCL-5) // (L23:397) (writeReturn():143) +(Sys.init) // function Sys.init 0 // (L24:398) (writeFunction(Sys.init, 0):156) +@6 // push constant 6 // (L25:398) (writePush(constant, 6):479) +D=A // (L25:399) (writePush(constant, 6):479) +@SP // (L25:400) (writeDtoSPAndBump():62) +A=M // (L25:401) (writeDtoSPAndBump():62) +M=D // (L25:402) (writeDtoSPAndBump():62) +@SP // (L25:403) (increaseSP():72) +M=M+1 // (L25:404) (increaseSP():72) +@8 // push constant 8 // (L26:405) (writePush(constant, 8):479) +D=A // (L26:406) (writePush(constant, 8):479) +@SP // (L26:407) (writeDtoSPAndBump():62) +A=M // (L26:408) (writeDtoSPAndBump():62) +M=D // (L26:409) (writeDtoSPAndBump():62) +@SP // (L26:410) (increaseSP():72) +M=M+1 // (L26:411) (increaseSP():72) +@aea8a00a813b467f414d81e6983352f4 // (L27:412) (push(label, aea8a00a813b467f414d81e6983352f4):53) +D=A // (L27:413) (push(label, aea8a00a813b467f414d81e6983352f4):53) +@SP // (L27:414) (writeDtoSPAndBump():62) +A=M // (L27:415) (writeDtoSPAndBump():62) +M=D // (L27:416) (writeDtoSPAndBump():62) +@SP // (L27:417) (increaseSP():72) +M=M+1 // (L27:418) (increaseSP():72) +@LCL // (L27:419) (push(register, LCL, 1):42) +AD=M // (L27:420) (push(register, LCL, 1):42) +@SP // (L27:421) (writeDtoSPAndBump():62) +A=M // (L27:422) (writeDtoSPAndBump():62) +M=D // (L27:423) (writeDtoSPAndBump():62) +@SP // (L27:424) (increaseSP():72) +M=M+1 // (L27:425) (increaseSP():72) +@ARG // (L27:426) (push(register, ARG, 1):42) +AD=M // (L27:427) (push(register, ARG, 1):42) +@SP // (L27:428) (writeDtoSPAndBump():62) +A=M // (L27:429) (writeDtoSPAndBump():62) +M=D // (L27:430) (writeDtoSPAndBump():62) +@SP // (L27:431) (increaseSP():72) +M=M+1 // (L27:432) (increaseSP():72) +@THIS // (L27:433) (push(register, THIS, 1):42) +AD=M // (L27:434) (push(register, THIS, 1):42) +@SP // (L27:435) (writeDtoSPAndBump():62) +A=M // (L27:436) (writeDtoSPAndBump():62) +M=D // (L27:437) (writeDtoSPAndBump():62) +@SP // (L27:438) (increaseSP():72) +M=M+1 // (L27:439) (increaseSP():72) +@THAT // (L27:440) (push(register, THAT, 1):42) +AD=M // (L27:441) (push(register, THAT, 1):42) +@SP // (L27:442) (writeDtoSPAndBump():62) +A=M // (L27:443) (writeDtoSPAndBump():62) +M=D // (L27:444) (writeDtoSPAndBump():62) +@SP // (L27:445) (increaseSP():72) +M=M+1 // (L27:446) (increaseSP():72) +@SP // (L27:447) (copy(SP, LCL):186) +D=M // (L27:448) (copy(SP, LCL):186) +@LCL // (L27:449) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L27:450) (copy(SP, LCL):186) +@SP // (L27:451) (loadOffsetToD(SP, 7, -):193) +D=M // (L27:452) (loadOffsetToD(SP, 7, -):193) +D=D-1 // should repeat 7 times // (L27:453) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:454) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:455) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:456) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:457) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:458) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L27:459) (loadOffsetToD(SP, 7, -):198) +@ARG // write SP-$offset to ARG // (L27:460) (writeCall(Class1.set, 2):230) +M=D // (L27:461) (writeCall(Class1.set, 2):230) +@Class1.set // Jump to Class1.set // (L27:462) (writeCall(Class1.set, 2):230) +0;JMP // (L27:463) (writeCall(Class1.set, 2):230) +(aea8a00a813b467f414d81e6983352f4) // return back from function here (CALL ENDS) // (L27:464) (writeCall(Class1.set, 2):230) +@SP // (L28:464) (writePop(temp, 0):621) +AM=M-1 // (L28:465) (writePop(temp, 0):621) +D=M // (L28:466) (writePop(temp, 0):621) +@R5 // (L28:467) (writePop(temp, 0):621) +M=D // end pop temp 0 // (L28:468) (writePop(temp, 0):621) +@23 // push constant 23 // (L29:469) (writePush(constant, 23):479) +D=A // (L29:470) (writePush(constant, 23):479) +@SP // (L29:471) (writeDtoSPAndBump():62) +A=M // (L29:472) (writeDtoSPAndBump():62) +M=D // (L29:473) (writeDtoSPAndBump():62) +@SP // (L29:474) (increaseSP():72) +M=M+1 // (L29:475) (increaseSP():72) +@15 // push constant 15 // (L30:476) (writePush(constant, 15):479) +D=A // (L30:477) (writePush(constant, 15):479) +@SP // (L30:478) (writeDtoSPAndBump():62) +A=M // (L30:479) (writeDtoSPAndBump():62) +M=D // (L30:480) (writeDtoSPAndBump():62) +@SP // (L30:481) (increaseSP():72) +M=M+1 // (L30:482) (increaseSP():72) +@0ac0a58c342d73fd63518ed52cbebcca // (L31:483) (push(label, 0ac0a58c342d73fd63518ed52cbebcca):53) +D=A // (L31:484) (push(label, 0ac0a58c342d73fd63518ed52cbebcca):53) +@SP // (L31:485) (writeDtoSPAndBump():62) +A=M // (L31:486) (writeDtoSPAndBump():62) +M=D // (L31:487) (writeDtoSPAndBump():62) +@SP // (L31:488) (increaseSP():72) +M=M+1 // (L31:489) (increaseSP():72) +@LCL // (L31:490) (push(register, LCL, 1):42) +AD=M // (L31:491) (push(register, LCL, 1):42) +@SP // (L31:492) (writeDtoSPAndBump():62) +A=M // (L31:493) (writeDtoSPAndBump():62) +M=D // (L31:494) (writeDtoSPAndBump():62) +@SP // (L31:495) (increaseSP():72) +M=M+1 // (L31:496) (increaseSP():72) +@ARG // (L31:497) (push(register, ARG, 1):42) +AD=M // (L31:498) (push(register, ARG, 1):42) +@SP // (L31:499) (writeDtoSPAndBump():62) +A=M // (L31:500) (writeDtoSPAndBump():62) +M=D // (L31:501) (writeDtoSPAndBump():62) +@SP // (L31:502) (increaseSP():72) +M=M+1 // (L31:503) (increaseSP():72) +@THIS // (L31:504) (push(register, THIS, 1):42) +AD=M // (L31:505) (push(register, THIS, 1):42) +@SP // (L31:506) (writeDtoSPAndBump():62) +A=M // (L31:507) (writeDtoSPAndBump():62) +M=D // (L31:508) (writeDtoSPAndBump():62) +@SP // (L31:509) (increaseSP():72) +M=M+1 // (L31:510) (increaseSP():72) +@THAT // (L31:511) (push(register, THAT, 1):42) +AD=M // (L31:512) (push(register, THAT, 1):42) +@SP // (L31:513) (writeDtoSPAndBump():62) +A=M // (L31:514) (writeDtoSPAndBump():62) +M=D // (L31:515) (writeDtoSPAndBump():62) +@SP // (L31:516) (increaseSP():72) +M=M+1 // (L31:517) (increaseSP():72) +@SP // (L31:518) (copy(SP, LCL):186) +D=M // (L31:519) (copy(SP, LCL):186) +@LCL // (L31:520) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L31:521) (copy(SP, LCL):186) +@SP // (L31:522) (loadOffsetToD(SP, 7, -):193) +D=M // (L31:523) (loadOffsetToD(SP, 7, -):193) +D=D-1 // should repeat 7 times // (L31:524) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:525) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:526) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:527) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:528) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:529) (loadOffsetToD(SP, 7, -):198) +D=D-1 // should repeat 7 times // (L31:530) (loadOffsetToD(SP, 7, -):198) +@ARG // write SP-$offset to ARG // (L31:531) (writeCall(Class2.set, 2):230) +M=D // (L31:532) (writeCall(Class2.set, 2):230) +@Class2.set // Jump to Class2.set // (L31:533) (writeCall(Class2.set, 2):230) +0;JMP // (L31:534) (writeCall(Class2.set, 2):230) +(0ac0a58c342d73fd63518ed52cbebcca) // return back from function here (CALL ENDS) // (L31:535) (writeCall(Class2.set, 2):230) +@SP // (L32:535) (writePop(temp, 0):621) +AM=M-1 // (L32:536) (writePop(temp, 0):621) +D=M // (L32:537) (writePop(temp, 0):621) +@R5 // (L32:538) (writePop(temp, 0):621) +M=D // end pop temp 0 // (L32:539) (writePop(temp, 0):621) +@b1c23d05017207e2f47201f7bf7111d4 // (L33:540) (push(label, b1c23d05017207e2f47201f7bf7111d4):53) +D=A // (L33:541) (push(label, b1c23d05017207e2f47201f7bf7111d4):53) +@SP // (L33:542) (writeDtoSPAndBump():62) +A=M // (L33:543) (writeDtoSPAndBump():62) +M=D // (L33:544) (writeDtoSPAndBump():62) +@SP // (L33:545) (increaseSP():72) +M=M+1 // (L33:546) (increaseSP():72) +@LCL // (L33:547) (push(register, LCL, 1):42) +AD=M // (L33:548) (push(register, LCL, 1):42) +@SP // (L33:549) (writeDtoSPAndBump():62) +A=M // (L33:550) (writeDtoSPAndBump():62) +M=D // (L33:551) (writeDtoSPAndBump():62) +@SP // (L33:552) (increaseSP():72) +M=M+1 // (L33:553) (increaseSP():72) +@ARG // (L33:554) (push(register, ARG, 1):42) +AD=M // (L33:555) (push(register, ARG, 1):42) +@SP // (L33:556) (writeDtoSPAndBump():62) +A=M // (L33:557) (writeDtoSPAndBump():62) +M=D // (L33:558) (writeDtoSPAndBump():62) +@SP // (L33:559) (increaseSP():72) +M=M+1 // (L33:560) (increaseSP():72) +@THIS // (L33:561) (push(register, THIS, 1):42) +AD=M // (L33:562) (push(register, THIS, 1):42) +@SP // (L33:563) (writeDtoSPAndBump():62) +A=M // (L33:564) (writeDtoSPAndBump():62) +M=D // (L33:565) (writeDtoSPAndBump():62) +@SP // (L33:566) (increaseSP():72) +M=M+1 // (L33:567) (increaseSP():72) +@THAT // (L33:568) (push(register, THAT, 1):42) +AD=M // (L33:569) (push(register, THAT, 1):42) +@SP // (L33:570) (writeDtoSPAndBump():62) +A=M // (L33:571) (writeDtoSPAndBump():62) +M=D // (L33:572) (writeDtoSPAndBump():62) +@SP // (L33:573) (increaseSP():72) +M=M+1 // (L33:574) (increaseSP():72) +@SP // (L33:575) (copy(SP, LCL):186) +D=M // (L33:576) (copy(SP, LCL):186) +@LCL // (L33:577) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L33:578) (copy(SP, LCL):186) +@SP // (L33:579) (loadOffsetToD(SP, 5, -):193) +D=M // (L33:580) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L33:581) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L33:582) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L33:583) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L33:584) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L33:585) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L33:586) (writeCall(Class1.get, 0):230) +M=D // (L33:587) (writeCall(Class1.get, 0):230) +@Class1.get // Jump to Class1.get // (L33:588) (writeCall(Class1.get, 0):230) +0;JMP // (L33:589) (writeCall(Class1.get, 0):230) +(b1c23d05017207e2f47201f7bf7111d4) // return back from function here (CALL ENDS) // (L33:590) (writeCall(Class1.get, 0):230) +@2890dd9d65ebe3c3085793074927559c // (L34:590) (push(label, 2890dd9d65ebe3c3085793074927559c):53) +D=A // (L34:591) (push(label, 2890dd9d65ebe3c3085793074927559c):53) +@SP // (L34:592) (writeDtoSPAndBump():62) +A=M // (L34:593) (writeDtoSPAndBump():62) +M=D // (L34:594) (writeDtoSPAndBump():62) +@SP // (L34:595) (increaseSP():72) +M=M+1 // (L34:596) (increaseSP():72) +@LCL // (L34:597) (push(register, LCL, 1):42) +AD=M // (L34:598) (push(register, LCL, 1):42) +@SP // (L34:599) (writeDtoSPAndBump():62) +A=M // (L34:600) (writeDtoSPAndBump():62) +M=D // (L34:601) (writeDtoSPAndBump():62) +@SP // (L34:602) (increaseSP():72) +M=M+1 // (L34:603) (increaseSP():72) +@ARG // (L34:604) (push(register, ARG, 1):42) +AD=M // (L34:605) (push(register, ARG, 1):42) +@SP // (L34:606) (writeDtoSPAndBump():62) +A=M // (L34:607) (writeDtoSPAndBump():62) +M=D // (L34:608) (writeDtoSPAndBump():62) +@SP // (L34:609) (increaseSP():72) +M=M+1 // (L34:610) (increaseSP():72) +@THIS // (L34:611) (push(register, THIS, 1):42) +AD=M // (L34:612) (push(register, THIS, 1):42) +@SP // (L34:613) (writeDtoSPAndBump():62) +A=M // (L34:614) (writeDtoSPAndBump():62) +M=D // (L34:615) (writeDtoSPAndBump():62) +@SP // (L34:616) (increaseSP():72) +M=M+1 // (L34:617) (increaseSP():72) +@THAT // (L34:618) (push(register, THAT, 1):42) +AD=M // (L34:619) (push(register, THAT, 1):42) +@SP // (L34:620) (writeDtoSPAndBump():62) +A=M // (L34:621) (writeDtoSPAndBump():62) +M=D // (L34:622) (writeDtoSPAndBump():62) +@SP // (L34:623) (increaseSP():72) +M=M+1 // (L34:624) (increaseSP():72) +@SP // (L34:625) (copy(SP, LCL):186) +D=M // (L34:626) (copy(SP, LCL):186) +@LCL // (L34:627) (copy(SP, LCL):186) +M=D // Update LCL=SP // (L34:628) (copy(SP, LCL):186) +@SP // (L34:629) (loadOffsetToD(SP, 5, -):193) +D=M // (L34:630) (loadOffsetToD(SP, 5, -):193) +D=D-1 // should repeat 5 times // (L34:631) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L34:632) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L34:633) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L34:634) (loadOffsetToD(SP, 5, -):198) +D=D-1 // should repeat 5 times // (L34:635) (loadOffsetToD(SP, 5, -):198) +@ARG // write SP-$offset to ARG // (L34:636) (writeCall(Class2.get, 0):230) +M=D // (L34:637) (writeCall(Class2.get, 0):230) +@Class2.get // Jump to Class2.get // (L34:638) (writeCall(Class2.get, 0):230) +0;JMP // (L34:639) (writeCall(Class2.get, 0):230) +(2890dd9d65ebe3c3085793074927559c) // return back from function here (CALL ENDS) // (L34:640) (writeCall(Class2.get, 0):230) +(Sys.initWHILE) // end label WHILE // (L35:640) (writeLabel(WHILE):308) +@Sys.initWHILE // (L36:640) (writeGoto(WHILE):329) +0;JMP // end goto WHILE // (L36:641) (writeGoto(WHILE):329) +@643 // (L37:642) (close():298) +0;JMP // (L37:643) (close():298) diff --git a/projects/08/FunctionCalls/StaticsTest/StaticsTest.out b/projects/08/FunctionCalls/StaticsTest/StaticsTest.out new file mode 100644 index 0000000..309f058 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/StaticsTest.out @@ -0,0 +1,2 @@ +| RAM[0] |RAM[261]|RAM[262]| +| 263 | -2 | 8 | diff --git a/projects/08/ProgramFlow/BasicLoop/BasicLoop.asm b/projects/08/ProgramFlow/BasicLoop/BasicLoop.asm index d6fc82f..5009114 100644 --- a/projects/08/ProgramFlow/BasicLoop/BasicLoop.asm +++ b/projects/08/ProgramFlow/BasicLoop/BasicLoop.asm @@ -4,14 +4,14 @@ D=A A=M M=D @SP -M=M+1 // end push constant 0 (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) -(__GLOBAL__.LOOP_START) // end label LOOP_START (L2) +M=D // end pop local 0 +(__GLOBAL__.LOOP_START) // end label LOOP_START @ARG A=M D=M @@ -19,7 +19,7 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L3) +M=M+1 @LCL A=M D=M @@ -27,20 +27,20 @@ D=M A=M M=D @SP -M=M+1 // end push local 0 (L4) +M=M+1 @SP // ==== add ==== A=M-1 D=M A=A-1 M=D+M @SP -M=M-1 // end add (L5) +M=M-1 // end add @SP // pop AM=M-1 D=M @LCL A=M // Read @LCL to A (for local 0) -M=D // end pop local 0 (L6) +M=D // end pop local 0 @ARG A=M D=M @@ -48,27 +48,27 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L7) +M=M+1 @1 // push constant 1 D=A @SP A=M M=D @SP -M=M+1 // end push constant 1 (L8) +M=M+1 @SP // ==== sub ==== A=M-1 D=M A=A-1 M=M-D @SP -M=M-1 // end sub (L9) +M=M-1 // end sub @SP // pop AM=M-1 D=M @ARG A=M // Read @ARG to A (for argument 0) -M=D // end pop argument 0 (L10) +M=D // end pop argument 0 @ARG A=M D=M @@ -76,12 +76,12 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L11) +M=M+1 @SP AM=M-1 D=M @__GLOBAL__.LOOP_START -D;JNE // end if-goto LOOP_START (L12) +D;JNE // end if-goto LOOP_START @LCL A=M D=M @@ -89,6 +89,6 @@ D=M A=M M=D @SP -M=M+1 // end push local 0 (L13) -@93 +M=M+1 +@92 0;JMP diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm index 6a8c02d..3b96f1a 100644 --- a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm @@ -1,17 +1,3 @@ -@256 // init starts -D=A -@SP -M=D // initialized SP to 256 -@300 -D=A -@LCL -M=D // initialized @LCL to 300 -@400 -D=A -@ARG -M=D // initialized @ARG to 400, init ends -@Sys.init -0;JMP @ARG // argument 1 D=M @1 // write 1 to A @@ -25,32 +11,32 @@ D=M A=M M=D @SP -M=M+1 // end push argument 1 (L0) +M=M+1 @SP // pop AM=M-1 D=M @THAT -M=D // (L1) +M=D // @0 // push constant 0 D=A @SP A=M M=D @SP -M=M+1 // end push constant 0 (L2) +M=M+1 @SP // pop AM=M-1 D=M @THAT A=M // Read @THAT to A (for that 0) -M=D // end pop that 0 (L3) +M=D // end pop that 0 @1 // push constant 1 D=A @SP A=M M=D @SP -M=M+1 // end push constant 1 (L4) +M=M+1 @THAT // that 1 D=M @1 // write 1 to A @@ -62,7 +48,7 @@ AM=M-1 D=M @R13 A=M // Read @R13 to A (for that 1) -M=D // end pop that 1 (L5) +M=D // end pop that 1 @ARG A=M D=M @@ -70,28 +56,28 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L6) +M=M+1 @2 // push constant 2 D=A @SP A=M M=D @SP -M=M+1 // end push constant 2 (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 @SP // pop AM=M-1 D=M @ARG A=M // Read @ARG to A (for argument 0) -M=D // end pop argument 0 (L9) -(__GLOBAL__.MAIN_LOOP_START) // end label MAIN_LOOP_START (L10) +M=D // end pop argument 0 +(__GLOBAL__.MAIN_LOOP_START) // end label MAIN_LOOP_START @ARG A=M D=M @@ -99,15 +85,15 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L11) +M=M+1 @SP AM=M-1 D=M @__GLOBAL__.COMPUTE_ELEMENT -D;JNE // end if-goto COMPUTE_ELEMENT (L12) +D;JNE // end if-goto COMPUTE_ELEMENT @__GLOBAL__.END_PROGRAM -0;JMP // end goto END_PROGRAM (L13) -(__GLOBAL__.COMPUTE_ELEMENT) // end label COMPUTE_ELEMENT (L14) +0;JMP // end goto END_PROGRAM +(__GLOBAL__.COMPUTE_ELEMENT) // end label COMPUTE_ELEMENT @THAT A=M D=M @@ -115,7 +101,7 @@ D=M A=M M=D @SP -M=M+1 // end push that 0 (L15) +M=M+1 @THAT // that 1 D=M @1 // write 1 to A @@ -129,14 +115,14 @@ D=M A=M M=D @SP -M=M+1 // end push that 1 (L16) +M=M+1 @SP // ==== add ==== A=M-1 D=M A=A-1 M=D+M @SP -M=M-1 // end add (L17) +M=M-1 // end add @THAT // that 2 D=M @2 // write 2 to A @@ -148,33 +134,33 @@ AM=M-1 D=M @R13 A=M // Read @R13 to A (for that 2) -M=D // end pop that 2 (L18) +M=D // end pop that 2 @THAT // pointer 1 D=M @SP A=M M=D @SP -M=M+1 // end push pointer 1 (L19) +M=M+1 @1 // push constant 1 D=A @SP A=M M=D @SP -M=M+1 // end push constant 1 (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 // pop AM=M-1 D=M @THAT -M=D // (L22) +M=D // @ARG A=M D=M @@ -182,29 +168,29 @@ D=M A=M M=D @SP -M=M+1 // end push argument 0 (L23) +M=M+1 @1 // push constant 1 D=A @SP A=M M=D @SP -M=M+1 // end push constant 1 (L24) +M=M+1 @SP // ==== sub ==== A=M-1 D=M A=A-1 M=M-D @SP -M=M-1 // end sub (L25) +M=M-1 // end sub @SP // pop AM=M-1 D=M @ARG A=M // Read @ARG to A (for argument 0) -M=D // end pop argument 0 (L26) +M=D // end pop argument 0 @__GLOBAL__.MAIN_LOOP_START -0;JMP // end goto MAIN_LOOP_START (L27) -(__GLOBAL__.END_PROGRAM) // end label END_PROGRAM (L28) -@209 +0;JMP // end goto MAIN_LOOP_START +(__GLOBAL__.END_PROGRAM) // end label END_PROGRAM +@192 0;JMP diff --git a/vm/CodeWriter.php b/vm/CodeWriter.php index c97b427..d346c37 100644 --- a/vm/CodeWriter.php +++ b/vm/CodeWriter.php @@ -11,16 +11,85 @@ class CodeWriter { // We aren't inside a function by default $this->fn = null; + $this->comments = true; + // Write the preamble for the assembler $this->writeInit(); } + private function push($kind, $what, $direct = false) { + if ($kind === 'register') { + assert(in_array($what, [ + 'SP','LCL','ARG','THIS','THAT', + 'R0','R1','R2','R3','R4','R5', + 'R6','R7','R8','R9','R10','R11' + ,'R12','R13','R14','R15' , 'D', 'A'] + )); + + switch ($what) { + // A Can be optimized + case 'A': + $direct = true; + $this->write(['D=A']); + break; + case 'D': + $direct = true; + break; + + default: + $this->write([ + "@$what", + "AD=M", + ]); + break; + } + + if ($direct === false) { + $this->write(["D=M"]); + } + } else if ($kind === 'label') { + $this->write([ + "@$what", + "D=A" + ]); + } + + $this->writeDtoSPAndBump(); + } + + private function writeDtoSPAndBump() { + $this->write([ + "@SP", + "A=M", + "M=D", + ]); + + $this->increaseSP(); + } + + private function increaseSP() { + $this->write([ + "@SP", + "M=M+1", + ]); + } + public function writeReturn() { $this->write([ - '@SP', + '@LCL // save return address first', + 'A=M-1', + 'A=A-1', + 'A=A-1', + 'A=A-1', + 'A=A-1', + 'D=M // D now holds the return address', + '@R14', + 'M=D // Wrote the return address to R14', + + "@SP // return for {$this->fn} starts", 'A=M-1', 'D=M',// Popped value to D - // And then write it to *ARG = pop() + // And then write it to R14 '@ARG', 'A=M', 'M=D', @@ -33,13 +102,14 @@ class CodeWriter { '@LCL', 'D=M', '@R13', - 'M=D // Save LCL to R13', + 'M=D // Save LCL to R13 = FRAME', // now we go restoring THAT, THIS, ARG, LCL 'A=D-1 // A=*LCL-1', 'D=M // D=*(*LCL-1)', '@THAT // A=THAT', 'M=D // *that = *(*lcl-1)', + // now we restore THIS '@R13', 'A=M-1', @@ -68,14 +138,9 @@ class CodeWriter { 'M=D // *LCL = *(*lcl-4)', // Now we hyperjump - '@R13', - 'A=M-1', - 'A=A-1', - 'A=A-1', - 'A=A-1', - 'A=A-1 // A=*LCL-5', - 'A=M // A=*(*LCL-5)', - '0;JMP // Jump to *(LCL-5)', + '@R14', + 'A=M', + '0;JMP // HyperJump to *(LCL-5)', ]); } @@ -113,92 +178,99 @@ class CodeWriter { } } + private function copy($registerA, $registerB) { + $this->write([ + "@$registerA", + 'D=M', + "@$registerB", + "M=D // Update $registerB=$registerA", + ]); + } + + private function loadOffsetToD($register, $offset, $sign = '-') { + $this->write([ + "@$register", + "D=M", + ]); + + for ($i=0; $i < $offset; $i++) { + $this->write([ + 'D=D' . $sign . "1 // should repeat $offset times", + ]); + } + } + /** * Function call executed, save state and JUMP */ public function writeCall(String $functionName, $numArgs) { + $returnLabel = bin2hex(random_bytes(16)); - $label = bin2hex(random_bytes(16)); + $this->push('label', $returnLabel); - // push the label to top of the stack - $this->write([ - "@$label // call $functionName $numArgs start", - 'D=A', - '@SP', - 'A=M', - 'M=D', - '@SP', - 'M=M+1', - ]); - - $pushes = [ - '@LCL', - '@ARG', - '@THIS', - '@THAT', - ]; - - // TODO: optimize this by saving LCL, ARG - // then doing the SP-n-5 calculation (since that will be much faster) - // and then updating ARG - foreach ($pushes as $lookupRegister) { - $this->write([ - "$lookupRegister // Read $lookupRegister to A", - "D=M // Put $lookupRegister to D", - '@SP', - 'A=M', - "M=D // Save $lookupRegister to SP", - '@SP', - "M=M+1 // end $lookupRegister pushed to SP", - ]); - } - - // Load current stackpointer to D - // and write it to LCL - $this->write([ - '@SP', - 'D=M', - '@LCL', - 'M=D // Update LCL=SP', - ]); + // push the exact values that these registers are holding + $this->push('register', 'LCL', true); + $this->push('register', 'ARG', true); + $this->push('register', 'THIS', true); + $this->push('register', 'THAT', true); + $this->copy('SP', 'LCL'); // Reduce D height times = numArgs+5 - $height = $numArgs + 5; - for ($i=0; $i < $height; $i++) { - $this->write([ - "D=D-1 // should repeat $height times", - ]); - } + $offset = $numArgs + 5; + $this->loadOffsetToD('SP', $offset, '-'); // now D = SP-n-5 + // now we need to write D to ARG $this->write([ - '@ARG // write D to ARG', + '@ARG // write SP-$offset to ARG', 'M=D', "@$functionName // Jump to $functionName", '0;JMP', - "($label) // return back from function here (CALL ENDS)", + "($returnLabel) // return back from function here (CALL ENDS)", + ]); + + // If we have returned from the Sys.init function call + // then put an infinite loop here + if ($functionName === "Sys.init") { + $this->write([ + '(__GLOBAL_TERMINATE__)', + '@__GLOBAL_TERMINATE__', + '0;JMP', + ]); + } + } + + private function writeConstantToRegister(String $register, Int $constant) { + if ($constant < 0) { + $constant = abs($constant); + $this->write([ + "@$constant", + "D=-A" + ]); + } else if ($constant === 0) { + $this->write(["D=0"]); + } else { + $this->write([ + "@$constant", + "D=A" + ]); + } + $this->write([ + "@$register", + "M=D // initialized $register to $constant", ]); } /** * Writes the preable to initialize the VM */ - private function writeInit() { - $this->write([ - '@256 // init starts', - 'D=A', - '@SP', - 'M=D // initialized SP to 256', - '@3000', - 'D=A', - '@LCL', - 'M=D // initialized @LCL to 3000', - '@4000', - 'D=A', - '@ARG', - 'M=D // initialized @ARG to 4000, init ends', - ]); + private function writeInit($initExists = true) { + $this->writeConstantToRegister("SP", 256); + $this->writeConstantToRegister("LCL", -1); + $this->writeConstantToRegister("ARG", -2); + $this->writeConstantToRegister("THIS", -3); + $this->writeConstantToRegister("THAT", -4); $this->writeCall('Sys.init', 0); } @@ -275,6 +347,58 @@ class CodeWriter { ]); } + private function binaryMath(String $command) { + $map = [ + 'sub' => '-', + 'add' => '+', + 'and' => '&', + 'or' => '|' + ]; + + $symbol = $map[$command]; + + $this->write([ + 'A=A-1', + "M=D{$symbol}M", + ]); + + if ($command === 'sub') { + $this->write([ + 'M=-M' + ]); + } + } + + private function unaryMath(String $command) { + $symbol = [ + 'neg' => '-', + 'not' => '!' + ][$command]; + + $this->write([ + "M={$symbol}M // end $command", + ]); + } + + private function booleanCompare(String $compare) { + $compare = strtoupper($compare); + $command = "D;J$compare"; + + $jumpPointer = $this->ic+10; + $this->write([ + 'A=A-1', + 'D=M-D', + 'M=0', + 'M=M-1', + "@$jumpPointer", + $command, + '@SP', + 'A=M-1', + 'A=A-1', + 'M=0', + ]); + } + function writeArithmetic(String $command) { $stackDecrease=true; // Read top of stack to D @@ -288,101 +412,27 @@ class CodeWriter { // TODO: Combine all the binary math commands into one // And the unary math commands into one case 'sub': - $this->write([ - 'A=A-1', - 'M=M-D', - ]); - break; - case 'add': - // But add it to previous D this time - $this->write([ - 'A=A-1', - 'M=D+M' - ]); + case 'and': + case 'or': + $this->binaryMath($command); break; case 'neg': - $this->write([ - "M=-M // end $command", - ]); - $stackDecrease = false; - break; - - case 'not': - $this->write([ - "M=!M // end $command", - ]); + $this->unaryMath($command); $stackDecrease = false; break; - case 'and': - $this->write([ - 'A=A-1', - 'M=D&M', - ]); - break; - - case 'or': - $this->write([ - 'A=A-1', - 'M=D|M', - ]); - break; - // TODO: Combine all the boolean commands case 'lt': - $jumpPointer = $this->ic+11; - $this->write([ - 'A=A-1', - 'D=M-D', - 'M=0', - 'M=M-1', - "@$jumpPointer", - 'D;JLT', - '@SP', - 'A=M-1', - 'A=A-1', - 'M=0', - ]); - break; - case 'gt': - $jumpPointer = $this->ic+11; - $this->write([ - 'A=A-1', - 'D=M-D', - 'M=0', - 'M=M-1', - "@$jumpPointer", - "D;JGT", - '@SP', - 'A=M-1', - 'A=A-1', - 'M=0', - ]); - break; - case 'eq': - $jumpPointer = $this->ic+11; - $this->write([ - 'A=A-1', - 'D=M-D', - 'M=0', - 'M=M-1', - "@{$jumpPointer}", - 'D;JEQ', - '@SP', - 'A=M-1', - 'A=A-1', - 'M=0', - ]); + $this->booleanCompare($command); break; default: throw new \Exception("$command not Implemented", 1); - } if ($stackDecrease) { @@ -394,8 +444,18 @@ class CodeWriter { } private function write(Array $lines) { + // print_r(debug_backtrace()); + // exit(1); + $callingLine = debug_backtrace()[0]['line']; + $callingFunction = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[1]['function']; + $args = join(", ", debug_backtrace(false, 2)[1]['args']); foreach ($lines as $line) { - fwrite($this->file, "$line // (L{$this->sourceLine}:{$this->ic})\n"); + if ($this->comments === true ) { + $line = "$line \t\t\t\t// (L{$this->sourceLine}:{$this->ic}) ($callingFunction($args):$callingLine)\n"; + } else { + $line = "$line\n"; + } + fwrite($this->file, $line); if (substr($line, 0, 2) !== "//" and substr($line, 0, 1) !== "(") { $this->ic += 1; } @@ -464,16 +524,7 @@ class CodeWriter { break; } - $this->write([ - // A=SP - "@SP", - "A=M", - // Write D to SP - "M=D", - // Bump Stack Pointer - "@SP", - "M=M+1 // end push $segment $index", - ]); + $this->writeDtoSPAndBump(); } /** @@ -581,7 +632,7 @@ class CodeWriter { * Resolves pointer [0|1] to the this|that register */ private function resolvePointer(Int $index) { - return $index == 0 ? '@THIS' : '@THAT'; + return ($index === 0) ? '@THIS' : '@THAT'; } // Keeping this because book asked me to diff --git a/vm/VMTranslator.php b/vm/VMTranslator.php index c867c15..8b040d1 100644 --- a/vm/VMTranslator.php +++ b/vm/VMTranslator.php @@ -98,9 +98,16 @@ class VMTranslator { $name = basename($dir); return "$dir/$name.asm"; } + + public function disableComments() { + $this->writer->comments = false; + } } if(isset($argv[1])) { $vmt = new VMTranslator($argv[1]); + if (isset($argv[2]) and $argv[2] === "--no-comments") { + $vmt->disableComments(); + } $vmt->translate(); }