gd32vf103汇编开发

gd32vf103汇编开发
目录

本文简单介绍gd32vf103汇编开发的一种方式。

前言

汇编在MCU开发中相当常见,如MCU的启动代码、RTOS任务调度 相关的线程切换操作、程序出现异常时进行Debug等都经常离不开 汇编代码。

本文以gd32vf103为例,通过一个简单的汇编程序,使用相关 工具链进行汇编和链接,并下载到MCU上测试运行,初步了解汇编 源程序如何最终能在目标MCU上运行的过程。

主要流程

首先需要安装和配置工具链并搭建开发环境,相关信息可参考 本站文章:在Arch Linux下搭建GD32VF103开发环境

需要一个汇编源程序,使用GNU工具链进行汇编和链接得到 可下载到MCU的二进制文件,使用调试工具下载和验证程序 的执行。

汇编代码

我们实现一个进行10个无符号整数相加的汇编程序,文件命名为sum.asm, 内容如下:

  .section .text
  .global _start

_start:
  li t0, 10       # t0用于计数, 10个数相加
  la t1, _data    # t1为地址指针, 指向每次取数的位置
  li a0, 0        # a0用于保存累加结果, 初始为0

add:
  lbu t2, 0(t1)   # 每次取数结果暂存至t2
  add a0, a0, t2  # a0 = a0 + t2
  addi t1, t1, 1  # 地址指针指向下一个数
  addi t0, t0, -1 # 计数值减1
  bnez t0, add    # 计数值非0, 继续执行取数累加

loop:
  j loop          # 执行到该步时累加已结束, a0结果应为
                  # 1 + 2 + ... + 10 = 55

  .global _data

_data:              # _data标签开始的10个byte初始化为待累加的数据
  .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

汇编和链接

汇编阶段生成目标文件:

riscv64-unknown-elf-as -g -march=rv32imac -o sum.o sum.s
  • -g: 生成调试信息;
  • -march=rv32imac: 指定目标指令集架构,gd32vf103为rv32imac;
  • -o sum.o: 指定输出文件为sum.o
  • sum.s: 汇编器的源文件。

链接生成可执行文件:

riscv64-unknown-elf-ld -m elf32lriscv -Ttext=0x20000000 -o sum.elf sum.o
  • -m elf32lriscv: 指定emulation模式(riscv, 32位, 小端);
  • -Ttext=0x20000000: 指定.text段的起始地址,0x20000000为gd32vf103 RAM的起始地址,本例中用调试器把指令和数据下载到RAM,指令在RAM中执行;
  • -o sum.elf: 指定输出文件为sum.elf
  • sum.o: 链接器使用的目标文件。

生成bin文件,用于烧写(可选):

riscv64-unknown-elf-objcopy -O binary sum.elf sum.bin

验证

按gd32vf103规格书引导配置要求,调整开发板BOOT0BOOT1 跳线,使开发板复位后从片上SRAM执行,连接调试器并上电。

使用以下命令使用openocd开启调试服务:

openocd -f openocd_gd32vf103.cfg

在另一个命令行窗口,运行gdb:

scv64-unknown-elf-gdb sum.elf

gdb相关操作:

  • target remote :3333: 连接到本地3333端口的调试服务;
  • monitor reset init: 使板复位;
  • load: 下载程序;
  • n: 单步执行;
  • 查看寄存器内容,可以使用info reg,或指定特定寄存器 查看,如info reg a0info reg a0 t0 pc
  • 更改寄存器内容,可以使用set,如set $pc = _startset $a0 = 0
  • 查看内存中的数据,x/16ub _data即可查看从_data标签 所在位置开始的16个占用单个字节无符号整数。

gdb

参考

  1. 在Arch Linux下搭建GD32VF103开发环境
  2. riscv-asm-manual