将带有链表的合并排序从C转换为MIPS

将带有链表的合并排序从C转换为MIPS,c,pointers,mips,mergesort,translate,C,Pointers,Mips,Mergesort,Translate,我正在尝试使用链表在MIPS中实现合并排序算法。我基本上是在翻译这段代码: 然而,我有一些问题。排序列表不完整,就好像它丢失了整个递归分支一样,例如,这是要排序的链表: 4 -> 3 -> 1 -> 2 输出为:1->2->4。然后,当我尝试将列表写入文件时出现错误(0x004003fc的运行时异常:地址超出范围0x00000000)。我猜这是因为我希望打印4个数字,但列表中只有3个数字 我想我需要帮助的地方是MergeSort函数,因为我不完全理解它在指针方面的实际功能。我认为它就是这样做的:

我正在尝试使用链表在MIPS中实现合并排序算法。我基本上是在翻译这段代码: 然而,我有一些问题。排序列表不完整,就好像它丢失了整个递归分支一样,例如,这是要排序的链表: 4 -> 3 -> 1 -> 2 输出为:1->2->4。然后,当我尝试将列表写入文件时出现错误(0x004003fc的运行时异常:地址超出范围0x00000000)。我猜这是因为我希望打印4个数字,但列表中只有3个数字

我想我需要帮助的地方是MergeSort函数,因为我不完全理解它在指针方面的实际功能。我认为它就是这样做的:

它接收指向列表头的指针作为参数。在函数内部,它创建“head”指针,并指向headRef的值(在本例中,&head在main上传递,因此现在函数内部的“head”在main中具有head的地址)。然后它声明两个指针,a和b(在MIPS中,这就像执行a=0和b=0?我不能“声明”寄存器)。然后检查列表中是否有1个或0个元素,如果有则返回。否则,它将列表分割成两个半部分,FrimeBeSead(头,A和B),但这是棘手的标准。此函数不返回任何内容。相反,它修改了指针“a”和“b”,使它们分别指向列表的前半部分和后半部分。在MIPS中,我认为这是两个返回值$v0和$v1。然后它递归地对列表排序,从左边开始,但再次,它不返回任何内容。。。它修改指针“a”和“b”。最后,它更改指向列表头的指针的值,使其指向新的排序列表

由于**ptr和&ptr值太多,我不知道在堆栈上保存什么。这就是我到目前为止所做的,关于这个函数:

# void mergesort(node** headRef)
# input $a0: head of the list
mergesort:
    move    $t0, $s3                # node* head = headRef
    li      $t1, 0                  # node* a
    li      $t2, 0                  # node* b
    # if(head == NULL || head->next == NULL)
    beqz    $t0, mergesort_return
    lw      $t3, node_next($t0)     # $t3 = head->next
    beqz    $t3, mergesort_return

    move    $a0, $t0
    move    $a1, $t1
    move    $a2, $t2
    # save head and $ra
    addi    $sp, $sp, -8
    sw      $t0, 0($sp)
    sw      $ra, 4($sp)
    jal     frontbacksplit
    # restore head and $ra
    lw      $t0, 0($sp)
    lw      $ra, 4($sp)
    addi    $sp, $sp, 8
    # save output results
    move    $t1, $v0                # a now points to the first half + 1 (if odd) of the list (frontRef)
    move    $t2, $v1                # b now points to the second half of the list (backRef)

    # save head, a, b and $ra
    addi    $sp, $sp, -16
    sw      $t0, 0($sp)
    sw      $t1, 4($sp)
    sw      $t2, 8($sp)
    sw      $ra, 12($sp)
    # mergesort(a)
    move    $a0, $t1
    jal     mergesort
    # restore registers and $ra
    lw      $t0, 0($sp)
    lw      $t1, 4($sp)
    lw      $t2, 8($sp)
    lw      $ra, 12($sp)
    addi    $sp, $sp, 16

    # save head, a, b and $ra
    addi    $sp, $sp, -16
    sw      $t0, 0($sp)
    sw      $t1, 4($sp)
    sw      $t2, 8($sp)
    sw      $ra, 12($sp)
    # mergesort(b)
    move    $a0, $t2
    jal     mergesort
    # restore registers and $ra
    lw      $t0, 0($sp)
    lw      $t1, 4($sp)
    lw      $t2, 8($sp)
    lw      $ra, 12($sp)
    addi    $sp, $sp, 16

    move    $a0, $t1
    move    $a1, $t2
    # save head, a, b and $ra
    addi    $sp, $sp, -16
    sw      $t0, 0($sp)
    sw      $t1, 4($sp)
    sw      $t2, 8($sp)
    sw      $ra, 12($sp)
    jal     sortedmerge
    # restore registers and $ra
    lw      $t0, 0($sp)
    lw      $t1, 4($sp)
    lw      $t2, 8($sp)
    lw      $ra, 12($sp)
    addi    $sp, $sp, 16

    move    $s3, $v0        # s3 is the saved head of the original list declared in main

mergesort_return:
    jr      $ra

嗯。。。我做到了。这是一个家庭作业,还没有评分。我希望他们不会认为是我抄的,哈哈

