如何建立自己的RISC-V编译环境--汇编?

本文详细介绍了如何搭建RISC-V编译环境,包括环境框架、目录结构、Makefile脚本及工具链使用。通过具体示例,如汇编代码生成与链接,帮助读者理解RISC-V编译流程。

如何建立自己的RISC-V编译环境–汇编?

1.RISC-V编译环境框架

这是我RISC-V编译环境的架构:

build  case  common  toolchain
一级目录 二级目录 说明
build - xx.hex、xx.bin、xx.dump & xx.elf生成的目录。
- Makefile 编译脚本。
- add(例子) 生成文件,根据test.c生成的xx.hex、xx.bin、xx.dump & xx.elf
project - 各个目录的源代码。
- add(例子) 放add项目的S文件。
common - 各个项目公用的文件。
- encoding.h /riscv-tests/env目录中的H文件。
- asm.h /riscv-tests/env/p/riscv_test.h文件,只是我改为asm.h。
- asm.ld /riscv-tests/env/p/link.ld文件,用于链接物理地址和汇编,我改名字为asm.ld了。
toolchain - 工具链。我在/riscv-tools/riscv-gnu-toolchain/的工具链上提取了对我有用的部分。

2.各目录内容介绍

2.1 toolchain:工具链目录我不打算介绍,如果有不明白的,可以看我的这个博客:
rocket-chip工具链的编译与使用(https://blog.youkuaiyun.com/a_weiming/article/details/84801051)

2.2 project:这个目录就是放你的项目代码的。每个项目建立一个目录。在这个例子中,我放的是add目录,add的源代码如下(全为汇编代码):
此外,RISC-V汇编不熟悉的可以参考以下链接:
https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
https://mp.weixin.qq.com/s/-syKN0DibKGGPCllaeNqMg
https://mp.weixin.qq.com/s/jyI-SSm_5Gg-KQyjKsIj5Q
https://mp.weixin.qq.com/s/3RHss3vhfK004-TtM8fpeA
https://mp.weixin.qq.com/s/Ln4qBYvSsgRvdiK1IJqI6Q

下面贴图为.section的说明。
在这里插入图片描述

注意,下文中使用“###”形式的均是我添加的注释,原代码中没有。

#*****************************************************************************
# add.S
#-----------------------------------------------------------------------------
#
# Test add instructions.
#

#屏蔽了原来的include "riscv_test.h"
######include "riscv_test.h"
#使用我自己的asm.h
#include "asm.h"

###使用RVTEST_RV32U段内容
RVTEST_RV32U
###使用RVTEST_CODE_BEGIN段内容
RVTEST_CODE_BEGIN
###按2^2字节(4字节)数据对齐
  .align 2
  ###“.option push”伪操作暂时将当前的选项设置保存起来,
  ###从而允许之后使用.option伪操作指定新的选项;
  ###而“.option pop”伪操作将最近保存的选项设置恢复出来重新生效。
  ###通过“.option push”和“.option pop”的组合,便可以在汇编程序中在不影响全
  ###局选项设置的情况下,为其中嵌入的某一段代码特别地设置不同的选项。
  ###意思就是:
  ###在add.S这个汇编文件中,将前面其他.S/.h文件中的配置选项保存起来,
  ###然后在add.S文件中设置一些新的选项,新的选项就是下面的.option norvc
  .option push
  ###伪操作表示接下来的汇编程序不可以被汇编生成16位宽的压缩指令。
  .option norvc

###定义标签asm_start
asm_start:
  ###将0xAAAAAAAA赋给a1
  li   a1, 0xAAAAAAAA
  ###将0x22222222赋给a1
  li   a0, 0x22222222
  ###将a0和a1相加,并出入a2中
  add  a2, a1, a0
  ###将0x7000_0000存入a4中
  lui  a4, 0x70000
  ###将a4的值+4并存入a6中
  addi a6, a4, 4
  ###将a2的结果存到总线为0x7000_0004的memory中
  sw   a2, 0(a6)
  ###将0xFF存到a5中
  li   a5, 255
  ###将a5的结果存到总线为0x7000_0000的memory中,用于停止VCS仿真
  sw   a5, 0(a4)

  ###恢复原选项配置
  .option pop

###使用RVTEST_CODE_END段内容
RVTEST_CODE_END
  
  ###数据段.data:已初始化的C程序全局变量和静态局部变量。
  .data
###使用RVTEST_DATA_BEGIN段内容
RVTEST_DATA_BEGIN

###使用RVTEST_DATA_END段内容
RVTEST_DATA_END

以下的定义在asm.h中有详细的说明。
RVTEST_RV32U
RVTEST_CODE_BEGIN
RVTEST_CODE_END
RVTEST_DATA_BEGIN
RVTEST_DATA_END

2.3 common:这个目录放的是通用的内容,例如asm.h和asm.lk。

2.3.1 encoding.h:这个文件不解释,就是RISC-V各重要CSR寄存器的定义。

2.3.2 asm.h:这个我是根据/riscv-tests/env/p/riscv_test.h文件进行修改的,下面简单说明一下里面各汇编的含义。
此外,我修改的是p目录下的文件,p目录下是单核的,而且是没有MMU的。具体env中各目录的差异大家可以看:
https://github.com/riscv/riscv-tests/tree/7ef425b4aea0a93568c788e68acebcc2f08da8d6
在这里插入图片描述

// See LICENSE for license details.

#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
#define _ENV_PHYSICAL_SINGLE_CORE_H

#include "./encoding.h"

//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------

###定义宏init
#define RVTEST_RV64U                                                    \
  .macro init;                                                          \
  .endm

###定义宏init,同时运行RVTEST_FP_ENABLE段
#define RVTEST_RV64UF                                                   \
  .macro init;                                                          \
  RVTEST_FP_ENABLE;                                                     \
  .endm

###定义宏init
#define RVTEST_RV32U                             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值