C MIPS32:递归子例程在;jr ra“;线

C MIPS32:递归子例程在;jr ra“;线,c,merge,mips,C,Merge,Mips,我已经编写了一个实现合并排序算法的MIPS子例程(代码在文章的末尾)。它接收指向数组的指针及其大小。对它进行排序,不要返回任何内容 我一直在调试它,修复了一些错误,由于子例程在达到基本情况(大小为1的数组)之前似乎运行良好,现在我使用gdb和此C代码针对特定情况对其进行调试: #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> extern

我已经编写了一个实现合并排序算法的MIPS子例程(代码在文章的末尾)。它接收指向数组的指针及其大小。对它进行排序,不要返回任何内容

我一直在调试它,修复了一些错误,由于子例程在达到基本情况(大小为1的数组)之前似乎运行良好,现在我使用gdb和此C代码针对特定情况对其进行调试:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

extern void merge_sort(char*, int);

int main(int argc,char **argv){

    char* vector;
    vector = (char*)malloc(sizeof(char));
    if(vector == NULL) printf("error");

    size_t vector_size = 1;
    memcpy(vector,"5",vector_size);

    merge_sort(vector, vector_size);

    int i;
    for(i = 0; i < vector_size; i++){
            printf("%c ", vector[i]);
    }

    printf("\n");
    return 0;
}
我不明白为什么会这样。我认为这可能是由于
ra
中存储的地址有问题,堆栈分配错误,或者C和MIPS代码之间的链接错误,但我不知道我做错了什么

以下是合并排序的MIPS代码:
对于基本情况,代码运行到行
beq t1,zero,SALIDA
,然后跳到
SALIDA
,并完成。所以我只是粘贴了部分代码(SALIDA在西班牙语中的意思是退出:P)

#包括
#包括
#定义SSIZE(56)
#定义O_RA(48)
#定义O_FP(44)
#定义O_总成(40)
#定义O_S3(36)
#定义O_S2(32)
#定义O_S1(28)
#定义O_S0(24)
#定义O_ARG0(SSIZE)
#定义O_ARG1((SSIZE)+4)
.文本
.对齐2
.globl合并\排序
.ent合并排序
合并和排序:
.frame$fp,SSIZE,ra
.设置noreorder
.cpload t9
.设置重新排序
subu sp、sp、SSIZE
sw s0、O_s0(sp)
sw s1、O_s1(sp)
sw s2,O_s2(sp)
sw s3、O_s3(sp)
开关总成,O_总成(sp)
sw$fp,O_fp(sp)
西南ra,O_ra(sp)
移动$fp,sp
sw a0,O_ARG0($fp)
sw a1,O_ARG1($fp)
lw t0,O_ARG1($fp)
addi t1,t0,-1
贝基t1,零,萨利达
萨利达:
lw s0,O_s0($fp)
lw s1,O_s1($fp)
lw s2,O_s2($fp)
lw s3,O_s3($fp)
移动sp,$fp
lw总成,O_总成($fp)
lw$fp,O_fp($fp)
lw ra,O_ra($fp)
添加sp、sp、SSIZE
jr ra
.end merge_排序

我认为您的问题是子例程末尾的以下问题:

lw  $fp, O_FP($fp)    // restores $fp
lw  ra, O_RA($fp)     // restore ra, but $fp isn't pointing to our frame anymore

我想如果你把这些指示颠倒过来,效果可能会更好。

-我真不敢相信是这样。你说得对,现在开始工作了!谢谢
#include <mips/regdef.h>
#include <sys/syscall.h>

#define     SSIZE   (56)
#define     O_RA    (48)
#define     O_FP    (44)
#define     O_GP    (40)
#define     O_S3    (36)
#define     O_S2    (32)
#define     O_S1    (28)
#define     O_S0    (24)
#define     O_ARG0  (SSIZE)
#define     O_ARG1  ((SSIZE) + 4)

.text
.align  2
.globl  merge_sort
.ent    merge_sort

merge_sort:
.frame $fp, SSIZE, ra
.set noreorder
.cpload t9
.set reorder     

subu    sp,sp,SSIZE

sw  s0, O_S0(sp)
sw  s1, O_S1(sp)
sw  s2, O_S2(sp)
sw  s3, O_S3(sp)

sw  gp, O_GP(sp)
sw  $fp, O_FP(sp)
sw  ra, O_RA(sp) 
move    $fp, sp

sw  a0, O_ARG0($fp)
sw  a1, O_ARG1($fp)

lw  t0, O_ARG1($fp)
addi    t1, t0, -1

beq     t1, zero, SALIDA

SALIDA:     
lw  s0, O_S0($fp)
lw  s1, O_S1($fp)
lw  s2, O_S2($fp)
lw  s3, O_S3($fp)

move    sp, $fp
lw  gp, O_GP($fp)
lw  $fp, O_FP($fp)
lw  ra, O_RA($fp) 

addiu   sp, sp, SSIZE

jr  ra

.end    merge_sort
lw  $fp, O_FP($fp)    // restores $fp
lw  ra, O_RA($fp)     // restore ra, but $fp isn't pointing to our frame anymore