######### uses function frontbacksplit
######### WORKING
# mergesort
# input $a0: head of the list to merge
mergesort:
    li      $t0, 0      # head_one = NULL
    li      $t1, 0      # head_two = NULL
    # base case
    beqz    $a0, mergesort_return
    lw      $t2, node_next($a0)
    beqz    $t2, mergesort_return

    addi    $sp, $sp, -8
    sw      $ra, 0($sp)
    sw      $a0, 4($sp)

    # move $a0, $a0
    move    $a1, $t0
    move    $a2, $t1
    jal     frontbacksplit
    move    $t0, $v0
    move    $t1, $v1

    lw      $ra, 0($sp)
    lw      $a0, 4($sp)
    addi    $sp, $sp, 8


    # mergesort(a)
    addi    $sp, $sp, -16
    sw      $ra, 0($sp)
    sw      $t0, 4($sp)
    sw      $t1, 8($sp)
    sw      $a0, 12($sp)

    move    $a0, $t0
    jal     mergesort   # mergesort(a)
    move    $t9, $v0

    lw      $ra, 0($sp)
    lw      $t0, 4($sp)
    lw      $t1, 8($sp)
    lw      $a0, 12($sp)
    addi    $sp, $sp, 16

    # mergesort(b)
    addi    $sp, $sp, -20
    sw      $ra, 0($sp)
    sw      $t0, 4($sp)
    sw      $t1, 8($sp)
    sw      $a0, 12($sp)
    sw      $t9, 16($sp)

    move    $a0, $t1
    jal     mergesort   # mergesort(b)
    move    $t8, $v0

    lw      $ra, 0($sp)
    lw      $t0, 4($sp)
    lw      $t1, 8($sp)
    lw      $a0, 12($sp)
    lw      $t9, 16($sp)
    addi    $sp, $sp, 20
    # t8 = a, t9 = b

    addi    $sp, $sp, -24
    sw      $ra, 0($sp)
    sw      $t0, 4($sp)
    sw      $t1, 8($sp)
    sw      $a0, 12($sp)
    sw      $t9, 16($sp)
    sw      $t8, 20($sp)

    move    $a0, $t8
    move    $a1, $t9
    jal     merge

    lw      $ra, 0($sp)
    lw      $t0, 4($sp)
    lw      $t1, 8($sp)
    lw      $a0, 12($sp)
    lw      $t9, 16($sp)
    lw      $t8, 20($sp)
    addi    $sp, $sp, 24

    #move   $v0, $v0

    jr      $ra

mergesort_return:
    move    $v0, $a0
    jr      $ra 


######### WORKING
# input $a0: source node (list to split)
# input $a1: front ref (a) $s4
# input $a2: back ref (b)  $s5
# output $v0: frontRef
# output $v1: backRef
frontbacksplit:
    # $a0 = node* source, $a1 = node* frontRef, $a2 = node* backRef
    move    $t0, $a0                # $t0 = source
    move    $t1, $a1                # $t1 = frontRef
    move    $t2, $a2                # $t2 = backRef

    li      $t3, 0                  # node* fast;
    li      $t4, 0                  # node* slow;
    # if(source == NULL)
    beqz    $t0, frontbacksplit_sorted
    lw      $t5, node_next($t0)     # $t5 = source->next
    # if(source->next == NULL)
    beqz    $t5, frontbacksplit_sorted
    # else
    move    $t4, $t0                # slow = source
    lw      $t3, node_next($t0)     # fast = source->next

frontbacksplit_while:
    # while(fast != NULL)
    beqz    $t3, frontbacksplit_endwhile
    lw      $t3, node_next($t3)     # fast = fast->next
    # if(fast != NULL)
    beqz    $t3, frontbacksplit_while
    lw      $t4, node_next($t4)     # slow = slow->next
    lw      $t3, node_next($t3)     # fast = fast->next
    j       frontbacksplit_while

frontbacksplit_endwhile:
    move    $t1, $t0                # frontRef = source
    lw      $t2, node_next($t4)     # backRef = slow->next
    sw      $zero, node_next($t4)   # slow->next = NULL

    move    $v0, $t1
    move    $v1, $t2
    j       frontbacksplit_end

frontbacksplit_sorted:
    move    $v0, $t0                # frontRef = source
    li      $v1, 0                  # backRef = NULL

frontbacksplit_end:
    jr      $ra


############ WORKING
# input $a0: head of the first list
# input $a1: head of the second list
# output $v0: pointer to the head of the merged-sorted list
merge:
    beqz    $a0, merge_return2
    beqz    $a1, merge_return1
    li      $t3, 0          # head_three = NULL

    lw      $t0, node_int($a0)
    lw      $t1, node_int($a1)

    addi    $sp, $sp, -16
    sw      $ra, 0($sp)
    sw      $a0, 4($sp)
    sw      $a1, 8($sp)
    sw      $t3, 12($sp)

    bge     $t0, $t1, merge_else

    # if head_one->num < head_two->num
    lw      $a0, node_next($a0)
    # $a1 already has head_two
    jal     merge
    move    $t0, $v0        # ptr = merge(head_one->next, head_two)
    # restore values
    lw      $ra, 0($sp)
    lw      $a0, 4($sp)
    lw      $a1, 8($sp)
    lw      $t3, 12($sp)

    move    $t3, $a0
    sw      $t0, node_next($t3)
    move    $v0, $t3
    addi    $sp, $sp, 16
    jr      $ra 

