Hi. I'm having trouble with a program I am writing in MIPS. This is an assignment, so I'll understand if no one helps. The program has two recursive functions: Power and Multiply. The basic algorithms for each are:

int Power(int base, int expon)
{
       if(expon == 0)
              return 1;
       else return Multiply(base, Power(base, expon-1))
}
 
int Multiply(int multiplicand, int multiplier)
{
       if(multiplier == 0 || multiplicand == 0)
              return 0;
       else if(multiplier > multiplicand)
              return Multiply(multiplier, multiplicand)
       else
              return multiplicand + Multiply(multiplicand, multiplier-1)
}

It seems very simple, but I just can't get it to work. Also, our algorithms may assume the base > 0, the exponent is not negative, and the result will fit in a word. My program is quite long, so here is what I have for just the Power and Multiply functions:

# Power 
# Parameter: t8 = base
# Parameter: t9 = exponent 
# t0 being used
# t1 being used
# Returned value in s7
 
      .text
      .ent Power
Power:
     addi $sp,$sp,-4
     sw $ra,0($sp)
 
 
     li        $v0,4              # "Power("
     la       $a0,power
     syscall
 
     li         $v0,1             # output t8
     move  $a0,$t8
     syscall
 
     li         $v0,4              # ","
     la        $a0,comma
     syscall
 
     li          $v0,1              # output t9
     move   $a0,$t9
     syscall
 
     li          $v0,4              # ")\n"
     la         $a0,cparen
     syscall
 
 
 
 
     beqz     $t9,expIsZero  # test if t9 = 0
expNotZero:
                                       # PARAM: base. stayed same
     addi      $t9,$t9,-1        # PARAM: t9 = expon-1
     jal Power                     # returned value in s7
 
 
     move    $t6,$t8            # PARAM: t6 = base
     move    $t7,$s7            # PARAM: t7 = Power(base,expon-1)
     jal         Multiply
     j           endPower
expIsZero:
     li $s7,1                         # if t9 = 0, return 1
endPower:
 
 
     lw          $ra,0($sp)
     addi       $sp,$sp,4
     j            $ra
     .end
 
 
 
# Multiply
# Parameter: t6 = multiplicand
# Parameter: t7 = multiplier
# t0 being used
# t1 being used
# t2 temporary
# Returned value in s6
 
        .text
        .ent Multiply
Multiply:
     addi         $sp,$sp,-4       # allocate space on stack for $ra
     sw           $ra,0($sp)       # save the return address on the stack
 
     li              $v0,4               # " "
     la             $a0,space
     syscall
 
     la             $a0,multiply    # "Multiply("
     syscall
 
     li              $v0,1              # output t6
     move        $a0,$t6
     syscall
 
     li              $v0,4              # ","
     la             $a0,comma
     syscall
 
     li              $v0,1              # output t7
     move       $a0,$t7
     syscall
 
     li              $v0,4               # ")\n"
     la             $a0,cparen
     syscall
 
 
 
     beqz        $t7,IsZero     # test if multiplier = 0
     beqz        $t6,IsZero     # test if multiplicand = 0
elseIf:
     bgt          $t7,$t6,greater   # test if multiplier > multiplicand
else:
                                      # PARAM: multiplicand stays same
     addi         $t7,$t7,-1    # PARAM: multiplier = multiplier - 1
     jal            Multiply       # returned value in s6
 
     add          $s6,$t6,$s6 # return multiplicand +
                                      # Multiply(multiplicand,multiplier-1)
 
     j              endMultiply
greater:
     move        $t2,$t7    # swap the values and
     move        $t7,$t6    # call again
     move        $t6,$t2
     jal             Multiply
     j               endMultiply
IsZero:
     li               $s6,0      # return 0
endMultiply:
 
 
 
 
     lw            $ra,0($sp)
     addi         $sp,$sp,4
     j              $ra
     .end

The output I am getting for Power(3,5) is:

Power(3,5)
Power(3,4)
Power(3,3)
Power(3,2)
Power(3,1)
Power(3,0)
Multiply(3,1)
Multiply(3,0)
Multiply(3,1)
Multiply(3,0)
Multiply(3,1)
Multiply(3,0)
Multiply(3,1)
Multiply(3,0)
Multiply(3,1)
Multiply(3,0)
1

...where 1 the final answer output in Main after Power finishes.
Everything is being called correctly, it just seems to be a logic problem. The program is due friday, so if anyone can lend some help, it would be greatly appreciated. I can post my entire code if needed, it just comes out lookin weird.

Thanks

Recommended Answers

Please post all the code, split into two sections, one for each function.

Jump to Post

All 3 Replies

Please post all the code, split into two sections, one for each function.

.data
array:     .space  40
space:     .asciiz "  "
newline:   .asciiz "\n"
prompt:    .asciiz "Enter 5 sets for Power(X,Y):\n"
set:       .asciiz "Set "
X:         .asciiz "X = "
Y:         .asciiz "Y = "
power:     .asciiz "Power("
multiply:  .asciiz "Multiply("
comma:     .asciiz ","
cparen:    .asciiz ")\n"
separator: .asciiz "==========================================\n\n"
terminated:.asciiz "Program Terminated"
    .text
    .globl  main
#------------------------------------#
#  Main                              #
#------------------------------------#
#  t0     counter                    #
#  t1     ends counter               #
#  a2     address of array           #
#------------------------------------#
main:   
        li      $v0,4          # "Enter 5 sets for Power(X,Y):\n"
        la      $a0,prompt
        syscall
 
        li      $t0,1          # counter for sets.  will input 5 times
        li      $t1,5          # terminates counter
        la      $a2,array      # a2 = address of array
 
