[MIPS程序被卡在嵌套函数上

问题描述 投票:0回答:1

我的程序似乎在Ch的jal指令之后卡在box_1上。我认为这与$ ra被覆盖有关。我该如何解决?

该程序应该是一个简单的比特币矿工。这是图表:

LINK

我正在使用this文章。

我认为解决此问题的方法可能与在堆栈上节省$ ra有关,但这似乎有点不切实际且效率低下吗?我可能做错了。

    .data

    A:      .word   0x87564C0C
    B:      .word   0xF1369725
    C:      .word   0x82E6D493
    D:      .word   0x63A6B509
    E:      .word   0xDD9EFF54
    F:      .word   0xE07C2655
    G:      .word   0xA41F32E7
    H:      .word   0xC7D25631
    W:      .word   0x6534EA14
    K:      .word   0xC67178F2



.text
.globl  main

main:

    li  $s0,0   #loop counter
    li  $s1,64  #loop limit

    main_loop:
        bge $s0,$s1,end_main_loop

            jal box_0
            move    $a0,$v0 #save return value in $a0 to be used as argument by box_1

            jal box_1
            move    $a0,$v0 #

            jal box_2
            move    $a0,$v0 #
            move    $s2,$a0 #will be necessary for the input of box_4 later

            jal box_3
            move    $s3,$v0 #Will be assigned to E later

            jal box_4
            move    $a0,$v0 #

            jal box_5


            ###Assignments

            lw  $a0,G
            la  $a1,H
            sw  $a0,($a1) #Old G goes into new H

            lw  $a0,F
            la  $a1,G
            sw  $a0,($a1)   #Old F goes into new G

            lw  $a0,E
            la  $a1,F
            sw  $a0,($a1)   #Old E goes into new F

            #

            la  $a1,E
            sw  $s3,($a1)   #Output of box_3 goes into new E

            #

            lw  $a0,C
            la  $a1,D
            sw  $a0,($a1)   #Old C goes into new D

            lw  $a0,B
            la  $a1,C

            sw  $a0,($a1)   #Old B goes into new C

            lw  $a0,A
            la  $a1,B

            sw  $a0,($a1)   #Old A goes into new B

            #

            la  $a0,A
            sw  $v0,($a0)   #Output of box_5 goes into new A


            addi    $s0,$s0,1   #increment loop counter





    end_main_loop:

        li  $v0, 10          # terminate program
        syscall


.text
.globl red_boxes

red_boxes:

box_0:

    lw  $t0,W
    lw  $t1,K

    addu    $t0,$t0,$t1 #Wt + Kt

    move    $v0,$t1

    jr  $ra


box_1: 

    move    $t0,$a0     #output of box_0

    jal Ch 
    move    $t1,$v0

    lw  $t3,H

    addu    $t0,$t0,$t1
    addu    $t3,$t0,$t3

    move    $v0,$t3

    jr  $ra

box_2:

    move    $t0,$a0     #output of box_1
    #move   $t1,$a1     #output of Sigma1

    jal Sigma1

    move    $t1,$v0

    addu    $t0,$t0,$t1

    move    $v0,$t0

    jr  $ra

box_3:

    move    $t0,$a0     #output of box_2

    lw  $t1,D

    addu    $t0,$t0,$t1

    move    $v0,$t0

    jr  $ra

box_4:

    move    $t0,$a0     #output of box_2 <----!!

    #move   $t1,$a1     #output of Ma

    jal Ma
    move    $t1,$v0

    addu    $t0,$t0,$t1

    move    $v0,$t0

    jr  $ra

box_5:

    move    $t0,$a0     #output of box_4
    #move   $t1,$a1     #output of Sigma0

    jal Sigma0 
    move    $t1,$v0

    addu    $t0,$t0,$t1

    move    $v0,$t0

    jr  $ra

.text
.globl op_boxes

op_boxes:

Ch:
#           (G&!E) || (F&E)

            lw  $t0,E
            lw  $t1,F
            lw  $t2,G


            and $t1,$t1,$t0 #(F&E)
            not $t0,$t0     #!E
            and $t2,$t2,$t0 #(G&!E)

            or  $t0,$t1,$t2 #(G&!E) || (F&E)

            move    $v0,$t0

            jr  $ra

Sigma1:

            lw  $t0,E

            ror $t1,$t0,6   #rotates E to the right by 6 bits
            ror $t2,$t0,11  # '''           by 11 bits
            ror $t3,$t0,25  # '''           by 25 bits

            addu    $t2,$t2,$t1 # A->6 + A->11
            addu    $t3,$t3,$t2 # (A->6 + A->11) + A->25

            li  $t1,1

            and $t1,$t3,$t1

            move    $v0,$t1

            jr  $ra

Ma:

#           majority = (A&B) | (B&C)   

            lw  $t0,A                      
            lw  $t1,B
            lw  $t2,C

            or $t3, $t0, $t2
            and $t1, $t1, $t3
            and $v0, $t0, $t2

            or $v0, $t1, $v0

            jr  $ra

Sigma0:

#Same as Sigma0 but shifted by different values
            lw  $t0,A

            ror $t1,$t0,2
            ror $t2,$t0,13
            ror $t3,$t0,22

            add $t2,$t2,$t1
            add $t3,$t3,$t2

            li  $t1,1

            and $t1,$t3,$t1

            move    $v0,$t1

            jr  $ra

另外,我使用了addu而不是add,因为有时会出现溢出。它是否正确?这篇文章没有关于溢出的任何内容。

assembly mips
1个回答
1
投票

在堆栈上节省$ ra,但这似乎有点不切实际且效率低下吗?

[如果您确切知道Ch的寄存器是什么(及其所有被调用者的寄存器,这里都不是),那么您可以将$ra保存在那些寄存器之一中,而不是保存在堆栈中以在此处和那里保存周期。

如果使用的是RISC V,则在调用Ch时可以将备用寄存器用作返回地址,然后通过在此处避免$ra,完全不需要保留$ra


如果您真的想优化代码,则有两种方法:

一种是开发程序范围的寄存器分配,因此您不必继续加载和存储这些全局变量,而只需操作寄存器。

((如果程序变得非常大,或者您还想混合使用编译器生成的C代码的调用,这可能很难-因为编译器不一定知道您程序范围内的寄存器分配。但是,如果您将其编写为C调用的子例程,但不回叫C-仅返回C-您仍然可以对整个子例程寄存器进行分配。)

另一种方法是内联所有方法,快速浏览一下看来调用并没有太多重用,因此似乎表明了这种内联。

两种方法都可以组合。


是的,当我们不关心溢出时,addu是适当的。它产生与add相同的位模式,只是放弃了溢出检查。

© www.soinside.com 2019 - 2024. All rights reserved.