思路分析
提到冒泡排序,是我们十分熟悉的一种排序方法,首先我们用伪代码来展示一下这个算法的整体思想,待排序数个数为n
for i=0-n-2
for j=0-(n-i-2)
if(a[j]>a[j+1])
swap(a[j],a[j+1]);
end if
end if
end if
总而言之,思路就是每一轮将所有相邻项比较,前一项大于后一项则交换数值,实现最高项为最大值。然后每下一轮,已经成为最大值的最高项,不再参与交换与运算,总共进行(n-1)轮。
然后我们用C语言来写一下代码,方便后续进行对比(总数量为8个数值)。
C语言源代码:
int p;
for (int i=0;i<7;i++)
{
for (int j=0;j<6-i;j++)
{
if (a[j]>=a[j+1]) //如果前一项大于后一项则交换
{
p =a[j];
a[j]=a[j+1];
a[j+1]=p;
}
}
}
冒泡法上面已经详细叙述过,我这里呢用3号寄存器和4号寄存器的值分别代表C语言循环用到的两个变量i和j,也用此进行限制循环的次数。其中内层循环需要j<n-2-i ,为了方便编码,我选择移项得到j+i<定值,避免了寄存器间的减法运算。
.asm代码与注释展示:
//前24条指令为将待排序数放入指定内存
addi $s0,$0,-1
addi $s1,$0,0
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
addi $s0,$s0,1
addi $s1,$s1,4
sw $s0,128($s1)
//初始化“i”并设置外循环
add $3,$ 3 ,$ 0
addi $s1,$0,28
addi $s2,$0,28
slt $s0,$0,15
beq $s0,$0,15
//初始化“j”并设置内循环
add $4,$0.$0
add $5 $3 $4
slt $s0,$5,$s2
beq $s0,$0,10
//取出数值进行比较并决定是否交换位置,小者靠后放
addi $6,$4,4
lw $s3,128($4)
lw $s4,128($6)
slt $t0,$s3,$s4
beq $t0,$0,2
sw $s3,128($6)
sw $s4,128($4)
//回到内循环上面,相当于内循环的“}”
addi $4,$4,4
beq $0,$0,-10
//回到外循环上面,相当于外循环的“}”
addi $3,$3,4
beq $0,$0,-15
addi $v0,$zero,10
syscall
对应的16进制代码
2010ffff
20110000
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
22100001
22310004
ae300200
1820
2011001c
2012001c
71802a
1200000f
2020
642820
b2802a
12000009
20860004
8c930200
8cd40200
274402a
11000002
acd30200
ac940200
20840004
1000fff4
20630004
1000ffef
2002000a
C