# 8. 虛擬機 II | 教學 | 主題 | 影片 | |--------|----|-------| | 投影片 | [Chapter 8. VM II: Program Control](http://nand2tetris.org/lectures/PDF/lecture%2008%20virtual%20machine%20II.pdf) | | ## 控制邏輯 範例 -- https://github.com/cccnqu/sp106b/blob/master/more/nand2tetris/08/ProgramFlow/BasicLoop/BasicLoop.vm BasicLoop.vm ``` // Computes the sum 1 + 2 + ... + argument[0] and pushes the // result onto the stack. Argument[0] is initialized by the test // script before this code starts running. push constant 0 pop local 0 // initializes sum = 0 label LOOP_START push argument 0 push local 0 add pop local 0 // sum = sum + counter push argument 0 push constant 1 sub pop argument 0 // counter-- push argument 0 if-goto LOOP_START // If counter > 0, goto LOOP_START push local 0 ``` 對應組合語言 -- https://github.com/cccnqu/sp106b/blob/master/more/nand2tetris/08/ProgramFlow/BasicLoop/BasicLoop.asm BasicLoop.asm ``` // push constant 0 @0 D=A @SP A=M M=D @SP M=M+1 // pop local 0 // initialize sum = 0 @SP M=M-1 @LCL AD=M @R15 M=D @SP A=M D=M @R15 A=M M=D // label LOOP_START (LOOP_START) // push argument 0 @ARG AD=M D=M @SP A=M M=D @SP M=M+1 // push local 0 @LCL AD=M D=M @SP A=M M=D @SP M=M+1 // add @SP M=M-1 @SP A=M D=M @SP M=M-1 @SP A=M A=M D=D+A @SP A=M M=D @SP M=M+1 // pop local 0 // sum = sum + counter @SP M=M-1 @LCL AD=M @R15 M=D @SP A=M D=M @R15 A=M M=D // push argument 0 @ARG AD=M D=M @SP A=M M=D @SP M=M+1 // push constant 1 @1 D=A @SP A=M M=D @SP M=M+1 // sub @SP M=M-1 @SP A=M D=M @SP M=M-1 @SP A=M A=M D=A-D @SP A=M M=D @SP M=M+1 // pop argument 0 // counter-- @SP M=M-1 @ARG AD=M @R15 M=D @SP A=M D=M @R15 A=M M=D // push argument 0 @ARG AD=M D=M @SP A=M M=D @SP M=M+1 // if-goto LOOP_START // If counter > 0, goto LOOP_START @SP M=M-1 @SP A=M D=M @LOOP_START D;JNE // push local 0 @LCL AD=M D=M @SP A=M M=D @SP M=M+1 ``` ## 函數呼叫 範例 -- https://github.com/cccnqu/sp106b/blob/master/more/nand2tetris/08/FunctionCalls/SimpleFunction/SimpleFunction.vm SimpleFunction.vm ``` // Performs a simple calculation and returns the result. function SimpleFunction.test 2 push local 0 push local 1 add not push argument 0 add push argument 1 sub return ``` 對應組合語言 -- https://github.com/cccnqu/sp106b/blob/master/more/nand2tetris/08/FunctionCalls/SimpleFunction/SimpleFunction.asm SimpleFunction.asm ``` // function SimpleFunction.test 2 (SimpleFunction.test) @0 D=A @SP A=M M=D @SP M=M+1 @0 D=A @SP A=M M=D @SP M=M+1 // push local 0 @LCL AD=M D=M @SP A=M M=D @SP M=M+1 // push local 1 @1 D=A @LCL A=M AD=D+A D=M @SP A=M M=D @SP M=M+1 // add @SP M=M-1 @SP A=M D=M @SP M=M-1 @SP A=M A=M D=D+A @SP A=M M=D @SP M=M+1 // not @SP M=M-1 @SP A=M D=M D=!D @SP A=M M=D @SP M=M+1 // push argument 0 @ARG AD=M D=M @SP A=M M=D @SP M=M+1 // add @SP M=M-1 @SP A=M D=M @SP M=M-1 @SP A=M A=M D=D+A @SP A=M M=D @SP M=M+1 // push argument 1 @1 D=A @ARG A=M AD=D+A D=M @SP A=M M=D @SP M=M+1 // sub @SP M=M-1 @SP A=M D=M @SP M=M-1 @SP A=M A=M D=A-D @SP A=M M=D @SP M=M+1 // return @R1 D=M @R13 M=D @5 A=D-A D=M @R14 M=D @SP M=M-1 @ARG AD=M @R15 M=D @SP A=M D=M @R15 A=M M=D @R2 D=M @R0 M=D+1 @R13 D=M D=D-1 @R13 M=D A=D D=M @R4 M=D @R13 D=M D=D-1 @R13 M=D A=D D=M @R3 M=D @R13 D=M D=D-1 @R13 M=D A=D D=M @R2 M=D @R13 D=M D=D-1 @R13 M=D A=D D=M @R1 M=D @R13 D=M D=D-1 @R13 M=D A=D D=M @R14 M=D 0;JMP ```