为什么此SPIM / MIPS程序用于对数组中的偶数整数求和不起作用?

时间:2019-04-19 11:23:53

标签: assembly mips mips32 spim qtspim

我是MIPS的新手,所以,如果您发现没有意义的内容,那就是原因。

我试图仅对代码中数组的偶数值求和,然后将结果粘贴在$ 10中。我已经包括了到目前为止我写的东西。执行程序时,它挂起并给我一些错误:“在PC = 0x0040001c处发生异常”和“在数据/堆栈中读取的错误地址读取了0x10040000”和“试图在0x80000180处执行非指令”。

.text

.globl main


main:

lui $16,0x1000
lw  $17,0($16)
addiu $16, $16, 4
addiu $18, $0, 2
addiu $19, $0, 32

loop:

beq $16, $19, exit
sll $0, $0, 0
lw  $17,0($16)
sll $0, $0, 0
div $17, $18
mfhi $13
beq $13, $0, even
sll $0, $0, 0
addiu $16, $16, 4
j loop
sll $0, $0, 0

even:

add $10, $10, $17
addiu $16, $16, 4

j loop
sll $0, $0, 0

exit:

sll $0, $0, 0

.data
size: .word 8
array: .word 23, -12, 45, -32, 52, -72, 8, 13   

我在$ 10中得到-56,但结果应该是$ 10中有25。

2 个答案:

答案 0 :(得分:1)

第一期:

我假设lui $16,0x1000的初衷是为了获得用户的内存,以获取大小,数组等,而lw $17,0($16)的大小则变为$ 17

使用

$ 16 = 0x10000000 $ 17 = 0

很明显,其他所有从数组中读取$ 16的内容都是错误的。

如果我使用la $16, size,则会得到:

$ 16 = 0x10010000 $ 17 = 8

其他对数组的读取应该更好。

下一期:

beq $16, $19, exit是'如果$ 16(您当前位于数组中的当前地址)== $ 19(您已将其设置为32,则要退出),因此它不会很快退出,并尝试访问内存不是

其他说明: sll $0, $0, 0没什么大用的$ 0 = 0 << 0-不知道您在想什么

答案 1 :(得分:1)

您的代码有很多问题。
1.您不读取数组或大小来获取数据参数
2.您的循环控制不正确。您使用$ 16(假定为@array并在1k处初始化),添加4并在其达到32时进行测试...我真的建议您不要使用单独的寄存器来计算循环迭代次数和计算数组地址
4.您应该在最后调用exit()(syscall 10),否则模拟器将尝试执行数据并发出“试图在...处执行非指令”的信息。
5.具有许多分支的程序组织很复杂并且容易出错。将循环测试放在最后并反转测试通常可以使代码更清晰。
6.为什么要插入所有这些点(sll $0, $0, 0)?大多数不是必需的,我不建议您使用延迟加载来学习技巧。一旦掌握它,那就是另一回事了。
7.测试数字是否为奇数或什至不需要除法。只需测试其LSB的值即可。

这是一个有效的代码:

.text
.globl main
main:
        la $16,array   # $16==@array
        la $19,size    # $19 =@size
        lw $19,0($19)  # $19=size of array(in words)
        addi $20, $0,0 # i=0
loop:
        lw  $17,0($16)    # $17=*array
        andi $13,$17,1    # get lsb to know is $17 is odd or even
        bne $13, $0, odd  # skip accumulation if $17 is odd
        add $10, $10, $17 # accumulate sum of evens
odd:    
        addiu $16, $16, 4 # array++
        addiu $20,$20,1   # i++
        bne $20, $19, loop# goto loop if i!= size

exit:
        addi $2,$0,10    # write 10 in $v0 ($2) to call
        syscall          # syscall 10 (exit)

.data
size:  .word 8
array: .word 23, -12, 45, -32, 52, -72, 8, 13