Domanda

Ok,

so I have a main function that does

jal gcd

and I have this code. It's not indenting properly for whatever reason but please bear with me.

Here's my question. For some reason, when only one call to gcd is made (from the main), and gcd doesnt branch because $a1 is 0 and it jumps to exgcd, when $ra, $a1, $a0 are restored, they all hold $sp's address, and not the variables that should be stored from before.

When gcd doesn't branch to exgcd on its first call, i.e $a1 is not 0, then the loading at the end of the recursion works fine and restores the proper variables.

Why does it not work in the first case?

Thank you.

I'd like to add that I understand there's no need to even store the $ra, but I'm still curious why it doesn't work properly.

To try and make my question more clear, why doesn't this code work:

gcd:    addi    $sp, $sp, -12
    sw  $a0, 0($sp)
    sw  $a1, 4($sp)
    sw  $ra, 8($sp)
    addi    $sp, $sp, 12
    lw  $ra, 8($sp) # restore
    lw  $a1, 4($sp)
    lw  $a0, 0($sp)
    jr  $ra

full functions:

gcd:    addi    $sp, $sp, -12
    sw  $a0, 0($sp)
    sw  $a1, 4($sp)
    sw  $ra, 8($sp)

    bne     $a1, $0, not0
    add $v0, $0, $a0
    j   exgcd   
not0:   sltu    $t0, $a1, $a0 # b<a?
    beq $t0, $0, bgta
    sub $t0, $a0, $a1
    add     $a0, $0, $a1
    add $a1, $a0, $0
    j   gcd 
bgta:   sub     $a1, $a1, $a0
    j   gcd
    j   exgcd
exgcd:  addi    $sp, $sp, 12
    lw  $ra, 8($sp) # restore
    lw  $a1, 4($sp)
    lw  $a0, 0($sp)
    jr  $ra
È stato utile?

Soluzione

You allocate some stack space and store the function arguments there, which is fine. When preparing to return, though, you release the stack memory and then try to read what you originally stored on the stack. That's backward. Restore the original value of $sp after your lw instructions.

Don't read from stack locations you've already popped.

You're not reading from the same locations you wrote. If the locations you're reading happen to contain values similar or equal to the values stored in the other locations, then your program might appear to work sometimes, even though it's really broken.

Altri suggerimenti

You modified the address of $sp but try to read back the values with the same offset, you'll have to recalculate the offset

exgcd:  addi    $sp, $sp, 12
    lw  $ra, -4($sp) # restore
    lw  $a1, -8($sp)
    lw  $a0, -12($sp)
    jr  $ra
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top