无法确定MARS中的MIPS错误:错误:程序计数器值无效:0x00000000 Go:执行因错误而终止

时间:2017-02-10 15:05:52

标签: assembly mips

我正在尝试将这个简单的C片段翻译成MIPS:

int leaf_example(int g, int h, int i, int j) {
    int f;
    f = (g + h) - (i + j);
    return f;
}

这是我的MIPS代码:

.text
    main:
        leaf:
            addi $sp, $sp, -8   #adjust stack to make room for 3 items
            sw $t1, 8($sp)      #save register $t1 for use in memory location 8
            sw $t0, 4($sp)      #save register $t0 for use in memory location 4
            sw $s0, 0($sp)      #save register $s0 for use in memory location 0

            add $t0, $a0, $a1   #register $t0 contains $a0 + $a1
            add $t1, $a2, $a3   #register $t1 contains $a2 + $a3
            sub $s0, $t0, $t1   #$t0 = $t0 - $t1 -> $t0 = ($a0 + $a1) - ($a2 + $a3)

            add $v0, $s0, $zero #copy $s0 to return register $v0

            #Before returning, we restore three original values of registers we pushed onto stack by popping them
            lw $s0, 0($sp)      #restore register $s0 for caller
            lw $t0, 4($sp)      #restore register $t0 for caller
            lw $t1, 8($sp)      #restore register $t1 for caller
            addi $sp, $sp, 8    #adjust stack to delete 3 items

            jr $ra          #jump back to calling routine

然而,当我编译并尝试运行它时,它给了我这个错误:

“错误:程序计数器值无效:0x00000000

Go:执行因错误而终止。“

我根本不明白这个错误。有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:1)

似乎MARS将注册$ra初始化为0x00000000并使用jr $ra,该程序跳转到0x00000000,这被视为无效。

我想你应该在leaf之后编写一些调用函数main:(然后通过system call no.10退出)的代码来测试你的函数。

答案 1 :(得分:0)

实际上你不需要保存和恢复$t0,$t1因为如果调用函数不使用那些寄存器, 保存和恢复它们的努力被浪费了。为了避免这种浪费,MIPS进行了划分 注册到保留和非保留的类别。保留的寄存器包括$s0 – $s7(因此保存了它们的名称)。非保留寄存器 包括$t0 – $t9(因此他们的名字,临时)。一个函数必须保存和 恢复它希望使用的任何保留寄存器,但它可以更改 非保留的寄存器是自由的。

.text
main:

        addi $a0,$0,1       #argument 0 = 1
        addi $a1,$0,2       #argument 1 = 2
        addi $a2,$0,3       #argument 2 = 3
        addi $a3,$0,4       #argument 3 = 4
        jal  leaf           # call function leaf
        add  $s0,$v0,$zero  # return value

        li $v0,10
        syscall


    leaf:
        addi $sp, $sp, -12  #adjust stack to make room for 3 items
        sw $s0, 8($sp)      #save register $t1 for use in memory location 8
        sw $t0, 4($sp)      #save register $t0 for use in memory location 4
        sw $t1, 0($sp)      #save register $s0 for use in memory location 0

        add $t0, $a0, $a1   #register $t0 contains $a0 + $a1
        add $t1, $a2, $a3   #register $t1 contains $a2 + $a3
        sub $s0, $t0, $t1   #$t0 = $t0 - $t1 -> $t0 = ($a0 + $a1) - ($a2 + $a3)

        add $v0, $s0, $zero #copy $s0 to return register $v0

        #Before returning, we restore three original values of registers we pushed onto stack by popping them
        lw $t1, 0($sp)      #restore register $s0 for caller
        lw $t0, 4($sp)      #restore register $t0 for caller
        lw $s0, 8($sp)      #restore register $t1 for caller
        addi $sp, $sp, 12    #adjust stack to delete 3 items

        jr $ra         #jump back to calling routine

改进版。

 .text
 main:

        addi $a0,$0,2       #argument 0 = 2
        addi $a1,$0,3       #argument 1 = 3
        addi $a2,$0,4       #argument 2 = 4
        addi $a3,$0,5       #argument 3 = 5
        jal  leaf           # call function leaf
        add  $s0,$v0,$zero  # return value

        li $v0,10
        syscall


    leaf:
        addi $sp, $sp, -4   #adjust stack to make room for 3 items
        sw $s0, 0($sp)      #save register $t1 for use in memory location 8


        add $t0, $a0, $a1   #register $t0 contains $a0 + $a1
        add $t1, $a2, $a3   #register $t1 contains $a2 + $a3
        sub $s0, $t0, $t1   #$t0 = $t0 - $t1 -> $t0 = ($a0 + $a1) - ($a2 + $a3)

        add $v0, $s0, $0    #copy $s0 to return register $v0

                            #Before returning, we restore three
                            #original values of registers we pushed
                            #onto stack by popping them

        lw $s0, 0($sp)      #restore register $t1 for caller
        addi $sp, $sp, 4    #adjust stack to delete 3 items

        jr $ra              #jump back to calling routine