Linux操作系统Lab1

yalooyu 2023-03-11 14:11:09

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

一、RISC-V环境安装

安装编译环境

sudo apt install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev git libncurses5-dev

安装RISC-V

git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain/
./configure --prefix=/opt/riscv --with-arch=rv64imafdc
sudo make linux -j$(nproc)
export PATH=/opt/riscv/bin:/opt/qemu/bin:$PATH

测试

riscv64-unknown-linux-gnu-gcc -v

二、编译

使用vim编写test.c文件

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

使用命令编译成汇编代码

riscv64-unknown-linux-gnu-gcc -S test.c -o test.s

汇编代码分析

	.file	"test.c"
	.option nopic
	.attribute arch, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"
	.attribute unaligned_access, 0
	.attribute stack_align, 16
	.text
	.align	1           #对齐
	.globl	g           #声明g为全局符号
	.type	g, @function #将g定义为一个函数
g:
	addi	sp,sp,-32   #修改栈指针sp=sp-32,push
	sd	s0,24(sp)   #把s0保存到sp+24,s0表示帧指针fp
	addi	s0,sp,32    #栈底保存到s0,s0=sp+32
	mv	a5,a0       #将a0存放的参数值存入a5
	sw	a5,-20(s0)  #将a5中的字保存到s0-20
	lw	a5,-20(s0)  #将s0-20的字存入a5
	addiw	a5,a5,3     #a5=a5+3
	sext.w	a5,a5       #将a5标记为扩展字
	mv	a0,a5       #将a5的值返回a0
	ld	s0,24(sp)   #恢复s0
	addi	sp,sp,32    #恢复sp
	jr	ra          #跳转到ra地址返回
	.size	g, .-g
	.align	1           #对齐
	.globl	f           #声明f为全局符号
	.type	f, @function #将f定义为一个函数
f:
	addi	sp,sp,-32   #修改栈指针sp=sp-32,push
	sd	ra,24(sp)   #将ra值保存到sp+24
	sd	s0,16(sp)   #将s0值保存到sp+16
	addi	s0,sp,32    #栈底保存到s0,s0=sp+32
	mv	a5,a0       #将a0存放的参数值存入a5
	sw	a5,-20(s0)  #将a5中的字保存到s0-20
	lw	a5,-20(s0)  #将s0-20的字存入a5
	mv	a0,a5       #将a5的值返回a0
	call	g           #调用函数g
	mv	a5,a0       #将返回来的值a0移入a5中
	mv	a0,a5       #将a5中的值移入返回值a0中
	ld	ra,24(sp)   #恢复ra
	ld	s0,16(sp)   #恢复s0
	addi	sp,sp,32    #恢复sp
	jr	ra          #跳转到ra地址返回
	.size	f, .-f
	.align	1           #对齐
	.globl	main        #声明main为全局符号
	.type	main, @function #将main定义为一个函数
main:
	addi	sp,sp,-16   #修改栈指针sp=sp-16,push
	sd	ra,8(sp)    #将ra值保存到sp+8
	sd	s0,0(sp)    #将s0值保存到sp+0
	addi	s0,sp,16    #栈底保存到s0,s0=sp+16
	li	a0,8        #赋值a0=8
	call	f           #调用函数f
	mv	a5,a0       #将返回来的值a0移入a5中
	addiw	a5,a5,1     #a5=a5+1
	sext.w	a5,a5       #将a5标记为扩展字
	mv	a0,a5       #将a5的值返回a0
	ld	ra,8(sp)    #恢复ra
	ld	s0,0(sp)    #恢复s0
	addi	sp,sp,16    #恢复sp
	jr	ra          #跳转到ra地址返回
	.size	main, .-main
	.ident	"GCC: () 12.2.0"
	.section	.note.GNU-stack,"",@progbits

 

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

571

社区成员

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

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