Linux操作系统分析-Lab1

qq_38213564 2023-03-14 23:35:52

实验内容

将一个简单的C程序汇编成LoongArch或RISC-V汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用。

riscv汇编指令基础知识:

https://blog.csdn.net/I_O_fly/article/details/127125338

C语言程序

int g(int x){
   return x+3;
}
 
int f(int x){
   return g(x);
}
 
int main()
{
    return f(8)+1;
}

将上述C程序汇编成RISC-V汇编代码

g:
	addi	sp,sp,-32    //sp=sp-32 sp为栈顶指针预留出4个存储空间
	sd	s0,24(sp)        //因为g函数是最内层的函数,它不再调用新的函数,所以这里不再存储返回地址,而是直接将f函数的栈底指针压栈
	addi	s0,sp,32     //s0=sp+32,构造g函数的栈空间,形成g函数的逻辑空栈
	mv	a5,a0            //a5=a0,a0存放的是函数参数8
	sw	a5,-20(s0)       //store指令,将a5的值存放到s0-20指向的位置中
	lw	a5,-20(s0)       //load指令,将s0-20位置中的值存放到a5中
	addiw	a5,a5,3      //a5=a5+3
	sext.w	a5,a5
	mv	a0,a5            //a0=a5,将g函数返回值保存在a0中
	ld	s0,24(sp)        //s0=sp+24,将sp+24的值重新存储到s0栈底指针中,指向f函数的栈空间
	addi	sp,sp,32     //栈顶指针指向f函数栈空间的栈顶
	jr	ra               //无条件跳转,进行函数返回
f:
	addi	sp,sp,-32    //栈顶指针向下增长32个字节位即4个64位留出4个存储空间
	sd	ra,24(sp)        //*(sp+24)=ra,其中ra存放的是main函数的返回地址
	sd	s0,16(sp)        //此时s0中存放的是main函数的栈底指针
	addi	s0,sp,32     //s0=sp+32,构造f函数的栈空间,形成f函数的逻辑空栈
	mv	a5,a0            //a5=a0,a0存放的是函数参数,此处保存一次参数的作用是用来给后面的g函数进行传递参数,此时a5中存放的是8,,可以发现RISC-V使用 寄存器 进行参数传递
	sw	a5,-20(s0)       //w表示是32位的数据,将a5的值存放到s0-20到s0-17指向的32位空间中
	lw	a5,-20(s0)       //load指令,将s0-20位置中的值存放到a5中
	mv	a0,a5            //a0=a5,此时a0保存的是函数参数,为调用g(x)做准备
	call	g            //调用g函数
	mv	a5,a0            //a5=a0
	mv	a0,a5            //a0=a5,将f函数返回值保存在a0中
	ld	ra,24(sp)        //ra=sp+24,获取main函数的返回地址
	ld	s0,16(sp)        //s0=sp+16,将sp+16的值重新存储到s0栈底指针中,指向main函数的栈空间
	addi	sp,sp,32     //指向main函数栈空间栈顶
	jr	ra               //返回到main函数
main:
	addi	sp,sp,-16   //开辟两个64位的空间,分别存储上一个程序的堆栈的返回地址和栈底指针
	sd	ra,8(sp)        //ra存放的是返回地址,将ra存放到sp+8指向的位置中(前面预留的)
	sd	s0,0(sp)        //store指令,s0为栈底指针,将s0的值存放到sp指向的位置中(前面预留的)
	addi	s0,sp,16    //设置main函数的栈底指针,构造main函数的栈空间
	ld	a0,8            //将参数8保存在a0中
	call	f           //调用函数f,f(8)的值会保存在a0中
	mv	a5,a0           //a5=a0,将f(8)的返回值保存在a5中
	addiw	a5,a5,1     //a5=a5+1
	sext.w	a5,a5
	mv	a0,a5           //a0=a5,main函数的返回值保存在a0中
	ld	ra,8(sp)        //获取上一个程序的返回地址
	ld	s0,0(sp)        //栈底指针指向上一个程序的栈空间栈底
	addi	sp,sp,16    //栈顶指针指向上一个程序栈空间栈顶
	jr	ra              //无条件跳转,函数返回

 

...全文
73 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