# A recursive factorial function (or so I hope). # The stack frame for each invocation has: # Return-Address (for recursive calls) # Parameter (for recursive calls) # Base of previous frame (for recrusive calls) # In addition # R(100) holds the return address # R(101) holds the parameter # R(102) holds the base of the previous frame (we don't know its # size, so we need to remember it # R(102) holds the return value from the recursive call BUILTIN L(print) L(WELCOME) CALL L(fact) 4 BUILTIN printlnInt RV JUMP 1 L(DONE) LABEL fact # Update the frame pointer MOVE R(102) FP MOVE FP SP # Update the stack pointer BINOP MINUS SP 4 MOVE SP ACC # Fill in the return address MOVE R(100) RA # Fill in the parameter MOVE R(101) A0 # If the parameter is less than 1, we're done CJUMP LT R(101) 1 L(BASECASE) # The recursive case LABEL RECCASE # Put stuff on the stack frame MOVE M(FP) R(100) BINOP MINUS FP 1 MOVE M(ACC) R(101) BINOP MINUS FP 2 MOVE M(ACC) R(102) # Compute the new parameter: R(101) - 1 BINOP MINUS R(101) 1 # And the recusive call CALL L(fact) ACC # Grab the result MOVE R(103) RV # Restore information MOVE R(100) M(FP) BINOP MINUS FP 1 MOVE R(101) M(ACC) BINOP MINUS FP 2 MOVE R(102) M(ACC) # Compute the result BINOP MUL R(103) R(101) MOVE RV ACC JUMP 1 L(ENDfact) # The base case LABEL BASECASE # Set the return value MOVE RV 1 JUMP 1 L(ENDfact) # Clean up after ourselves LABEL ENDfact # Restore the stack pointer MOVE SP FP # Restore the frame pointer MOVE FP R(102) # Return to where we came from JUMP 1 R(100) # Here's a carriage return LABEL CR STRING \n # Were's a welcome message LABEL WELCOME STRING Welcome to factorial\n LABEL DONE END