阵列在MIPS中排序



,所以我正在研究分配以对MIPS进行分类。要排序的数据在单独的.ASM文件中给出:

.data
.word 3
.word 40
.word 30
.word 70
.text

我决定使用气泡排序。我可以肯定的是,我的算法是正确的,并且似乎可以正确地对数据进行排序。这个项目的有趣之处在于,我们排序的值将以MIDI注释作为测试程序的一种手段(因此,自然而然地,音符应按顺序播放)。当我测试代码时,这很好,但是,我在MIDI音符结束时听到一些奇怪的节拍。我逐步介绍了我的代码,并发现最后,当我预计它的值为3的值时,$ t1(我用来与循环迭代的值进行比较的值)为7。我将$ 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

您的排序算法非常损坏。您尚未注意到这一点,因为它恰好使用您的测试数据获得了正确的答案。它将使用其他测试数据产生错误的答案(例如,我相信您的算法将分类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

,所以我真的不应该问这个问题,而不必再给我的代码。错误非常简单。这似乎有效。

#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:

最新更新