RISC-V 排序
参考此篇博客
RISC-V编程——冒泡排序
虽然说是冒泡排序,但是实现的貌似是插入排序。。。
进行了一些小优化改动
代码
.data
vector:
.word 12,13,6,9,1,4,3,10,8
.text
sort:
addi sp,sp,-20
sw ra,16(sp) #存数据
sw s7,12(sp)
sw s6,8(sp)
sw s4,4(sp)
sw s3,0(sp)
li a1,9 #n=9
li s3,1 #i=1 (i=0时j-1=-1是无效地址)
la a0,vector #a0=vector的address
mv s5,a0 #s5=vector
mv s6,a1 #s6=n
loop1:
bge s3,s6,exit1 #i>=n,goto exit1
addi s4,s3,-1 #else,j=i-1
loop2:
slli t0,s4,2 #t0=j*4,word
add t0,s5,t0 #t0=vector+j*4
lw t1,0(t0) #t1=vector[j]
lw t2,4(t0) #t2=vector[j+1]
ble t1,t2,exit2 #if vector[j]<=vector[j+1] goto exit2
mv a0,s5 #else,a0=vector,用于swap
mv a1,s4 #a1=j,用于swap
jal ra,swap
addi s4,s4,-1 #j=j-1
j loop2
exit2:
addi s3,s3,1 #i=i+1
j loop1
exit1:
lw s3,0(sp)
lw s4,4(sp)
lw s6,8(sp)
lw s7,12(sp)
lw ra,16(sp)
addi sp,sp,20
jal x0,exit
swap:
slli t0,a1,2
add t0,a0,t0 #vector+k
lw t1,0(t0) #t1=vector[k]
lw t2,4(t0) #t2=vector[k+1]
sw t2,0(t0) #vector[k]=t2
sw t1,4(t0) #vector[k+1]=t0
jalr x0,0(ra) #回去
exit:
其中寄存器 sp
是指向堆栈顶部的指针,通过 addi
指令将其减去20,实际上就是将堆栈顶部向下移动20字节,以留出空间以存储函数的变量和临时数据,a1
存储代表数组长度的 n
,s3
存储循环变量 i
注意指令 jal ra, swap
会将当前地址压入 ra
保存
RV32I通用寄存器功能
通用寄存器共计32个,作用如下
Register | ABI Name | Saver | 作用 |
---|---|---|---|
x0 | zero | — | 硬编码恒为0 |
x1 | ra | Caller | 函数调用的返回地址 |
x2 | sp | Callee | 堆栈指针 |
x3 | gp | — | 全局指针 |
x4 | tp | — | 线程指针 |
x5-7 | t0-2 | Caller | 临时寄存器/ |
x8 | s0/fp | Callee | 保存寄存器/帧指针 |
x9 | s1 | Callee | 保存寄存器 |
x10-11 | a0-1 | Caller | 函数参数/返回值 |
x12-17 | a2-7 | Caller | 函数参数 |
x18-27 | s2-11 | Callee | 保存寄存器 |
x28-31 | t3-6 | Caller | 临时寄存器 |
EntyEnty520~