# MIPS Procedures
# CSC 211
# Original main (and stubs) and macros written by Jerod Weinman

# Because MARS does not heed the .ent directive to specify the entry point,
# we must put the "main" routine first. Otherwise, we'd include main in the
# .globl symbols below and uncomment the following line:
#.ent main

# Ensure the following procedure labels are globally visible
.globl remainder, gcd, gcdtail, count, reverse

.data                             # Arrays and strings for global processing

# The following array has 100 random numbers in [0-10]
numbers: .word 9, 6, 2, 2, 1, 5, 5, 10, 1, 7, 8, 2, 4, 0, 3, 9, 3, 4, 8, 4, 6,
               8, 4, 9, 8, 4, 0, 7, 6, 5, 5, 0, 0, 1, 9, 6, 6, 5, 7, 6, 1, 7,
               7, 2, 8, 0, 0, 2, 0, 4, 2, 6, 8, 4, 0, 4, 8, 6, 2, 10, 6, 6, 0,
               7, 4, 10, 5, 5, 1, 1, 3, 7, 4, 4, 8, 5, 8, 8, 8, 10, 8, 5, 6, 3,
               5, 3, 0, 2, 2, 0, 4, 3, 3, 6, 6, 1, 0, 6, 9, 7

message: .asciiz "Hello, world!"
        
.text                             # Start generating instructions

# Parameterized macros for text output
.macro print_str (%addr)
  la   $a0, %addr                 # Load argument (string pointer) into register
  li   $v0, 4                     # Load "print string" SYSCALL service number
  syscall                         # Make system call (printing string)
.end_macro

.macro putchar (%ch)
  li   $a0, %ch                   # Load argument (ASCII char) into register
  li   $v0, 11                    # Load "print char" SYSCALL service number
  syscall
.end_macro

        
# main        
# Run the assignment procedure(s).
# You may edit anything within main for testing, as it will not be graded
main:
  # Problem 1 (Remainder)
  li   $a0, 24                    # Load arguments into registers
  li   $a1, 7
  jal  remainder                  # Call the procedure
  move $s2, $v0                   # Copy result into saved registers

  # Problem 2 (GCD)
  li   $a0, 66                    # Load arguments into registers
  li   $a1, 24
  jal  gcd                        # Call the procedure
  move $s3, $v0
        
  # Problem 3 (Frequency Count)
  la   $a0, numbers               # Load argument (array pointer, beginning)
  addi $a0, $a0, 32               # Example: shift pointer 8 ints into array
  li   $a1, 10                    # Load argument for length
  li   $a2, 5                     # Load argument for sought      
  jal  count                      # Call the procedure (result is in $v0)

  # Problem 4 (String Reverse)
  print_str(message)              # Invoke macro for output
  putchar('\n')                   # Invoke macro to separate lines ('\n'=0xA)
        
  la   $a0, message               # Load argument (string pointer) into register
  jal  reverse                    # Call the procedure

  print_str(message)              # Invoke macro for output (reversed)
        
        
  li   $v0, 10                    # Load exit SYSCALL service number
  syscall                         # Make system call (terminating program)
# END MAIN



# Problem 1
# DOCUMENT YOUR PROCEDURE HERE (and delete this line)
remainder:
# ADD YOUR CODE HERE (and delete this line)
  jr   $ra                        # Return to caller
#END remainder

        
# Problem 2
# DOCUMENT YOUR PROCEDURE HERE (and delete this line)
gcd:
# ADD YOUR CODE HERE (and delete this line)
  jr   $ra                         # Return to caller
#END gcd


gcdtail:
# ADD YOUR CODE HERE (and delete this line)
  jr   $ra                         # Return to caller
#END gcdtail


# Problem 3
# DOCUMENT YOUR PROCEDURE HERE (and delete this line)
count:
# ADD YOUR CODE HERE (and delete this line)
  jr   $ra                         # Return to caller
#END count


# Problem 5
# DOCUMENT YOUR PROCEDURE HERE (and delete this line)
reverse:
# ADD YOUR CODE HERE (and delete this line)
  jr $ra                           # Return to caller
#END reverse
