linux操作系统_lab1

雨境迷踪 2023-03-14 19:34:42

实验要求

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

编写 C 语言程序

#include<stdio.h>

int div(int a, int b) {
    if(b == 0) return -1;
    return a / b;
}

int main() {
    int a = 2024;
    int b = 2;
    return div(a, b);
}

使用如下指令将其汇编成RISC-V汇编代码

riscv64-linux-gnu-gcc -S -o hello.s hello.c

 

.file "test.c"              // 文件名

.option pic                 // 选择代码生成选项

.text                       // 代码段开始

.align 1                    // 数据对齐到 2 的 1 次方,也就是 1 个字节

.globl div                  // 全局符号定义

.type div, @function        // 定义函数类型为 @function

div:                        // 定义函数名
 addi sp,sp,-32             // 分配栈空间
 sd s0,24(sp)               // 保存 s0 到栈中
 addi s0,sp,32              // 设置 s0 为当前栈顶地址

 mv a5,a0                   // 将第一个参数 a0 复制到 a5 中
 mv a4,a1                   // 将第二个参数 a1 复制到 a4 中
 sw a5,-20(s0)              // 将 a5 中的值存储在 s0 帧中的 -20 位置
 mv a5,a4                   // 将 a4 中的值移动到 a5 中
 sw a5,-24(s0)              // 将 a5 中的值存储在 s0 帧中的 -24 位置
 lw a5,-24(s0)              // 从 s0 帧的 -24 位置加载一个 32 位值到 a5 中
 sext.w a5,a5               // 把 a5 中的 32 位值符号扩展为 64 位,并将结果存储回 a5

 bne a5,zero,.L2            // 如果 a5 不等于 0,跳转到 .L2 标签

 li a5,-1                   // 如果 a5 等于 0,将 -1 存储到 a5 中
 j .L3                      // 无条件跳转到 .L3 标签

.L2:
 lw a5,-20(s0)              // 从 s0 帧的 -20 位置加载一个 32 位值到 a5 中
 mv a4,a5                   // 将 a5 中的值移动到 a4 中
 lw a5,-24(s0)              // 从 s0 帧的 -24 位置加载一个 32 位值到 a5 中
 divw a5,a4,a5              // 将 a4 除以 a5,并将结果存储回 a5
 sext.w a5,a5               // 把 a5 中的 32 位值符号扩展为 64 位,并将结果存储回 a5

.L3:
 mv a0,a5                   // 将 a5 中的值移动到 a0 中
 ld s0,24(sp)               // 从栈中恢复 s0
 addi sp,sp,32              // 回收栈空间
 jr ra                      // 返回地址
 .size div, .-div           // 设置 div 函数的大小

.align 1                    // 数据对齐到 2 的 1 次方,也就是 1 个字节
.globl main                 // 全局符号定义
.type main, @function       // 定义函数类型为 @function

main:
 addi sp,sp,-32             // 分配栈空间
 sd ra,24(sp)               // 保存返回地址
 sd s0,16(sp)               // 保存旧的栈底指针
 addi s0,sp,32              // 更新栈底指针
 li a5,2024                 // 将2024加载到a5寄存器中
 sw a5,-24(s0)              // 将a5寄存器中的值存储到栈帧中的位置-24处
 li a5,2                    // 将2加载到a5寄存器中
 sw a5,-20(s0)              // 将a5寄存器中的值存储到栈帧中的位置-20处
 lw a4,-20(s0)              // 将栈帧中的位置-20处的值加载到a4寄存器中
 lw a5,-24(s0)              // 将栈帧中的位置-24处的值加载到a5寄存器中
 mv a1,a4                   // 将a4寄存器中的值移动到a1寄存器中,作为div函数的第二个参数
 mv a0,a5                   // 将a5寄存器中的值移动到a0寄存器中,作为div函数的第一个参数
 call div                   // 调用div函数
 mv a5,a0                   // 将div函数的返回值移动到a5寄存器中
 mv a0,a5                   // 将a5寄存器中的值移动到a0寄存器中,作为main函数的返回值
 ld ra,24(sp)               // 恢复返回地址
 ld s0,16(sp)               // 恢复旧的栈底指针
 addi sp,sp,32              // 释放栈空间
 jr ra                      // 返回到调用者
 .size main, .-main         // 定义main函数的大小

 

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

571

社区成员

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

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