I am trying to implement a recursive modular exponentiation program in MIPS assembly. The program lets the user input three positive numbers x, n and p, and outputs (x^n) mod p. I was able to write the code for it in Java, but I am having a difficult time converting that code to MIPS Assembly. Here is my Java code:
int modPow(int x, int n, int p) {
x = x%p;
if (n == 0)
return 1;
else if (n == 1)
return x;
else if (n%2 == 0)
return modPow(x*x%p, n/2, p);
else
return x*modPow(x, n-1, p)%p;
}
I realize that my biggest issue is calling methods in MIPS, especially recursively. Here is what I have so far:
.text
main:li $v0, 5 #store x in $v0
syscall
move $s0, $v0 #move x to $s0
li $v0, 5 #store n in $v0
syscall
move $s1, $v0 #move n to $s1
li $v0, 5 #store p in $v0
syscall
move $s2, $v0 #move p to $s2
div $s0, $s2
mfhi $s0 #x = x % p
bne $s1, $zero, L1 #Branch to first ElseIf if !(n==0)
li $a0, 1 #return value stored as 1
li $v0, 1 #output 1 (what is stored in $a0)
syscall
L1: li $t0, 1 #$t0 = 1
bne $s1, $t0, L2 #Branch to second ElseIf if !(n==1)
move $a0, $s1 #$a0 = n
li $v0, 1 #output n (stored in $a0)
syscall
L2: li $t0, 2 #t0 = 2
div $s1, $t0
mfhi $t0 #$t0 = n % 2
bne $t0, $zero, L3 #Branch to else if !(n%2==0)
mflo $s1 #$s1 = floor(n/2)
mult $s0, $s0 #x * x
mfhi $s0 #x = x * x
div $s0, $s2
mfhi $s0 #$s0 = (x * x) % p
jal main
L3: li $t0, 1 #$t0 = 1
sub $s1, $t0 #n = n-1
jal main
mult $s0, $a0 #x * mod(x, n-1, p)
mfhi $s0 #x = x * mod(x, n-1, p)
div $s0, $s2
mfhi $a0 #x = x * mod(x, n-1, p) % p stored in $a0
li $v0, 1
syscall
I use syscall instructions to take the input from the user and to output things to the user. Doing most of the arithmetic is simple enough, most of my trouble is with these method calls, especially in recursion. Can anyone help me?