Linux操作系统分析lab1

实验要求

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

实验步骤

1.安装RISC-V交叉编译器
sudo apt-get install gcc-riscv64-linux-gnu
2.编写测试程序lab1.c
vim /tmp/lab1.c

请添加图片描述

3.生成RISC-V汇编代码
riscv64-linux-gnu-gcc -S -o lab1.s lab1.c
4.分析汇编代码

		.file   "lab1.c"		#源文件名
        .option nopic			#生成位置无关代码
        .text
        .align  1				#指定对齐方式
        .globl  g 				#指定g为全局可调用
        .type   g, @function	#指定g为函数
g:
        add     sp,sp,-32		# sp = sp - 32, sp为栈顶指针
        sd      s0,24(sp)		# s0的值保存在sp+24的地址中, s0为栈底指针
        add     s0,sp,32		# s0 = sp + 32
        mv      a5,a0			# a5 = a0
        sw      a5,-20(s0)		# a5的值保存在s0-20的地址中
        lw      a5,-20(s0)		# 将s0-20地址中的值保存在a5
        addw    a5,a5,3			# a5 = a5 + 3
        sext.w  a5,a5
        mv      a0,a5			# g函数的返回a5保存在a0中用于返回
        ld      s0,24(sp)		# s0 = sp + 24,恢复栈底指针原值
        add     sp,sp,32		# 恢复栈顶指针原值
        jr      ra				# 跳转,函数返回

        .size   g, .-g
        .align  1
        .globl  f				# f为全局符号
        .type   f, @function	# f定义为函数
     
f:
        add     sp,sp,-32		# sp = sp - 32, sp为栈顶指针
        sd      ra,24(sp)		# ra的值(返回地址)保存在sp+24的地址中
        sd      s0,16(sp)		# s0的值保存在sp+16的地址中,s0为栈底指针
        add     s0,sp,32		# s0 = sp + 32
        mv      a5,a0			# a5 = a0,保存函数传入进来的的参数
        sw      a5,-20(s0)		# a5的值存放到s0-20指向的地址中
        lw      a5,-20(s0)		# 将s0-20地址中的值存放到a5中
        mv      a0,a5			# a0 = a5保存调用g函数的待传的参数
        call    g				# 调用g函数
        mv      a5,a0			# a5 = a0
        mv      a0,a5			# a0 = a5, f函数的返回值保存在a0中
        ld      ra,24(sp)		# ra = sp + 24, 得到返回地址
        ld      s0,16(sp)		# s0 = sp + 16, 将sp+16的值重新存储到s0栈底指针中,指向main函数的栈空间
        add     sp,sp,32		# sp = sp + 32, 指向main函数栈空间栈顶
        jr      ra				# 函数返回,回到mian函数
        .size   f, .-f
        .align  1
        .globl  main
        .type   main, @function
main:
        add     sp,sp,-16		# sp = sp - 16
        sd      ra,8(sp)		# Mem[sp+8]=ra
        sd      s0,0(sp)		# Mem[sp]=s0,s0为栈底指针
        add     s0,sp,16		# s0=sp+16,main函数栈空间
        li      a0,8			# 保存函数调用的待传参数
        call    f				# 调用f函数
        mv      a5,a0			# a5 = a0, f函数返回值保存到a5中
        addw    a5,a5,1			# a5 = a5 + 1
        sext.w  a5,a5			
        mv      a0,a5			# a0 = a5, 保存main函数的返回值
        ld      ra,8(sp)		# 得到返回地址

        ld      s0,0(sp)		# 恢复栈底指针
        add     sp,sp,16		# 恢复栈顶指针
        jr      ra				# 函数返回
        .size   main, .-main
        .ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值