571
社区成员
发帖
与我相关
我的任务
分享实验要求:将一个简单的C程序汇编成LoongArch或RISC-V汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用。
实验平台:Compiler Explorer (godbolt.org),可以在该平台上使用在线汇编
实验过程:本实验采用RISC-V汇编代码

RISC-V寄存器表如下:
以以下C源代码为例:
int add_a_and_b(int a, int b) {
return a + b;
}
int sub_a_and_b(int a,int b){
return a-b;
}
int main() {
return sub_a_and_b(add_a_and_b(2, 3),1);
}
add_a_and_b:
addi sp,sp,-32 //sp为栈顶指针,sp=sp-32
sd s0,24(sp) //s0为栈底指针,保存s0,将s0的值存放到sp+24的位置上
addi s0,sp,32 //s0=sp+32
mv a5,a0 //a5=a0
mv a4,a1 //a4=a1
sw a5,-20(s0) //a5为变量,将a5的值存放到s0-20的位置上
mv a5,a4 //a5=a4
sw a5,-24(s0) //将a5的值存放到s0-24的位置上
lw a4,-20(s0) //将s0-20中的值存放到a4中
lw a5,-24(s0) //将s0-24中的值存放到a5中
addw a5,a4,a5 //a5=a4+a5
sext.w a5,a5 //扩展a5
mv a0,a5 //a0=a5
ld s0,24(sp) //为出栈做准备,恢复栈底,将s0的值存放到sp+24的位置上
addi sp,sp,32 //sp=sp+32
jr ra //pc=ra,返回
sub_a_and_b:
addi sp,sp,-32 //sp=sp-32
sd s0,24(sp) //将s0的值存放到sp+24的位置上
addi s0,sp,32 //s0=sp+32
mv a5,a0 //a5=a0
mv a4,a1 //a4=a1
sw a5,-20(s0) //将a5的值存放到s0-20的位置上
mv a5,a4 //a5=a4
sw a5,-24(s0) //将a5的值存放到s0-24的位置上
lw a4,-20(s0) //将s0-20中的值存放到a4中
lw a5,-24(s0) //将s0-24中的值存放到a5中
subw a5,a4,a5 //a5=a4-a5
sext.w a5,a5 //扩展a5
mv a0,a5 //a0=a5
ld s0,24(sp) //将s0的值存放到sp+24的位置上
addi sp,sp,32 //sp=sp+32
jr ra //返回
main:
addi sp,sp,-16 //建立空栈,sp=sp-16
sd ra,8(sp) //保存返回值,将ra的值放到sp+8的位置中
sd s0,0(sp) //将s0的值放到sp的位置中
addi s0,sp,16 //s0=sp+16
li a1,3 //将立即数3写入a1
li a0,2 //将立即数2写入a0
call add_a_and_b //保存现场,压栈pc指针,调用add_a_and_b函数
mv a5,a0 //a5=a0
li a1,1 //将立即数1写入a1寄存器
mv a0,a5 //a0=a5
call sub_a_and_b //保存现场,压栈pc指针,调用sub_a_and_b函数
mv a5,a0 //a5=a0
mv a0,a5 //a0=a5
ld ra,8(sp) //将sp+8位置中的内容加载到ra中
ld s0,0(sp) //将sp的内容加载到s0中
addi sp,sp,16 //sp=sp+16
jr ra //返回