You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIPS升序冒泡排序改降序后出现异常输出,求原因解释

Why does reversing the operands in bgt cause an abnormal value in my MIPS bubble sort?

Problem Description

As a MIPS beginner, I have a working ascending bubble sort code:

.data 
nums: .word 10 
elems: .word 23, 42, 54, 10, 56, 78, 15, 43, 21, 87 
space: .asciiz " " 
end: .asciiz "The end." 

.text 
la $s0, elems 
lw $t4, nums 

reset: 
li $t0, 0 #offset 
li $t5, 0 #count up to nums 

loop: 
add $s1, $s0, $t0 
lw $s3, ($s1) 
addi $t1, $t0, 4 
add $s2, $s0, $t1 
lw $s4, ($s2) 
bgt $s3, $s4, swap 

next: 
addi $t5, $t5, 1 
addi $t0, $t0, 4 
beqz $t4, exit 
beq $t5, $t4, nummin 
j loop 

nummin: 
subi $t4, $t4, 1 
j reset 

swap: 
sw $s3, ($s2) 
sw $s4, ($s1) 
j next 

exit: 
li $t0, 0 
li $t1, 0 

loop2: 
li $v0, 1 
add $t2, $s0, $t1 
lw $a0, ($t2) 
syscall 
li $v0, 4 
la $a0, space 
syscall 
addi $t0, $t0, 1 
addi $t1, $t1, 4 
beq $t0, 10, done 
j loop2 

done: 
li $v0, 4 
la $a0, end 
syscall

It outputs the correct ascending result:

10 15 21 23 42 43 54 56 78 87 The end.

But when I reverse the operands in the bgt instruction to bgt $s4, $s3, swap to implement descending sort, I get this abnormal output:

1750335520 87 78 56 54 43 42 23 21 15

Root Cause Analysis

Your original ascending sort code has a hidden out-of-bounds memory access bug that only surfaces when switching to descending order. Here's the breakdown:

  1. Incorrect comparison count in bubble sort
    For an array of n elements, a single bubble sort pass only needs n-1 adjacent comparisons (to avoid accessing beyond the last element). However, your code initializes $t4 to nums (10, the total element count) and runs $t4 comparisons per pass. This means the first pass tries to compare the 10th element (index 9) with a non-existent 11th element (index 10), which points to memory right after your elems array—the start of the space string.

  2. Why ascending sort worked without issues
    The space string is stored as .asciiz " ", which in memory holds the ASCII space value (0x20) followed by a null terminator (0x00). When loaded as a 4-byte word via lw, this becomes 0x20000000 (decimal 1750335520). In your ascending logic (bgt $s3, $s4, swap), you only swap if the current element is larger than the next. Since the last elems element is 87 (far smaller than 0x20000000), the swap condition never triggers. The out-of-bounds access doesn't modify your array, so the output stays correct.

  3. Why descending sort causes the abnormal value
    When you reverse the operands to bgt $s4, $s3, swap, you now swap if the next element is larger than the current. The out-of-bounds value 0x20000000 is way larger than 87, so the swap condition fires:

    • The invalid value 0x20000000 gets written into the last position of elems (index 9).
    • The value 87 overwrites the space string's memory, corrupting your separator.
    • In subsequent bubble sort passes, this extremely large value will be swapped to the front of the array (since descending order prioritizes larger elements first), making it the first printed value.
    • The corrupted space string may cause unexpected formatting, though in your case, the valid sorted elements still appear in order after the abnormal value.

Fix Suggestion

Adjust the comparison count to avoid out-of-bounds access by initializing $t4 to nums - 1 (since we need n-1 comparisons per pass for n elements):

.text 
la $s0, elems 
lw $t4, nums 
subi $t4, $t4, 1  # Subtract 1 to get n-1 comparisons per pass

This ensures each pass only compares valid adjacent elements. Your descending sort will then output the expected result: 87 78 56 54 43 42 23 21 15 10 The end.

内容的提问来源于stack exchange,提问作者NgTriVien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:52:25