# This assumes 32-bit RISC-V; Input arg, print factoral
         .data
input:   .asciz "Input: "
answer:  .asciz "Factorial = "
newline: .asciz "\n"

         .text
main:
       # Unfortunately RARS doesn't support command-line program args
       bgtz a0, initialized
       li a7, 4  # PrintString
       la a0, input
       ecall
       li a7, 5  # ReadInt - saves user's int to a0 (return value of ecall)
       ecall
initialized:      
       jal ra, fact
       mv t0, a0  # a0 is result; move to local var., t0
       li a7, 4  # PrintString
       la a0, answer  # load-address (address is ptr to string)
       ecall
       li a7, 1   # PrintInt
       mv a0, t0  # Move local var, t0, to arg, a0
       ecall
       li a7, 4  # PrintString
       la a0, newline  # load-address (address is ptr to string)
       ecall
       li a7, 10  # Exit with program code 0 (success)
       ecall

fact:  addi t0, zero, 2          # immediate 2 needed for "if(n<2)" ; OR: li t0, 2
       bge    a0, t0, elseF      # if n<2 false, ie if n≥2 goto ELSE 
       addi a0, zero, 1          # THEN: create return-value 1, place in reg. a0; OR: li a0, 1 
       jr ra                     # return --this is the end of the "then" clause 
elseF: # Prolog of 'fact' function: Create call frame
       addi sp, sp, -16          # PUSH1: allocate 16 Bytes on the stack 
       sw ra, 8(sp)              # PUSH2: save ra into first allocated word 

       sw a0, 0(sp)              # PUSH3: save my argument (n) into second word 
       addi a0, a0, -1           # Decrement argument (n-1) into a0 for my child 
       jal ra, fact              # call my child procedure
       add t0, a0, zero          # copy return value from my child into t0; OR: mv t0, a0 
                                 # (because I need to restore my own argument into a0) 
       lw a0, 0(sp)              # POP3: restore original arg, a0, from stack

       mul a0, a0, t0            # multiply my own arg a0==n times the return 
                                 # value from my child that I had copied into t0, and 
                                 # place the result into a0, as my own return value 

       # Epilog of 'fact' function: Restore ra; remove call frame
       lw ra, 8(sp)              # POP2: restore ra from stack 
       addi sp, sp, 16           # POP1: dealloc the 16 B that I had allocated 

       jr ra
