// Bootstrap code @256 D = A @SP M = D // ^ SP = 256 // call Sys.init 0 @Sys.init:return:0 D = A @SP A = M M = D @SP M = M + 1 // ^ push return-address @LCL D = M @SP A = M M = D @SP M = M + 1 // ^ push lcl @ARG D = M @SP A = M M = D @SP M = M + 1 // ^ push arg @THIS D = M @SP A = M M = D @SP M = M + 1 // ^ push this @THAT D = M @SP A = M M = D @SP M = M + 1 // ^ push that @SP D = M @0 D = D - A @5 D = D - A @ARG M = D // ^ ARG = SP - 0 - 5 @SP D = M @LCL M = D // ^ LCL = SP @Sys.init 0;JMP // ^ goto Sys.init (Sys.init:return:0) // Start /home/felixm/dev/nand2tetris/projects/08/FunctionCalls/FibonacciElement/Sys.vm // function Sys.init 0 (Sys.init) @0 D = A // ^ push 0 * 0 // push constant 4 @4 D = A @SP A = M M = D @SP M = M + 1 // call Main.fibonacci 1 @Main.fibonacci:return:1 D = A @SP A = M M = D @SP M = M + 1 // ^ push return-address @LCL D = M @SP A = M M = D @SP M = M + 1 // ^ push lcl @ARG D = M @SP A = M M = D @SP M = M + 1 // ^ push arg @THIS D = M @SP A = M M = D @SP M = M + 1 // ^ push this @THAT D = M @SP A = M M = D @SP M = M + 1 // ^ push that @SP D = M @1 D = D - A @5 D = D - A @ARG M = D // ^ ARG = SP - 1 - 5 @SP D = M @LCL M = D // ^ LCL = SP @Main.fibonacci 0;JMP // ^ goto Main.fibonacci (Main.fibonacci:return:1) // label Sys.init:WHILE (Sys.init:WHILE) // goto Sys.init:WHILE @Sys.init:WHILE 0;JMP // Start /home/felixm/dev/nand2tetris/projects/08/FunctionCalls/FibonacciElement/Main.vm // function Main.fibonacci 0 (Main.fibonacci) @0 D = A // ^ push 0 * 0 // push argument 0 @0 D = A @ARG A = M A = D + A D = M // ^ D = *(ARG + index) @SP A = M M = D @SP M = M + 1 // ^ push D // push constant 2 @2 D = A @SP A = M M = D @SP M = M + 1 // lt @SP A = M A = A - 1 A = A - 1 D = M A = A + 1 D = D - M @IF_JLT_1 D;JLT @ELSE_JLT_1 0;JMP (IF_JLT_1) D = -1 @END_JLT_1 0;JMP (ELSE_JLT_1) D = 0 (END_JLT_1) @SP A = M A = A - 1 A = A - 1 M = D @SP M = M - 1 // if-goto Main.fibonacci:IF_TRUE @SP A = M A = A - 1 D = M @SP M = M - 1 @Main.fibonacci:IF_TRUE D;JNE // goto Main.fibonacci:IF_FALSE @Main.fibonacci:IF_FALSE 0;JMP // label Main.fibonacci:IF_TRUE (Main.fibonacci:IF_TRUE) // push argument 0 @0 D = A @ARG A = M A = D + A D = M // ^ D = *(ARG + index) @SP A = M M = D @SP M = M + 1 // ^ push D // return @LCL D = M @R13 M = D // ^ R13 = FRAME = LCL @5 D = A @R13 A = M - D D = M @R14 M = D // ^ R14 = RET = *(FRAME - 5) @SP A = M A = A - 1 D = M @SP M = M - 1 @ARG A = M M = D // ^ POP into *ARG @ARG D = M + 1 @SP M = D // ^ SP = ARG + 1 @1 D = A @R13 A = M - D D = M @THAT M = D // ^ THAT = *(FRAME - 1) @2 D = A @R13 A = M - D D = M @THIS M = D // ^ THIS = *(FRAME - 2) @3 D = A @R13 A = M - D D = M @ARG M = D // ^ ARG = *(FRAME - 3) @4 D = A @R13 A = M - D D = M @LCL M = D // ^ LCL = *(FRAME - 4) @R14 A = M 0;JMP // ^ goto RET // label Main.fibonacci:IF_FALSE (Main.fibonacci:IF_FALSE) // push argument 0 @0 D = A @ARG A = M A = D + A D = M // ^ D = *(ARG + index) @SP A = M M = D @SP M = M + 1 // ^ push D // push constant 2 @2 D = A @SP A = M M = D @SP M = M + 1 // sub @SP A = M A = A - 1 A = A - 1 D = M A = A + 1 D = D - M A = A - 1 M = D @SP M = M - 1 // call Main.fibonacci 1 @Main.fibonacci:return:2 D = A @SP A = M M = D @SP M = M + 1 // ^ push return-address @LCL D = M @SP A = M M = D @SP M = M + 1 // ^ push lcl @ARG D = M @SP A = M M = D @SP M = M + 1 // ^ push arg @THIS D = M @SP A = M M = D @SP M = M + 1 // ^ push this @THAT D = M @SP A = M M = D @SP M = M + 1 // ^ push that @SP D = M @1 D = D - A @5 D = D - A @ARG M = D // ^ ARG = SP - 1 - 5 @SP D = M @LCL M = D // ^ LCL = SP @Main.fibonacci 0;JMP // ^ goto Main.fibonacci (Main.fibonacci:return:2) // push argument 0 @0 D = A @ARG A = M A = D + A D = M // ^ D = *(ARG + index) @SP A = M M = D @SP M = M + 1 // ^ push D // push constant 1 @1 D = A @SP A = M M = D @SP M = M + 1 // sub @SP A = M A = A - 1 A = A - 1 D = M A = A + 1 D = D - M A = A - 1 M = D @SP M = M - 1 // call Main.fibonacci 1 @Main.fibonacci:return:3 D = A @SP A = M M = D @SP M = M + 1 // ^ push return-address @LCL D = M @SP A = M M = D @SP M = M + 1 // ^ push lcl @ARG D = M @SP A = M M = D @SP M = M + 1 // ^ push arg @THIS D = M @SP A = M M = D @SP M = M + 1 // ^ push this @THAT D = M @SP A = M M = D @SP M = M + 1 // ^ push that @SP D = M @1 D = D - A @5 D = D - A @ARG M = D // ^ ARG = SP - 1 - 5 @SP D = M @LCL M = D // ^ LCL = SP @Main.fibonacci 0;JMP // ^ goto Main.fibonacci (Main.fibonacci:return:3) // add @SP A = M A = A - 1 A = A - 1 D = M A = A + 1 D = D + M A = A - 1 M = D @SP M = M - 1 // return @LCL D = M @R13 M = D // ^ R13 = FRAME = LCL @5 D = A @R13 A = M - D D = M @R14 M = D // ^ R14 = RET = *(FRAME - 5) @SP A = M A = A - 1 D = M @SP M = M - 1 @ARG A = M M = D // ^ POP into *ARG @ARG D = M + 1 @SP M = D // ^ SP = ARG + 1 @1 D = A @R13 A = M - D D = M @THAT M = D // ^ THAT = *(FRAME - 1) @2 D = A @R13 A = M - D D = M @THIS M = D // ^ THIS = *(FRAME - 2) @3 D = A @R13 A = M - D D = M @ARG M = D // ^ ARG = *(FRAME - 3) @4 D = A @R13 A = M - D D = M @LCL M = D // ^ LCL = *(FRAME - 4) @R14 A = M 0;JMP // ^ goto RET