【问题标题】:Array sorting in MIPSMIPS 中的数组排序
【发布时间】:2014-03-08 05:06:58
【问题描述】:

所以我正在处理一项在 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

【问题讨论】:

    标签: arrays sorting mips


    【解决方案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

    【讨论】:

    • 哈哈,是的,对不起,我应该编辑我的帖子:P 我刚问完这个问题就发现了,感觉很傻......谢谢你的回复!我也会努力纠正我的排序算法。
    【解决方案2】:

    所以我真的不应该在不给我的代码再次提供一次的情况下问这个问题。错误非常简单。这似乎有效。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多