linux操作系统分析lab1

文章详细描述了如何将一个简单的C语言程序转化为RISC-V架构的汇编代码,并通过分析汇编指令,探讨了存储程序计算机中函数调用的堆栈框架以及其在执行过程中的作用。
摘要由CSDN通过智能技术生成

实验要求

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

编写待测试代码

// lab1.c
int sum(int a, int b) {
    return a + b;
}
int main() {
    int a = 8;
    int b = 9;
    return sum(a, b);
}

准备交叉编译环境

如果选择的ISA不是x86, 还需要准备相应的gcc和binutils, 才能正确地进行编译。

riscv32(64):

  • apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu

执行命令 riscv64-linux-gnu-gcc -S lab1.c -o test.S得到汇编文件。

汇编代码分析

	.file	"lab1.c"			# lab1.c 文件名
	.option pic					# 生成位置无关代码
	.text						# 下面的代码都是程序的代码段
	.align	1					# 对齐到2的1次方个字节
	.globl	sum					# sum函数是全局的
	.type	sum, @function		# sum函数的类型是函数
sum:							# sum函数的入口
	addi	sp,sp,-32			# 为sum函数的局部变量分配32个字节的栈空间
	sd	s0,24(sp)				# 将s0寄存器的值存储到栈顶+24字节的位置上,保存s0的值
	addi	s0,sp,32			# 将sp+32的值赋值给s0,s0指向sum函数的栈帧
	mv	a5,a0					# 将第一个参数值a0复制到a5寄存器
	mv	a4,a1					# 将第二个参数值a1复制到a4寄存器
	sw	a5,-20(s0)				# 将a5寄存器的值存储到栈顶-20字节的位置上,保存第一个参数
	mv	a5,a4					# 将a4寄存器的值复制到a5寄存器
	sw	a5,-24(s0)				# 将a5寄存器的值存储到栈顶-24字节的位置上,保存第二个参数
	lw	a4,-20(s0)				# 将栈顶-20字节的值加载到a4寄存器
	lw	a5,-24(s0)				# 将栈顶-24字节的值加载到a5寄存器
	addw	a5,a4,a5			# 将a4和a5寄存器的值相加,结果存储到a5寄存器
	sext.w	a5,a5				# 将a5寄存器的值扩展为64位
	mv	a0,a5					# 将a5寄存器的值存储到a0寄存器中,作为函数的返回值
	ld	s0,24(sp)				# 将栈顶+24字节位置上的值存储到s0寄存器中,恢复s0的值
	addi	sp,sp,32			# 释放32字节的栈空间,将sp指针向上移动
	jr	ra						# 跳转到ra寄存器的地址执行,返回调用者
	.size	sum, .-sum			# 设置sum函数的大小
	.align	1
	.globl	main				# main函数可全局调用
	.type	main, @function		# main是一个函数
main:
	addi	sp,sp,-32			# 将栈指针向下移动32个字节,为本地变量和保存寄存器做准备
	sd	ra,24(sp)				# 将ra寄存器的值存储到栈顶+24字节的位置上,保存ra的值
	sd	s0,16(sp)				# 将s0寄存器的值存储到栈顶+16字节的位置上,保存s0的值
	addi	s0,sp,32			# 将sp+32的值赋值给s0,s0指向main函数的栈帧
	li	a5,8					# 将8赋值给a5寄存器
	sw	a5,-24(s0)				# 将a5寄存器的值存储到栈顶-24字节的位置上,保存第二个参数
	li	a5,9					# 将9赋值给a5寄存器
	sw	a5,-20(s0)				# 将a5寄存器的值存储到栈顶-20字节的位置上,保存第一个参数
	lw	a4,-20(s0)				# 将栈顶-20字节的值加载到a4寄存器
	lw	a5,-24(s0)				# 将栈顶-24字节的值加载到a5寄存器
	mv	a1,a4					# 将a4寄存器的值存储到a1寄存器中,作为第二个参数
	mv	a0,a5					# 将a5寄存器的值存储到a0寄存器中,作为第一个参数
	call	sum					# 调用sum函数
	mv	a5,a0					# 将a0寄存器的值存储到a5寄存器中
	mv	a0,a5					# 将a5寄存器的值存储到a0寄存器中,作为函数的返回值
	ld	ra,24(sp)				# 将栈顶+24字节位置上的值存储到ra寄存器中,恢复ra的值
	ld	s0,16(sp)				# 将栈顶+16字节位置上的值存储到s0寄存器中,恢复s0的值
	addi	sp,sp,32			# 释放32字节的栈空间,将sp指针向上移动
	jr	ra						# 跳转到ra寄存器的地址执行,返回调用者
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值