diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm index ada39c6..c923bd7 100644 --- a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm @@ -1,370 +1,417 @@ -@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 -(Main.fibonacci) // function Main.fibonacci 0 -@ARG -A=M -D=M -@SP -A=M -M=D -@SP -M=M+1 // end push argument 0 (L1) -@2 // push constant 2 -D=A -@SP -A=M -M=D -@SP -M=M+1 // end push constant 2 (L2) -@SP // ==== lt ==== -A=M-1 -D=M -A=A-1 -D=M-D -M=0 -M=M-1 -@43 -D;JLT -@SP -A=M-1 -A=A-1 -M=0 -@SP -M=M-1 // end lt (L3) -@SP -AM=M-1 -D=M -@Main.fibonacciIF_TRUE -D;JNE // end if-goto IF_TRUE (L4) -@Main.fibonacciIF_FALSE -0;JMP // end goto IF_FALSE (L5) -(Main.fibonacciIF_TRUE) // end label IF_TRUE (L6) -@ARG -A=M -D=M -@SP -A=M -M=D -@SP -M=M+1 // end push argument 0 (L7) -@SP -A=M-1 -D=M -@ARG -A=M -M=D -@ARG -D=M+1 -@SP -M=D // @SP = ARG+1 -@LCL -D=M -@R13 -M=D // Save LCL to R13 -A=D-1 // A=*LCL-1 -D=M // D=*(*LCL-1) -@THAT // A=THAT -M=D // *that = *(*lcl-1) -@R13 -A=M-1 -A=A-1 // A=*LCL-2 -D=M // D=*(*LCL-2) -@THIS // A=THIS -M=D // *THIS = *(*lcl-2) -@R13 -A=M-1 -A=A-1 -A=A-1 // A=*LCL-3 -D=M // D=*(*LCL-3) -@ARG // A=ARG -M=D // *ARG = *(*lcl-3) -@R13 -A=M-1 -A=A-1 -A=A-1 -A=A-1 // A=*LCL-4 -D=M // D=*(*LCL-4) -@LCL // A=LCL -M=D // *LCL = *(*lcl-4) -@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) -(Main.fibonacciIF_FALSE) // end label IF_FALSE (L9) -@ARG -A=M -D=M -@SP -A=M -M=D -@SP -M=M+1 // end push argument 0 (L10) -@2 // push constant 2 -D=A -@SP -A=M -M=D -@SP -M=M+1 // end push constant 2 (L11) -@SP // ==== sub ==== -A=M-1 -D=M -A=A-1 -M=M-D -@SP -M=M-1 // end sub (L12) -@5fd25fdab54b4bfd5a91536ecfd6806e -D=A -@SP -A=M -M=D -@SP -M=M+1 -@LCL // Read @LCL to A -D=M // Put @LCL to D -@SP -A=M -M=D // Save @LCL to SP -@SP -M=M+1 -@ARG // Read @ARG to A -D=M // Put @ARG to D -@SP -A=M -M=D // Save @ARG to SP -@SP -M=M+1 -@THIS // Read @THIS to A -D=M // Put @THIS to D -@SP -A=M -M=D // Save @THIS to SP -@SP -M=M+1 -@THAT // Read @THAT to A -D=M // Put @THAT to D -@SP -A=M -M=D // Save @THAT to SP -@SP -M=M+1 -@SP -D=M -@LCL -M=D -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -@ARG -M=D -@Main.fibonacci // Jump to Main.fibonacci -0;JMP -(5fd25fdab54b4bfd5a91536ecfd6806e) // return back from function here -@ARG -A=M -D=M -@SP -A=M -M=D -@SP -M=M+1 // end push argument 0 (L14) -@1 // push constant 1 -D=A -@SP -A=M -M=D -@SP -M=M+1 // end push constant 1 (L15) -@SP // ==== sub ==== -A=M-1 -D=M -A=A-1 -M=M-D -@SP -M=M-1 // end sub (L16) -@a954c9cff71cdccc09f4338e60df6394 -D=A -@SP -A=M -M=D -@SP -M=M+1 -@LCL // Read @LCL to A -D=M // Put @LCL to D -@SP -A=M -M=D // Save @LCL to SP -@SP -M=M+1 -@ARG // Read @ARG to A -D=M // Put @ARG to D -@SP -A=M -M=D // Save @ARG to SP -@SP -M=M+1 -@THIS // Read @THIS to A -D=M // Put @THIS to D -@SP -A=M -M=D // Save @THIS to SP -@SP -M=M+1 -@THAT // Read @THAT to A -D=M // Put @THAT to D -@SP -A=M -M=D // Save @THAT to SP -@SP -M=M+1 -@SP -D=M -@LCL -M=D -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -@ARG -M=D -@Main.fibonacci // Jump to Main.fibonacci -0;JMP -(a954c9cff71cdccc09f4338e60df6394) // return back from function here -@SP // ==== add ==== -A=M-1 -D=M -A=A-1 -M=D+M -@SP -M=M-1 // end add (L18) -@SP -A=M-1 -D=M -@ARG -A=M -M=D -@ARG -D=M+1 -@SP -M=D // @SP = ARG+1 -@LCL -D=M -@R13 -M=D // Save LCL to R13 -A=D-1 // A=*LCL-1 -D=M // D=*(*LCL-1) -@THAT // A=THAT -M=D // *that = *(*lcl-1) -@R13 -A=M-1 -A=A-1 // A=*LCL-2 -D=M // D=*(*LCL-2) -@THIS // A=THIS -M=D // *THIS = *(*lcl-2) -@R13 -A=M-1 -A=A-1 -A=A-1 // A=*LCL-3 -D=M // D=*(*LCL-3) -@ARG // A=ARG -M=D // *ARG = *(*lcl-3) -@R13 -A=M-1 -A=A-1 -A=A-1 -A=A-1 // A=*LCL-4 -D=M // D=*(*LCL-4) -@LCL // A=LCL -M=D // *LCL = *(*lcl-4) -@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) -(Sys.init) // function Sys.init 0 -@4 // push constant 4 -D=A -@SP -A=M -M=D -@SP -M=M+1 // end push constant 4 (L21) -@dd19df789547baebfea110998cdf5713 -D=A -@SP -A=M -M=D -@SP -M=M+1 -@LCL // Read @LCL to A -D=M // Put @LCL to D -@SP -A=M -M=D // Save @LCL to SP -@SP -M=M+1 -@ARG // Read @ARG to A -D=M // Put @ARG to D -@SP -A=M -M=D // Save @ARG to SP -@SP -M=M+1 -@THIS // Read @THIS to A -D=M // Put @THIS to D -@SP -A=M -M=D // Save @THIS to SP -@SP -M=M+1 -@THAT // Read @THAT to A -D=M // Put @THAT to D -@SP -A=M -M=D // Save @THAT to SP -@SP -M=M+1 -@SP -D=M -@LCL -M=D -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -D=D-1 -@ARG -M=D -@Main.fibonacci // Jump to Main.fibonacci -0;JMP -(dd19df789547baebfea110998cdf5713) // return back from function here -(Sys.initWHILE) // end label WHILE (L23) -@Sys.initWHILE -0;JMP // end goto WHILE (L24) -@369 -0;JMP +@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) diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out index 546d784..fdf5e2d 100644 --- a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out @@ -1,2 +1,2 @@ | RAM[0] |RAM[261]| -| 257 | 0 | +| 262 | 3 | diff --git a/vm/CodeWriter.php b/vm/CodeWriter.php index 4afdf10..c97b427 100644 --- a/vm/CodeWriter.php +++ b/vm/CodeWriter.php @@ -17,65 +17,65 @@ class CodeWriter { public function writeReturn() { $this->write([ - "@SP", - "A=M-1", - "D=M",// Popped value to D + '@SP', + 'A=M-1', + 'D=M',// Popped value to D // And then write it to *ARG = pop() - "@ARG", - "A=M", - "M=D", + '@ARG', + 'A=M', + 'M=D', // SP=ARG+1 - "@ARG", - "D=M+1", - "@SP", - "M=D // @SP = ARG+1", - "@LCL", - "D=M", - "@R13", - "M=D // Save LCL to R13", + '@ARG', + 'D=M+1', + '@SP', + 'M=D // @SP = ARG+1', + '@LCL', + 'D=M', + '@R13', + 'M=D // Save LCL to R13', // 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)", + '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", - "A=A-1 // A=*LCL-2", - "D=M // D=*(*LCL-2)", - "@THIS // A=THIS", - "M=D // *THIS = *(*lcl-2)", + '@R13', + 'A=M-1', + 'A=A-1 // A=*LCL-2', + 'D=M // D=*(*LCL-2)', + '@THIS // A=THIS', + 'M=D // *THIS = *(*lcl-2)', // now we restore ARG - "@R13", - "A=M-1", - "A=A-1", - "A=A-1 // A=*LCL-3", - "D=M // D=*(*LCL-3)", - "@ARG // A=ARG", - "M=D // *ARG = *(*lcl-3)", + '@R13', + 'A=M-1', + 'A=A-1', + 'A=A-1 // A=*LCL-3', + 'D=M // D=*(*LCL-3)', + '@ARG // A=ARG', + 'M=D // *ARG = *(*lcl-3)', // now we restore LCL - "@R13", - "A=M-1", - "A=A-1", - "A=A-1", - "A=A-1 // A=*LCL-4", - "D=M // D=*(*LCL-4)", - "@LCL // A=LCL", - "M=D // *LCL = *(*lcl-4)", + '@R13', + 'A=M-1', + 'A=A-1', + 'A=A-1', + 'A=A-1 // A=*LCL-4', + 'D=M // D=*(*LCL-4)', + '@LCL // A=LCL', + '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)", + '@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)', ]); } @@ -97,7 +97,8 @@ class CodeWriter { if ($numArgs > 0) { $this->write([ // This is only required for the first argument - "@SP", "A=M" + '@SP', + 'A=M', ]); } @@ -105,9 +106,9 @@ class CodeWriter { // push a zero to the stack for($i=0;$i<$numArgs;$i++) { $this->write([ - "M=0", - "@SP", - "AM=M+1", + 'M=0', + '@SP', + 'AM=M+1', ]); } } @@ -121,20 +122,20 @@ class CodeWriter { // push the label to top of the stack $this->write([ - "@$label", - "D=A", - "@SP", - "A=M", - "M=D", - "@SP", - "M=M+1" + "@$label // call $functionName $numArgs start", + 'D=A', + '@SP', + 'A=M', + 'M=D', + '@SP', + 'M=M+1', ]); $pushes = [ - "@LCL", - "@ARG", - "@THIS", - "@THAT", + '@LCL', + '@ARG', + '@THIS', + '@THAT', ]; // TODO: optimize this by saving LCL, ARG @@ -144,42 +145,39 @@ class CodeWriter { $this->write([ "$lookupRegister // Read $lookupRegister to A", "D=M // Put $lookupRegister to D", - "@SP", - "A=M", + '@SP', + 'A=M', "M=D // Save $lookupRegister to SP", - "@SP", - "M=M+1", + '@SP', + "M=M+1 // end $lookupRegister pushed to SP", ]); } // Load current stackpointer to D + // and write it to LCL $this->write([ - "@SP", - "D=M", - ]); - - // Write current stackpointer to LCL - $this->write([ - "@LCL", - "M=D", + '@SP', + 'D=M', + '@LCL', + 'M=D // Update LCL=SP', ]); // Reduce D height times = numArgs+5 $height = $numArgs + 5; for ($i=0; $i < $height; $i++) { $this->write([ - "D=D-1", + "D=D-1 // should repeat $height times", ]); } // now D = SP-n-5 // now we need to write D to ARG $this->write([ - "@ARG", - "M=D", + '@ARG // write D to ARG', + 'M=D', "@$functionName // Jump to $functionName", - "0;JMP", - "($label) // return back from function here", + '0;JMP', + "($label) // return back from function here (CALL ENDS)", ]); } @@ -188,22 +186,21 @@ class CodeWriter { */ private function writeInit() { $this->write([ - "@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", - // We jump to Sys.init - "@Sys.init", - "0;JMP" + '@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', ]); + + $this->writeCall('Sys.init', 0); } function setInputFileName($inputFileName) { @@ -226,7 +223,7 @@ class CodeWriter { $endJump = $this->ic+1; $this->write([ "@$endJump", - "0;JMP" + '0;JMP', ]); } @@ -236,7 +233,7 @@ class CodeWriter { function writeLabel(String $label) { $globalLabel = $this->resolveLabel($label); $this->write([ - "($globalLabel) // end label $label (L{$this->sourceLine})", + "($globalLabel) // end label $label", ]); } @@ -257,7 +254,7 @@ class CodeWriter { $globalLabel = $this->resolveLabel($label); $this->write([ "@$globalLabel", - "0;JMP // end goto $label (L{$this->sourceLine})", + "0;JMP // end goto $label", ]); } @@ -274,7 +271,7 @@ class CodeWriter { 'AM=M-1', 'D=M', "@$globalLabel", - "D;JNE // end if-goto $label (L{$this->sourceLine})", + "D;JNE // end if-goto $label", ]); } @@ -283,8 +280,8 @@ class CodeWriter { // Read top of stack to D $this->write([ "@SP // ==== $command ====", - "A=M-1", - "D=M" + 'A=M-1', + 'D=M' ]); switch ($command) { @@ -293,7 +290,7 @@ class CodeWriter { case 'sub': $this->write([ 'A=A-1', - "M=M-D", + 'M=M-D', ]); break; @@ -307,7 +304,7 @@ class CodeWriter { case 'neg': $this->write([ - "M=-M // end $command (L{$this->sourceLine})", + "M=-M // end $command", ]); $stackDecrease = false; break; @@ -315,7 +312,7 @@ class CodeWriter { case 'not': $this->write([ - "M=!M // end $command (L{$this->sourceLine})", + "M=!M // end $command", ]); $stackDecrease = false; break; @@ -336,23 +333,23 @@ class CodeWriter { // TODO: Combine all the boolean commands case 'lt': - $jumpPointer = $this->ic+10; + $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", + 'D;JLT', + '@SP', + 'A=M-1', + 'A=A-1', + 'M=0', ]); break; case 'gt': - $jumpPointer = $this->ic+10; + $jumpPointer = $this->ic+11; $this->write([ 'A=A-1', 'D=M-D', @@ -360,15 +357,15 @@ class CodeWriter { 'M=M-1', "@$jumpPointer", "D;JGT", - "@SP", - "A=M-1", - "A=A-1", - "M=0", + '@SP', + 'A=M-1', + 'A=A-1', + 'M=0', ]); break; case 'eq': - $jumpPointer = $this->ic+10; + $jumpPointer = $this->ic+11; $this->write([ 'A=A-1', 'D=M-D', @@ -376,10 +373,10 @@ class CodeWriter { 'M=M-1', "@{$jumpPointer}", 'D;JEQ', - "@SP", - "A=M-1", - "A=A-1", - "M=0", + '@SP', + 'A=M-1', + 'A=A-1', + 'M=0', ]); break; @@ -391,17 +388,17 @@ class CodeWriter { if ($stackDecrease) { $this->write([ '@SP', - "M=M-1 // end $command (L{$this->sourceLine})" + "M=M-1 // end $command" ]); } } private function write(Array $lines) { foreach ($lines as $line) { - if (substr($line, 0, 2) !== "//") { + fwrite($this->file, "$line // (L{$this->sourceLine}:{$this->ic})\n"); + if (substr($line, 0, 2) !== "//" and substr($line, 0, 1) !== "(") { $this->ic += 1; } - fwrite($this->file, "$line\n"); } } @@ -419,7 +416,7 @@ class CodeWriter { // Take the constant "@$index // push $segment $index", // Write it to D - "D=A", + 'D=A', ]); break; case 'argument': @@ -433,8 +430,8 @@ class CodeWriter { } $this->write([ $register, - "A=M", - "D=M", + 'A=M', + 'D=M', ]); break; @@ -442,7 +439,7 @@ class CodeWriter { $symbol = $this->resolveStatic($index); $this->write([ $symbol, - "D=M" + 'D=M' ]); break; @@ -450,7 +447,7 @@ class CodeWriter { $register = $this->resolvePointer($index); $this->write([ "$register // pointer $index", - "D=M" + 'D=M' ]); break; @@ -458,7 +455,7 @@ class CodeWriter { $register = $this->resolveTemp($index); $this->write([ "$register // temp $index", - "D=M" + 'D=M' ]); break; @@ -475,7 +472,7 @@ class CodeWriter { "M=D", // Bump Stack Pointer "@SP", - "M=M+1 // end push $segment $index (L{$this->sourceLine})", + "M=M+1 // end push $segment $index", ]); } @@ -500,7 +497,7 @@ class CodeWriter { $register = $this->resolveSegmentToRegister($segment); $this->write([ "$register // $segment $index" , - "D=M", + 'D=M', "@$index // write $index to A", "D=D+A // D = segment+index", "@R13 // save it to R13", @@ -533,10 +530,10 @@ class CodeWriter { $this->write([ "@SP // pop", "AM=M-1", - "D=M", + 'D=M', $lookupRegister, "A=M // Read $lookupRegister to A (for $segment $index)", - "M=D // end pop $segment $index (L{$this->sourceLine})", + "M=D // end pop $segment $index", ]); break; @@ -545,9 +542,9 @@ class CodeWriter { $this->write([ "@SP //pop $segment $index", "AM=M-1", - "D=M", + 'D=M', $symbol, - "M=D // end pop $segment $index (L{$this->sourceLine})" + "M=D // end pop $segment $index" ]); break; @@ -557,9 +554,9 @@ class CodeWriter { $this->write([ "@SP // pop", "AM=M-1", - "D=M", + 'D=M', $register, - "M=D // (L{$this->sourceLine})" + "M=D //" ]); break; @@ -568,9 +565,9 @@ class CodeWriter { $this->write([ "@SP", "AM=M-1", - "D=M", + 'D=M', "$tempRegister", - "M=D // end pop temp $index (L{$this->sourceLine})" + "M=D // end pop temp $index" ]); break;