590 lines
4.9 KiB
NASM
590 lines
4.9 KiB
NASM
// 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
|
|
|
|
|