程序集返回地址不起作用

时间:2012-04-15 16:12:14

标签: assembly mips

我在C:

中有这个功能
int func(int n0, int n){
    if (n > 1){
        int nFinal = func(n0, --n);
        return (nFinal*nFinal) + n0;
    }
    return n0;
}

并希望在大会中对其进行编程。 我有这段代码:

    .data
    .text
    .globl  func
func:
    addi            $29,$29, -4
    sw      $ra,0($29)
    move            $8,$4       
    move            $9,$5       
    ble     $9,1,fim
    sub     $9,$9,1
    move            $5,$9
    jal     func
    move            $4,$11
    jal     quadrado
    add     $11,$2,$8
    j       fim
quadrado:
    mul     $2,$4,$4
    jr      $31
fim:    
    lw      $31,0($29)  
    move            $2,$11
    jr      $31

如果在$ 4和$ 5中传递的参数分别为2和1,我可以看到程序达到ble指令它按预期工作。它跳转到fim标签,从堆栈恢复返回地址并将返回值传递给我的main函数。

问题是参数$ 5的值未定义。它可以是任何给定的值。我相信我的程序的问题是我的main函数的返回地址丢失了,程序无法返回它。我相信wen程序到达jal func指令,main返回地址被jal func指令返回地址替换。

我该如何解决这个问题? (不是要求代码而只是一些指示)

2 个答案:

答案 0 :(得分:1)

  

[...]我相信我的程序的问题是我的main函数的返回地址丢失了,程序无法返回它。我相信wen程序到达jal func指令,main返回地址被jal func指令返回地址替换。

差不多。您在函数开头递减堆栈指针($29 / $sp)以创建空间以保存返回地址($31 / $ra),但之后在最后重新加载返回地址时,你错过了堆栈指针的相应增量 - 你正在查看该值,但实际上并没有从堆栈中弹出它。

答案 1 :(得分:1)

评论您的代码会有很大帮助。你使用临时寄存器可能会使事情更复杂。您只需要使用一个临时寄存器。这是func例程的一点帮助。我假设你可以完成剩下的工作。并且记得在弹出返回地址时移动堆栈指针。

func:
        #push rtn. addr. onto stk
        sw $ra, 0($sp)
        subi $sp, $sp, 4

        #result = arg0
        move $t0, $a0

        #if arg1 <= 1 return arg0           
        ble $a1, 1, rtn

        #call func(arg0, arg1-1)
        subi $a1, $a1, 1
        jal func

        #result = func(arg0, arg1-1)^2 + arg0
        mul $t0, $v0, $v0
        add $t0, $t0, $a0

rtn: