MIPS中的数组排序

时间:2014-03-08 05:06:59

标签: arrays sorting mips

所以我正在进行一项分配,以便在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

2 个答案:

答案 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: