我的任务是使用MIPS汇编和QTSpim对硬编码的整数数组进行排序和打印。我一直在尝试遵循这里发布的其他类似问题,但我很难理解我现在哪里出错了。我得到“Exception occurred at PC= 0x 00400068 Bad address in data/stack read:0x 10040000”QTSpim高亮显示“[80000180] 0001 d821加27美元,0美元,1美元; 90:移动$k1 $at #保存$at”我对组装还比较陌生,所以任何帮助都非常感谢!
.data
myarray: .word 4, 1, 3, 2, 16, 9, 10, 14, 8, 7
arraysize: .word 10
str1: .asciiz "Unsorted array: "
str2: .asciiz "\nSorted array: "
nline: .asciiz "\n"
.text
.globl main
main:
li $v0, 0
la $t1, myarray #Coping base address of array into $t1
loop1: #Printing unsorted array
bge $t0, 10, sortFlag
lw $t2, 0($t1) # loading word from addrs, then goes to the next addrs
addi $t1, $t1, 4
li $v0, 1 # Syscall to print value
move $a0, $t2
syscall
li $a0, 32 # Syscall number for printing space
li $v0, 11
syscall
addi $t0, $t0, 1 # Incrementing counter
j loop1
sortFlag:
add $t6, $0, $0 # t6 holds flag to determine whether the list is sorted
la $a1, myarray # Sets $a1 to base address of array
sort:
lw $t2, 0($a1) #Sets $t0 to current element in array
lw $t3, 4($a1) #Sets $t1 to next element in array
slt $t5, $t2, $t3 # Sets $t5 if $t0 < $t1
beq $t5, $0, swap #Swaps if $t5 = 1
add $t6, $0, 1 #Check list again if swapped
sw $t2, 4($a1) #Storing greater numbers in higher position in the array
sw $t3, 0($a1) #Storing lesser numbers in lower position in the array
swap:
addi $a1, $a1, 4 #Moves to next location in array
bne $a1, $t6, sort #If $a0 doesn't equal the end of the array, jump to sort
bne $t6, $0, sortFlag #If $t6 = 1, jump to sortFlag
loop2: #Repeated from above to re-print the now sorted array
bge $t7, 10, exit
lw $t4, 0($t1)
addi $t1, $t1, 4
# syscall to print value
li $v0, 1
move $a2 $t4
syscall
li $a2, 32
li $v0, 11
syscall
addi $t7, $t7, 1
j loop2
exit:
li $v0, 10
syscall
2条答案
按热度按时间gajydyqb1#
它告诉您在0x 00400068执行的指令正试图使用非法的内存位置。(只需忽略QtSpim突出显示的内容。)
因此,请使用模拟器来确定哪个指令位于0x 00400068。
一旦知道哪个指令是坏的,就可以确定坏的基址寄存器。
一旦知道哪个基址寄存器是坏的,就可以通过使用调试器观察执行情况来找出它是如何变成那样的。
您用于指向单词的指针的值需要开始对齐,并以4的倍数递增。然而,您正在做这些事情,因此这似乎不是一个问题。
因此,可能是循环没有正确终止,算法继续运行,并最终运行到内存末尾。这个猜测也得到了违规地址0x 10040000的支持。该地址靠近或位于全局数据内存的末尾,通常从01 x 0010000开始。因此,对于10的小数组,你的记忆力不应该达到那么高。
开发和调试提示:
零(有时是1或2)测试边缘情况,所以让它工作应该是一个优先事项。
这种方法将算法研究与开发从汇编研究、开发和编程中分离出来。(您可以研究的主题范围更大,因为算法不受汇编的约束,而且到汇编的转换也不受算法的约束。)这种方法还确保您在汇编中只处理错别字之类的问题-而不是算法问题,这在程序集中更难调试。
另外,寄存器中的变量依赖于模拟器初始化为0,这通常是不好的做法。这种依赖基本上只在非常小的程序中起作用。
zzoitvuj2#
以下是我从该错误消息中收集到的信息(我可能是错的,因为我从未使用过QTspim)
根据使用的寄存器(
$k1
是Linux内核使用的寄存器,$at
是一个临时寄存器,用于实现伪指令),以及源代码中任何地方都没有这条指令,我认为您的某个系统调用出现了问题。现在我想起来了,您在这里忘记了一个逗号:move $a2 $t4
。请尝试修复该问题,然后看看会发生什么情况。