1

I'm writing a function that should return the square root of a perfect square recursively as part of a longer assignment.

I was following this mathematical method before I reverted to an even simpler algorithm to see if the error would repeat itself and it did.

The following code:

.data

prompt: .asciiz "num2sqrt: "

.text
.globl main
    
sqrt:
    # save return address & t0
    addi    $sp, $sp, -8
    sw  $ra, 0($sp)
    sw  $t0, 4($sp)
    
    # t0 = n
    move $t0, $a0
    
    # a0 = n/2
    srl $a0, $t0, 1
    jal sqrtRecursor
    
    #restore return address & t0
    lw  $t0, 4 ($sp)
    lw  $ra, 0 ($sp)
    addi    $sp, $sp, 8
    jr  $ra
    
sqrtRecursor:
    # save return address & t1
    addi    $sp, $sp, -8
    sw  $ra, 0($sp)
    sw  $t1, 4($sp)
    
    # square test
    mult    $a0, $a0
    mflo    $t1
    beq     $t1, $t0, returnAnswer
    bne     $t1, $t0, newGuess
    
    #restore return address & t1
    lw  $t1, 4 ($sp)
    lw  $ra, 0 ($sp)
    addi    $sp, $sp, 8
    jr  $ra

returnAnswer:
    move    $v0, $a0
    
newGuess:   
    # t1 = (((x+1)*guess)/x)/2
    # x+1
    addi    $t1, $t0, 1
    # *guess
    mult    $a0, $t1
    mflo    $t1
    # /x
    div $t1, $t0
    mflo    $t1
    # /2
    srl $t1, $t1, 1
    move    $a0, $t1
    jal sqrtRecursor    
    
main:

    #print "Enter num2sqrt: "
    la  $a0, prompt
    li  $v0, 4
    syscall
    
    #input num2sqrt
    li  $v0, 5
    syscall
    move    $s1, $v0
    
    move    $a0, $s1
    jal sqrt
    
    # print result
    move    $a0, $v0
    li  $v0, 1
    syscall
    
    # end
    li  $v0, 10
    syscall

returns the following error on QTSpim:

Can't expand stack segment by 12 bytes to 524288 bytes. Use -lstack # with # > 524288

which then hangs the app for a minute or so.

I've double checked that I'm saving and returning all my return addresses and used variables, and also attempted implementing the same algorithm in Java separately (which worked), but have yet been unable to figure out what I need to fix and where.

I've been able to implement a power function before this so I'm not a complete novice and am asking after putting in approximately 5 hours of research and debugging on this.

It could be a stack management problem or an if/else implementation error from the intuition I have about my own code.

  • 1
    You have a classic stack overflow: silly message but that's what it's telling you. Single step in the debugger, and you'll find it. Use the smallest possible input, that should produce the minimal recursion, then something just slightly larger. On another note, are you sure you need recursion to solve this? In any case, find all the function exit points and make sure they each clean up the stack on their way out. Pay particular attention to how `returnAnswer` and `newGuess` clean up the stack and return to their caller. – Erik Eidt Mar 29 '21 at 23:45
  • Thank you. What solved my problem was this: through single stepping i found out returnAnswer wasn't ending like I had expected. Right after returnAnswer would shift a correct answer into v0, newGuess would run and start recursing through again. I shifted the stack management and return commands under returnAnswer which then solved the problem as the function is now quitting after returnAnswer instead of moving to newGuess and recursing again – Sohaib Baig Mar 30 '21 at 13:04

0 Answers0