Add solutions for part 1
This commit is contained in:
589
projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm
Normal file
589
projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm
Normal file
@@ -0,0 +1,589 @@
|
||||
// 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
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| RAM[0] |RAM[261]|
|
||||
| 262 | 3 |
|
||||
@@ -0,0 +1,18 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst
|
||||
|
||||
// FibonacciElement.asm results from translating both Main.vm and Sys.vm into
|
||||
// a single assembly program, stored in the file FibonacciElement.asm.
|
||||
|
||||
load FibonacciElement.asm,
|
||||
output-file FibonacciElement.out,
|
||||
compare-to FibonacciElement.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1;
|
||||
|
||||
repeat 6000 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
@@ -0,0 +1,17 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst
|
||||
|
||||
load, // Load all the VM files from the current directory
|
||||
output-file FibonacciElement.out,
|
||||
compare-to FibonacciElement.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1;
|
||||
|
||||
set sp 261,
|
||||
|
||||
repeat 110 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
30
projects/08/FunctionCalls/FibonacciElement/Main.vm
Normal file
30
projects/08/FunctionCalls/FibonacciElement/Main.vm
Normal file
@@ -0,0 +1,30 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/Main.vm
|
||||
|
||||
// Computes the n'th element of the Fibonacci series, recursively.
|
||||
// n is given in argument[0]. Called by the Sys.init function
|
||||
// (part of the Sys.vm file), which also pushes the argument[0]
|
||||
// parameter before this code starts running.
|
||||
|
||||
function Main.fibonacci 0
|
||||
push argument 0
|
||||
push constant 2
|
||||
lt // checks if n<2
|
||||
if-goto IF_TRUE
|
||||
goto IF_FALSE
|
||||
label IF_TRUE // if n<2, return n
|
||||
push argument 0
|
||||
return
|
||||
label IF_FALSE // if n>=2, returns fib(n-2)+fib(n-1)
|
||||
push argument 0
|
||||
push constant 2
|
||||
sub
|
||||
call Main.fibonacci 1 // computes fib(n-2)
|
||||
push argument 0
|
||||
push constant 1
|
||||
sub
|
||||
call Main.fibonacci 1 // computes fib(n-1)
|
||||
add // returns fib(n-1) + fib(n-2)
|
||||
return
|
||||
15
projects/08/FunctionCalls/FibonacciElement/Sys.vm
Normal file
15
projects/08/FunctionCalls/FibonacciElement/Sys.vm
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/Sys.vm
|
||||
|
||||
// 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"
|
||||
// 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
|
||||
Reference in New Issue
Block a user