assembly - 帧指针 MIPS 的使用

标签 assembly mips spim qtspim

我需要将我的代码从堆栈指针转换为仅使用帧指针,我该怎么做?我是 MIPS 的新手。

我在下面有这个递归 C 代码及其 MIPS 代码。我正在使用堆栈指针,如何将其更改为使用帧指针?

这是我的C代码

int fact(int n)
{
    if(n!=1)
     return n*factorial(n-1);
}

    int comb (int n, int k)
    {
    return fact (n) / fact (k) / fact (n - k);
    }

here my MIPS code

comb:           
 sub $sp, $sp, 16
 sw $ra , 0($sp)
 sw $s0, 4($sp) 
 sw $a0, 8($sp) 
 sw $a1, 12($sp)
 jal fact       
 move $s0, $v0  
 lw $a0, 12($sp) 
 jal fact       
 div $s0, $s0, $v0 
 lw $a0, 8($sp) 
 lw $a1, 12($sp) 
 sub $a0, $a0, $a1 
 jal fact       
 div $s0, $s0, $v0 
 move $v0, $s0  
 lw  $ra, 0($sp) 
 lw  $s0, 4($sp) 
 addi $sp, $sp, 16 
 jr $ra         

最佳答案

我发现@markgz 的评论很有趣。他的维基百科链接包含引述:

The frame pointer ($30) is optional and in practice rarely used except when the stack allocation in a function is determined at runtime, for example, by calling alloca().

我一直觉得 $fp 似乎是多余的,但我总是使用它,因为这是我被教导的方式。

无论如何,如果您仍然感兴趣,下面是我如何使用帧指针:

#save $ra $s0, $a0 on stack
addi $sp $sp -4
sw   $fp 0($sp)
move $fp $sp
addi $sp $sp -12
sw   $ra  -4($fp)
sw   $a0  -8($fp)
sw   $s0 -12($fp)

...

#restore and shrink stack
lw $s0 -12($fp)
lw $ra  -4($fp)
lw $fp   0($fp)
addi $sp $sp 16

jr $ra

所以每次扩栈的时候,我都是用stack-pointer保存帧指针的旧值,然后在缩栈的时候恢复帧指针的旧值。

大多数情况下,我只是在每次编写新函数时复制并粘贴这段代码。

关于assembly - 帧指针 MIPS 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23037560/

相关文章:

assembly - 如何在 MIPS Assembly 中执行递归操作?

斐波那契汇编程序

assembly - 为什么 MIPS 堆栈基址是 0x7ffffffc 而不是 0x80000000

assembly - (MIPS)某些汇编指令是否比其他指令更快?

string - Mips如何存储用户输入字符串

c - 如何仅使用移位和加法进行乘法和除法?

gcc - .asciz 和 .string 汇编器指令之间有什么区别?

assembly - MIPS汇编中的两条顺序分支指令?

assembly - SPIM 中的 MIPS 宏出现问题

assembly - 如何转换 Mips 伪指令?