实验要求
将一个简单的C程序汇编成LoongArch或RISC-V汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用
实验内容
1编写C语言代码
int Add(int x, int y)
{
return x + y;
}
int main(void)
{
int z = Add(2,3);
return 0;
}
2编译成RISC-V汇编代码
版本:RISC-V rv32gc clang 15.0.0
Add:
addi sp, sp, -16 # sp = sp-16 sp为栈顶指针,分配16字节的栈空间
sw ra, 12(sp) # 将ra的内容保存到sp+12的地址中
sw s0, 8(sp) # 将s0的内容保存到sp+8的地址中
addi s0, sp, 16 # s0 = sp +16
sw a0, -12(s0) # 将a0的内容保存到s0-12的地址中
sw a1, -16(s0) # 将s0的内容保存到s0-16的地址中
lw a0, -12(s0) # 将s0-12中的内容保存到a0中
lw a1, -16(s0) # 将s0-16中的内容保存到a1中
add a0, a0, a1 # x[a0] = x[a0] + x[a1]
lw ra, 12(sp) # 将sp-12中的内容保存到ra中
lw s0, 8(sp) # 将sp-8中的内容保存到s0中
addi sp, sp, 16 # 恢复栈顶指针sp
ret # 跳转到main函数中call Add的下一句指令
main:
addi sp, sp, -32
sw ra, 28(sp) # 将ra的内容保存到sp+28的地址中
sw s0, 24(sp) # 将s0的内容保存到sp+24的地址中
addi s0, sp, 32 # s0 = sp +32
li a0, 0 # a0 = 0
sw a0, -20(s0) # 将a0的内容保存到s0-20的地址中
sw a0, -12(s0) # 将a0的内容保存到s0-12的地址中
li a0, 2 # a0 = 2
li a1, 3 # a1 = 3
call Add # 跳转到Add函数
mv a1, a0 # a1 = a0
lw a0, -20(s0) # 将s0-20中的内容保存到a0中
sw a1, -16(s0) # 将a1的内容保存到s0-16的地址中
lw ra, 28(sp) # 将sp-28中的内容保存到ra中
lw s0, 24(sp) # 将sp-24中的内容保存到s0中
addi sp, sp, 32 # sp = sp +32
ret # 返回