Linux操作系统_实验二

wzkkkkkkkk 2024-03-14 14:41:12

实验要求:

         将一个简单的C程序汇编成x86或x86-64或ARM64或LoongArch或RISC-V汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用。参考资料https://gitee.com/mengning997/linuxkernel/tree/master/src/assembly

1. 安装环境

    kk@kk:~/Desktop$ sudo apt install gcc-riscv64-linux-gnu
 

2. C语言源代码

    vi test.c

#include<stdio.h>
int add(int a, int b) {
    return a + b;
}
int main() {
    int num = add(3,4);
    return 0;
}

3. 将C语言源代码汇编为RISC-V汇编代码

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

    .file    "test.c"                  ; 指定源文件名为 "test.c"
    .option pic                    ; 设置编译选项,可能是用于生成位置无关代码的选项
    .text                          ; 进入代码段
    .align    1                       ; 对齐方式设置为 2^1 = 2 字节对齐
    .globl    add                     ; 声明全局函数 add
    .type    add, @function           ; 设置函数 add 的类型为函数
add:                              ; 定义函数 add 的起始位置
    addi    sp,sp,-32               ; 分配 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    a4,-20(s0)               ; 将 s0 寄存器指向的地址减去 20 的位置的值加载到 a4 寄存器
    lw    a5,-24(s0)               ; 将 s0 寄存器指向的地址减去 24 的位置的值加载到 a5 寄存器
    addw    a5,a4,a5                ; 将 a4 寄存器和 a5 寄存器的值相加并将结果存入 a5 寄存器
    sext.w    a5,a5                   ; 将 a5 寄存器的低 32 位符号扩展为 64 位
    mv    a0,a5                    ; 将 a5 寄存器的值复制给 a0
    ld    s0,24(sp)                ; 将栈上保存的 s0 寄存器的值恢复到 s0 寄存器
    addi    sp,sp,32                ; 回收栈空间
    jr    ra                        ; 跳转到 ra 寄存器保存的地址,即返回地址,结束函数调用
    .size    add, .-add              ; 设置函数 add 的大小为当前位置减去函数起始位置,即函数大小

    .align    1                       ; 对齐方式设置为 2^1 = 2 字节对齐
    .globl    main                    ; 声明全局函数 main
    .type    main, @function          ; 设置函数 main 的类型为函数
main:                             ; 定义函数 main 的起始位置
    addi    sp,sp,-32               ; 分配 32 字节的栈空间
    sd    ra,24(sp)                ; 将 ra 寄存器保存到栈上
    sd    s0,16(sp)                ; 将 s0 寄存器保存到栈上
    addi    s0,sp,32                ; 设置 s0 指向栈顶
    li    a1,4                     ; 将立即数 4 加载到 a1 寄存器
    li    a0,3                     ; 将立即数 3 加载到 a0 寄存器
    call    add                     ; 调用函数 add
    mv    a5,a0                    ; 将函数返回值保存到 a5 寄存器
    sw    a5,-20(s0)               ; 将 a5 寄存器的值保存到 s0 寄存器指向的地址减去 20 的位置
    li    a5,0                     ; 将立即数 0 加载到 a5 寄存器
    mv    a0,a5                    ; 将 a5 寄存器的值复制给 a0
    ld    ra,24(sp)                ; 将栈上保存的 ra 寄存器的值恢复到 ra 寄存器
    ld    s0,16(sp)                ; 将栈上保存的 s0 寄存器的值恢复到 s0 寄存器
    addi    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        

 

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

571

社区成员

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

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