Linux操作系统分析Lab1

LuckyTeemo 2023-03-14 22:11:01

一、实验任务

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

二、实验步骤

1、安装RISC-V的交叉编译器

sudo apt-get install gcc-riscv64-linux-gnu

2、创建文件1.c

#include<stdio.h>
 
int f(int a,int b) {
        return 3*a + b;
}
 
int main() {
        int a = 1;
        int b = 2;
        int result=f(a,b);
        return 0;
}

 3、把1.c文件编译为1.s文件

riscv64-linux-gnu-gcc -S 1.c -o 1.S

4.查看汇编代码并分析

	.file	"1.c"         
	.option pic
	.text                    
	.align	1
	.globl	f
	.type	f, @function
f:
	addi	sp,sp,-32     //sp = sp - 32, sp为栈顶指针
	sd	s0,24(sp)         // s0的值保存在sp+24的地址中, s0为栈底指针
	addi	s0,sp,32      //s0 = sp + 32
	mv	a5,a0             //a的值放入a5寄存器
	mv	a4,a1             //b的值放入a4寄存器
	sw	a5,-20(s0)        //a的值保存在s0-20的地址中
	mv	a5,a4             //b的值放入a5寄存器
	sw	a5,-24(s0)        //b的值保存在s0-24的地址中
	lw	a4,-20(s0)        //将s0-20地址中的值保存在a4寄存器,a4寄存器保存a的值
	mv	a5,a4             //a5寄存器保存a的值
	slliw	a5,a5,1       //a5寄存器左移一位存入a5,即a5寄存器保存a*2的值
	addw	a5,a5,a4      //a4寄存器的值与a5寄存器值相加存入a5,即a5寄存器保存a*3的值
	sext.w	a5,a5         //a5寄存器的值扩展为64位
	lw	a4,-24(s0)        //将s0-24地址中的值保存在a4寄存器,a4寄存器保存b的值
	addw	a5,a4,a5      //a4寄存器的值与a5寄存器值相加存入a5,即a5寄存器保存a*3+b的值
	sext.w	a5,a5         //a5寄存器的值扩展为64位
	mv	a0,a5             //a5寄存器的值存入a0,即a0的值为a*3+b
	ld	s0,24(sp)         //将栈顶+24字节位置上的值存储到s0寄存器中,恢复s0的值
	addi	sp,sp,32      //释放32字节的栈空间,将sp指针向上移动
	jr	ra                //跳转到ra寄存器的地址执行,返回调用者
	.size	f, .-f
	.align	1
	.globl	main
	.type	main, @function
main:
	addi	sp,sp,-32         //将栈指针向下移动32个字节
	sd	ra,24(sp)             //将ra寄存器的值保存到sp+24字节的位置
	sd	s0,16(sp)             //将r0寄存器的值保存到sp+16字节的位置
	addi	s0,sp,32          //s0 = sp+32
	li	a5,1                  //把a5寄存器的值设置为1,存入了变量a
	sw	a5,-28(s0)            //把a5寄存器的值保存到s0-28的位置,即把变量a加入栈
	li	a5,2                  //把a5寄存器的值设置为2,存入了变量b
	sw	a5,-24(s0)            //把a5寄存器的值保存到s0-24的位置,即把变量b加入栈
	lw	a4,-24(s0)            //将s0-24地址中的值保存在a4寄存器,即a4寄存器保存了变量b
	lw	a5,-28(s0)            //将s0-28地址中的值保存在a5寄存器,即a5寄存器保存了变量a
	mv	a1,a4                 //变量b存入a1寄存器
	mv	a0,a5                 //变量a存入a0寄存器
	call	f                 //调用函数f
	mv	a5,a0                 //将a0寄存器的值存储到a5寄存器中,函数调用结果存入a5
	sw	a5,-20(s0)            //把a5寄存器的值保存到s0-20的位置
	li	a5,0                  //a5寄存器值设置为0
	mv	a0,a5                 //a0的值为1
	ld	ra,24(sp)             //将栈顶+24字节位置上的值存储到ra寄存器中
	ld	s0,16(sp)             //将栈顶+16字节位置上的值存储到s0寄存器中
	addi	sp,sp,32          //sp=sp+32,栈帧退回
	jr	ra                    //跳转到ra寄存器的地址执行,返回调用者
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0"
	.section	.note.GNU-stack,"",@progbits

 

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

571

社区成员

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

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