マージ ソート アルゴリズムを実装する 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;
}
私の問題は、サブルーチン行をステップ実行しているときに、最後から 2 番目の行 (jr ra) に到達するとクラッシュしてコード 060 で終了し、gdb が次のメッセージを表示することです。
Warning: GDB can't find the start of the function at 0x400730.
GDB is unable to find the start of the function at 0x400730
and thus can't determine the size of that function's stack
frame. This means that GDB may be unable to access that stack
frame, or the frames below it.
This problem is most likely caused by an invalid program
counter or stack pointer. However, if you think GDB should
simply search farther back from 0x400730 for code which looks
like the beginning of a function, you can increase the range
of the search using the `set heuristic-fence-post' command.
0x004008a0 in _start
なぜそれが起こるのか分かりません。に格納されているアドレスの問題か、スタック割り当ての誤りか、C と MIPS コードの間のリンケージが間違っている可能性があると思いますが、ra
何が間違っているのかわかりません。
以下は、merge_sort の MIPS コードです。
基本ケースでは、コードは の行まで実行されbeq t1, zero, SALIDA
、次に にジャンプしSALIDA
て終了します。そのため、コードのその部分を貼り付けるだけです (SALIDA はスペイン語で終了を意味します:P)。
#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