In: Computer Science
Write a recursive ARM Assembly program that takes two integers as input and outputs the greatest common divisor.
*I am using Eclipse DS-5 Community Workspace with A64 Instruction Set)
Use the following algorithm:
// Given two integers m and n:
if (m < n)
gcd(n, m)
if n is a divisor of m
gcd(m, n) = n
else
gcd (m, n) = gcd (n, m % n)
Your program must be recursive. You must create a function that
calls itself, and saves variables to the stack, and creates a stack
frame. Your program should restore the stack as it returns from
recursive calls.
Your program should have the following prompt:
"Enter Two Integers: "
Your program should then output the greatest common divisor then terminate.
Sample Test Cases
Enter Two Integers: 0 37
37
Enter Two Integers: 1 37
1
Enter Two Integers: -1 37
1
Enter Two Integers: 5 75
5
Enter Two Integers: -10 -100
10
Enter Two Integers: -10 100
10
Note: gcd(0,0) will not be tested.
CODE
                .text
        .globl  main
main:
        sub     $sp,$sp,12      # push stack
        sw      $ra,4($sp)      # save return address
        li      $v0,4       # Ready for string output
        la      $a0,pow     # Load address of pow
        syscall         # Print string
        
        li $v0,5        # Ready for integer input
        syscall         # Read integer from console
        move $t2,$v0    # Move into to $t2 temporarily
                
        li      $v0,4       # Ready for string output
        la      $a0,bas     # Load address of bas
        syscall         # Print string
        
        li $v0,5        # Ready for integer input
        syscall         # Read integer from console
        move $a0,$t2    # Move into to $a0
        move $a1,$v0    # Move power integer to $a1
        
        jal euc
        sw      $v0,8($sp)
# print the result
        
        li      $v0,4
        la      $a0,str
        syscall
        li      $v0,1
        lw      $a0,8($sp)
        syscall
        
        lw      $ra,4($sp)      # restore return address
        add     $sp,$sp,12      # pop stack
        jr      $ra
        .data
str:                    # label of address containing a string
        .asciiz "GCD = "  # Assembly directive used to create a null terminated ASCII string
bas:                    # label of address containing a string
        .asciiz "Enter second integer = "  # Assembly directive used to create a null terminated ASCII string
pow:                    # label of address containing a string
        .asciiz "Enter first integer = "  # Assembly directive used to create a null terminated ASCII string
        
        .text
euc:
        sub     $sp,$sp,8       # push stack
        sw      $ra,4($sp)      # save return address
        bne $a1, $zero, L1 # if b!=0 then exit
        add     $v0,$zero,$a0   # return a0
        add     $sp,$sp,8       # pop stack
        jr      $ra             # return to calling procedure
L1:
        move $t4,$a1         # set up c = b
        rem $a1,$a0,$a1      # b = a % b
        move $a0,$t4         # a = c
        jal euc            # recurse
        lw      $ra,4($sp)      # restore previous return addr
        move $v0,$a0    # Move a to $v0
        add     $sp,$sp,8       # pop stack
        jr      $ra             # return to calling procedure