merge_else:
    # $a0 already has head_one
    lw      $a1, node_next($a1)
    jal     merge
    move    $t0, $v0        # ptr = merge(head_one->next, head_two)
    # restore values
    lw      $ra, 0($sp)
    lw      $a0, 4($sp)
    lw      $a1, 8($sp)
    lw      $t3, 12($sp)

    move    $t3, $a1
    sw      $t0, node_next($t3)
    move    $v0, $t3
    addi    $sp, $sp, 16
    jr      $ra

merge_return1:
    move    $v0, $a0
    jr      $ra

merge_return2:
    move    $v0, $a1
    jr      $ra 
使用函数frontbacksplit
#########工作
#合并排序
#输入$a0:要合并的列表的标题
合并排序:
li$t0,0#head_one=NULL
li$t1,0#头2=NULL
#基本情况
beqz$a0,合并排序返回
lw$t2,节点\下一个($a0)
beqz$t2,合并排序返回
附加$sp,$sp,-8
西南$ra,0($sp)
sw$a0,4($sp)
#移动$a0,$a0
移动$a1,$t0
移动$a2,$t1
日航前后分裂
移动$t0,$v0
移动$t1,$v1
lw$ra,0$sp
lw$a0,4($sp)
附加$sp,$sp,8
#合并排序(a)
附加$sp,$sp,-16
西南$ra,0($sp)
sw$t0,4($sp)
sw$t1,8($sp)
sw$a0,12($sp)
移动$a0,$t0
日航合并分拣#合并分拣(a)
移动$t9,$v0
lw$ra,0$sp
lw$t0,4($sp)
lw$t1,8($sp)
lw$a0,12($sp)
附加$sp,$sp,16
#合并排序(b)
附加$sp,$sp,-20
西南$ra,0($sp)
sw$t0,4($sp)
sw$t1,8($sp)
sw$a0,12($sp)
sw$t9,16($sp)
移动$a0,$t1
日航合并分拣#合并分拣(b)
移动$t8,$v0
lw$ra,0$sp
lw$t0,4($sp)
lw$t1,8($sp)
lw$a0,12($sp)
lw$t9,16($sp)
附加$sp,$sp,20
#t8=a,t9=b
附加$sp,$sp,-24
西南$ra,0($sp)
sw$t0,4($sp)
sw$t1,8($sp)
sw$a0,12($sp)
sw$t9,16($sp)
sw$t8,20($sp)
移动$a0,$t8
移动$a1,$t9
日航合并
lw$ra,0$sp
lw$t0,4($sp)
lw$t1,8($sp)
lw$a0,12($sp)
lw$t9,16($sp)
lw$t8,20($sp)
附加$sp,$sp,24
#移动$v0,$v0
jr$ra
合并排序返回:
移动$v0,$a0
jr$ra
#########工作
#输入$a0:源节点(要拆分的列表)
#输入$a1:前参考(a)$s4
#输入$a2:后参考(b)$s5
#输出$v0:frontRef
#输出$v1:backRef
前后裂缝:
#$a0=节点*源,$a1=节点*前参考,$a2=节点*后参考
移动$t0,$a0#$t0=源
移动$t1,$a1#$t1=frontRef
移动$t2,$a2#$t2=backRef
li$t3,0#节点*快速;
li$t4,0节点*慢;
#if(source==NULL)
beqz$t0,前后分裂
lw$t5,节点_下一步($t0)#$t5=源->下一步
#如果(源->下一步==NULL)
beqz$t5,前后分裂
#否则
移动$t4,$t0#慢=源
lw$t3,节点_next($t0)#fast=source->next
前向后向裂缝,同时:
#while(快速!=NULL)
beqz$t3,前后夹板
lw$t3,节点_next($t3)#fast=fast->next
#如果(快速!=NULL)
beqz$t3,前后裂
lw$t4,节点_next($t4)#slow=slow->next
lw$t3,节点_next($t3)#fast=fast->next
j前后裂
前后劈裂时:
移动$t1,$t0#frontRef=源
lw$t2,节点_next($t4)#backRef=slow->next
sw$zero,node_next($t4)#slow->next=NULL
移动$v0,$t1
移动$v1,$t2
j前后裂端
前向后向裂缝(已排序):
移动$v0,$t0#frontRef=源
li$v1,0#backRef=NULL
前后劈裂端:
jr$ra
############工作
#输入$a0:第一个列表的标题
#输入$a1:第二个列表的标题
#输出$v0:指向合并排序列表的标题的指针
合并:
beqz$a0,合并返回2
beqz$a1,合并返回1
li$t3,0#头三=空
lw$t0,节点内部($a0)
lw$t1,节点内部($a1)
附加$sp,$sp,-16
西南$ra,0($sp)
sw$a0,4($sp)
sw$a1、8($sp)