###################################################################### # gcd.s --- A MIPS program to compute the greatest common divisor of # two integers using the Euclidean algorithm recursively. # This program is the "manual" compilation of gcd.c. # # For this exercise, you will implement the gcd() function from the # gcd.c program, using a frame. Start you implementation at the # end of this file. ###################################################################### .data pr1: .asciiz "To exit, enter 0 for i's value.\n" pr2: .asciiz "Enter i's value: " pr3: .asciiz "Enter j's value: " rs1: .asciiz "The GCD of " rs2: .asciiz " and " rs3: .asciiz " is " rs4: .asciiz ".\n" ###################################################################### # main ###################################################################### .text .globl main main: sub $sp, $sp, 16 # Push frame and save registers. sw $fp, 16($sp) sw $ra, 12($sp) sw $s0, 8($sp) # i in $s0. sw $s1, 4($sp) # j in $s1. add $fp, $sp, 16 li $v0, 4 # Print exit instruction. la $a0, pr1 syscall while: li $v0, 4 # Prompt for i. la $a0, pr2 syscall li $v0, 5 # Read i. syscall move $s0, $v0 if: beqz $s0, ewhile li $v0, 4 # Prompt for j. la $a0, pr3 syscall li $v0, 5 # Read j. syscall move $s1, $v0 move $a0, $s0 # Compute GCD of i and j. move $a1, $s1 jal gcd move $t0, $v0 # Copy GCD to $t0. li $v0, 4 # Begin printing result string. la $a0, rs1 syscall li $v0, 1 # Print i. move $a0, $s0 syscall li $v0, 4 la $a0, rs2 syscall li $v0, 1 # Print j. move $a0, $s1 syscall li $v0, 4 la $a0, rs3 syscall li $v0, 1 # Print gcd(i, j). move $a0, $t0 syscall li $v0, 4 # Finish printing result string. la $a0, rs4 syscall b while ewhile: li $v0, 0 # Set return value. lw $s1, 4($sp) # Restore registers and pop frame. lw $s0, 8($sp) lw $ra, 12($sp) lw $fp, 16($sp) add $sp, $sp, 16 jr $ra # Return. ###################################################################### # gcd --- Using a frame, implement the gcd() function from # gcd.c below. # # Use the following frame map for this function: # # +----------+ # | $fp | # +----------+ # | $ra | # +----------+ # | $s0 | Store $s0's value here, then use $s0 for i. In what # +----------+ register is i initially? # | $s1 | Store $s1's value here, then use $s1 for j. In what # +----------+ register is j initially? # # Why can't we simply use the registers which hold the values of i # and j at the time the gcd function begins to execute? Why must we # copy these values to $s0 and $s1? # # Source code: # # int gcd(int i, int j) # { # if (j == 0) # return i; # else # return gcd(j, i % j); /* % is the remainder operator. # * The MIPS rem R-format # * instruction performs this # * operation. # */ # } # ###################################################################### .text gcd: