所以我正在进行一项分配,以便在MIPS中对数组进行排序。要排序的数据在单独的.asm文件中给出,如下所示:
.data
.word 3
.word 40
.word 30
.word 70
.text
我决定使用冒泡排序。我相当确定我的算法是合理的,它似乎正确地排序数据。这个项目的有趣之处在于,我们排序的值将作为MIDI音符播放,作为测试程序的一种方式(因此,音符应该按升序播放)。当我测试我的代码时,这非常有效,但是,我在MIDI音符的末尾听到了一些奇怪的节拍。我逐步完成了我的代码并发现,最后,$ t1(我用来比较我的循环迭代器的完整性值)保持值为7,当我预期它保持值为3时。我将$ t1指定为0($ t2),$ t2为0x10010000,我认为它仍然是我的数组的基地址。数组的基地址应该为3,不是吗?
我有点困惑为什么$ t1总共是7 ...任何建议?我在下面列出了所有代码。
#ec2.asm
.include "ec2_data.asm" #must be in the same directory as ec2.asm
#ec2_data.asm: puts some values in the "data segment"
#the first value is the number of values to sort (n)
#the remaining n word values are the data to sort
#the values will be stored in memory as word values starting
# address 0x10010000
j main
#$t2 is hasChanged
#$t3 is itemCount
#$t4 is i, our iterator in the for loop
#$t5 is array[i] (temp)
#$t6 is array[i+1] (temp)
while_label:
beq $t2, $zero, done_sorting #checks to see if the previous iteration switched any values. If not, we are done.
addi $t2, $zero, 0 #initialize hasChanged to 0
addi $t3, $t3, -1 #decrement itemCount by -1
addi, $t0, $t0, 4 #add 4 to the array offset
addi, $t4, $zero, 0 #set our for loop iterator to 0
for_label:
lw $t5, 0($t0) #set a temp value equal to array[i]
lw $t6, 4($t0) #set a temp value equal to array[i+1]
beq $t4, $t3, while_label #for loop: if i = itemcount, we have incremented all the way through our for loop
bge $t6, $t5, skip_swap #if array[i+1] is greater than or equal to array[i], we don't need to swap these values
#swap
sw $t6, 0($t0) #set array[i] equal to array[i+1]
sw $t5, 4($t0) #set array[i+1] equal to the temp value
addi $t2, $t2, 1 #set hasChanged to 1 to indicate that a swap has been made
skip_swap:
addi, $t4, $t4, 1 #increment i by 1 (for loop iterator)
j for_label #keep the for loop going!
main:
#read values
addi $t0, $zero, 0x10010000 #sets $t0 to be the base address of the array
addi $t2, $zero, 1
lw $t3, 0($t0) #stores n in $t3
j while_label
done_sorting:
# adapted from MIDI example
#duration 25 ms
#instrument (whichever)
#volume 64
addi $v0, $zero, 33 # midi out synchronous
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
addi $t1, $t1, 4 # adds four to the array offset in $t1
lw $a0, 0($t2) # stores the first sorted value ( 4($t1) ) in $a0
midi_loop:
beq $t0, $t1, done
addi $t2, $t2, 4
lw $a0, 0($t2)
syscall
addi $t0, $t0, 1
j midi_loop
done:
#addi $v0, $zero, 10 # syscall for exit
#syscall # clean exit
答案 0 :(得分:1)
您的排序算法非常糟糕。您没有注意到,因为它恰好得到了您的测试数据的正确答案。它将与其他测试数据产生错误的答案(例如,我相信您的算法将排序70,40,30到40,30,70。)
但您的问题是$t1
为什么会以7
结束。答案很简单。你写了这个:
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
addi $t1, $t1, 4 # adds four to the array offset in $t1
我们可以看到您将$t2
设置为0 + 0x10010000 = 0x10010000。然后将0($t2)
(= 0x10010000)处的单词加载到$t1
。 0x10010000处的单词为3,因此此时$t1
为3.然后将{4}添加到$t1
,将结果存储在$t1
中。此时$t1
为7.在此之后,您永远不会修改$t1
。
答案 1 :(得分:0)
所以我真的不应该问这个问题,而不是一次性地给我的代码。错误非常简单。这似乎有效。
#ec2.asm
.include "ec2_data.asm" #must be in the same directory as ec2.asm
#ec2_data.asm: puts some values in the "data segment"
#the first value is the number of values to sort (n)
#the remaining n word values are the data to sort
#the values will be stored in memory as word values starting
# address 0x10010000
j main
#$t2 is hasChanged
#$t3 is itemCount
#$t4 is i, our iterator in the for loop
#$t5 is array[i] (temp)
#$t6 is array[i+1] (temp)
while_label:
beq $t2, $zero, done_sorting #checks to see if the previous iteration switched any values. If not, we are done.
addi $t2, $zero, 0 #initialize hasChanged to 0
addi $t3, $t3, -1 #decrement itemCount by -1 WHY
addi, $t0, $zero, 0x10010000 #add 4 to the array offset
addi, $t4, $zero, 0 #set our for loop iterator to 0
for_label:
addi, $t0, $t0, 4
lw $t5, 0($t0) #set a temp value equal to array[i]
lw $t6, 4($t0) #set a temp value equal to array[i+1]
beq $t4, $t3, while_label #for loop: if i = itemcount, we have incremented all the way through our for loop
bge $t6, $t5, skip_swap #if array[i+1] is greater than or equal to array[i], we don't need to swap these values
#swap
sw $t6, 0($t0) #set array[i] equal to array[i+1]
sw $t5, 4($t0) #set array[i+1] equal to the temp value
addi $t2, $t2, 1 #set hasChanged to 1 to indicate that a swap has been made
skip_swap:
addi, $t4, $t4, 1 #increment i by 1 (for loop iterator)
j for_label #keep the for loop going!
main:
#read values
addi $t0, $zero, 0x10010000 #sets $t0 to be the base address of the array
addi $t2, $zero, 1
lw $t3, 0($t0) #stores n in $t3
j while_label
done_sorting:
# adapted from MIDI example
#duration 25 ms
#instrument (whichever)
#volume 64
addi $v0, $zero, 33 # midi out synchronous
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
lw $a0, 0($t2) # stores the first sorted value ( 4($t1) ) in $a0
midi_loop:
beq $t0, $t1, done
addi $t2, $t2, 4
lw $a0, 0($t2)
syscall
addi $t0, $t0, 1
j midi_loop
done: