0

我在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指令返回地址代替。

我怎么解决这个问题?(不问代码,只是一些方向)

4

2 回答 2

1

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

差不多。您在函数开始时递减堆栈指针 ( $29/ $sp) 以创建空间来保存返回地址 ( $31/ $ra),但是在最后重新加载返回地址后,您会丢失堆栈指针的相应增量 - - 您正在查看该值,但实际上并未将其从堆栈中弹出。

于 2012-04-15T19:13:27.597 回答
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:
于 2012-04-15T22:25:17.223 回答