Sets:
        li      $v0,4          # "\n"
        la      $a0,newline
        syscall
        la      $a0,space      # "  "
        syscall
        la      $a0,set        # "Set "
        syscall
 
        li      $v0,1          # outputs set number
        move    $a0,$t0
        syscall
 
        li      $v0,4          # "\n"
        la      $a0,newline
        syscall
 
        li      $v0,4
        la      $a0,X          # "X = "
        syscall
 
        li      $v0,5          # Input array($a2) = X
        syscall
        sw      $v0,($a2)
        addi    $a2,$a2,4      # next place in array
 
        li      $v0,4          # "Y = "
        la      $a0,Y
        syscall
 
        li      $v0,5          # Input array($a2) = Y
        syscall
        sw      $v0,($a2)
        addi    $a2,$a2,4      # next place in array
 
 
        addi    $t0,$t0,1      # increment counter
        ble     $t0,$t1,Sets
 
        # array should now look like:  base, expon, base, expon...
 
        li      $v0,4          # "\n"
        la      $a0,newline
        syscall
        la      $a2,array      # a2 = address of array
        li      $t0,1          # reset counter.  will repeat 5 times
 
Repeat: 
        li      $v0,4          # "==========================================\n\n"
        la      $a0,separator
        syscall
        la      $a0,set        # "Set "
        syscall
 
        li      $v0,1          # outputs set number
        move    $a0,$t0
        syscall
 
        li      $v0,4          # "\n" twice
        la      $a0,newline
        syscall
        syscall
 
        lw      $t8,($a2)      # PARAM:  t8 = base
        addi    $a2,$a2,4      # next item in array will be exponent
        lw      $t9,($a2)      # PARAM:  t9 = exponent
 
        jal     Power          # calls Power(t8,t9)
                               # will return the value in s7
 
        li      $v0,1          # print the final value
        move    $a0,$s7
        syscall
 
        li      $v0,4          # "\n"
        la      $a0,newline
        syscall
 
        addi    $a2,$a2,4      # next item in array is next base
        addi    $t0,$t0,1      # increment counter
        ble     $t0,$t1,Repeat
 
        li      $v0,10
        syscall
        .end
 
 
#------------------------------------#
#  Power                             #
#------------------------------------#
#  Param:  t8 = base                 #
#  Param:  t9 = exponent             #
#  t0      being used                #
#  t1      being used                #
#------------------------------------#
#  Returned value in s7              #
#------------------------------------#
 
        .text
        .ent    Power
Power:
        addi    $sp,$sp,-4     # allocate space on stack for $ra
        sw      $ra,0($sp)     # save the return address on the stack
 
        li      $v0,4          # "Power("
        la      $a0,power
        syscall
        li      $v0,1          # output t8
        move    $a0,$t8
        syscall
        li      $v0,4          # ","
        la      $a0,comma
        syscall
        li      $v0,1          # output t9
        move    $a0,$t9
        syscall
        li      $v0,4          # ")\n"
        la      $a0,cparen
        syscall
 
 
 
        beqz    $t9,expIsZero  # test if t9 = 0
expNotZero:
                               # PARAM: base.  stayed same
        addi    $t9,$t9,-1     # PARAM: t9 = expon-1
        jal     Power          # returned value in s7
 
        move    $t6,$t8        # PARAM: t6 = base
        move    $t7,$s7        # PARAM: t7 = Power(base,expon-1)
        jal     Multiply
        j       endPower
expIsZero:
        li      $s7,1          # if t9 = 0, return 1
endPower:
 
 
        lw      $ra,0($sp)     # restore return address
        addi    $sp,$sp,4      # deallocate the space on the stack
        j       $ra            # return to main
        .end
 
 
#------------------------------------#
#  Multiply                          #
#------------------------------------#
#  Param:  t6 = multiplicand         #
#  Param:  t7 = multiplier           #
#  t0      being used                #
#  t1      being used                #
#  t2      temporary                 #
#------------------------------------#
#  Returned value in s6              #
#------------------------------------#
 
        .text
        .ent    Multiply
Multiply:
        addi    $sp,$sp,-4     # allocate space on stack for $ra
        sw      $ra,0($sp)     # save the return address on the stack
 
        li      $v0,4          # "  "
        la      $a0,space
        syscall
        la      $a0,multiply   # "Multiply("
        syscall
        li      $v0,1          # output t6
        move    $a0,$t6
        syscall
        li      $v0,4          # ","
        la      $a0,comma
        syscall
        li      $v0,1          # output t7
        move    $a0,$t7
        syscall
        li      $v0,4          # ")\n"
        la      $a0,cparen
        syscall
 
 
 
        beqz    $t7,IsZero     # test if multiplier = 0
        beqz    $t6,IsZero     # test if multiplicand = 0
elseIf:
        bgt     $t7,$t6,greater# test if multiplier > multiplicand
else:
                               # PARAM: multiplicand stays same
        addi    $t7,$t7,-1     # PARAM: multiplier = multiplier - 1
        jal     Multiply       # returned value in s6
 
        add     $s6,$t6,$s6    # return multiplicand +
                               # Multiply(multiplicand,multiplier-1)
        j       endMultiply
greater:
        move    $t2,$t7        # swap the values and
        move    $t7,$t6        # call again
        move    $t6,$t2
        jal     Multiply
        j       endMultiply
IsZero:
        li      $s6,0          # return 0
endMultiply:
 
 
 
 
        lw      $ra,0($sp)     # restore return address
        addi    $sp,$sp,4      # deallocate the space on the stack
        j       $ra            # return to main
        .end

Okay, here's my entire program. Main, Power, and Multiply are all separated.

The main problem I am seeing is that before your

jal

instructions, you're not passing the parameters, and after the instruction, you're not getting the value out of

$v0

, in fact I don't see you returning to there in your functions, so that might just be your convention.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.20 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.