首页 > 解决方案 > RISC-V:全局变量

问题描述

所以,我最近完成了我自制的 RISC-V CPU,只使用逻辑 IC 和存储器。(如果有人感兴趣,您可以在这里观看更多内容:https ://www.youtube.com/watch?v=KzSaFFpBPDM )

这意味着硬件已设置好,此时无法进行任何重大更改。我正在使用 xPack 进行编译:https ://xpack.github.io/riscv-none-embed-gcc/ ,架构设置为 RV32I。一切正常,除非我需要使用全局变量,这是一个示例代码:

#include <stdint.h>

int static_var_1 = 2;
int static_var_2 = 4;

int main(void)
{
    int var = static_var_1 + static_var_2;
}

对象转储(objdump)揭示了这一点:

APP.elf:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <_start>:
   0:   00080137            lui sp,0x80
   4:   ffc10113            addi    sp,sp,-4 # 7fffc <_estack>
   8:   00c000ef            jal ra,14 <main>
   c:   0040006f            j   10 <_exit>

00000010 <_exit>:
  10:   0000006f            j   10 <_exit>

00000014 <main>:
  14:   fe010113            addi    sp,sp,-32
  18:   00812e23            sw  s0,28(sp)
  1c:   02010413            addi    s0,sp,32
  20:   00002703            lw  a4,0(zero) # 0 <_start>
  24:   00402783            lw  a5,4(zero) # 4 <static_var_2>
  28:   00f707b3            add a5,a4,a5
  2c:   fef42623            sw  a5,-20(s0)
  30:   00000793            li  a5,0
  34:   00078513            mv  a0,a5
  38:   01c12403            lw  s0,28(sp)
  3c:   02010113            addi    sp,sp,32
  40:   00008067            ret

Disassembly of section .data:

00000000 <static_var_1>:
   0:   0002                    c.slli64    zero
    ...

00000004 <static_var_2>:
   4:   0004                    0x4
    ...

Disassembly of section ._user_heap_stack:

00000008 <._user_heap_stack>:
    ...

根据我的观察和这部分代码

  20:   00002703            lw  a4,0(zero) # 0 <_start>
  24:   00402783            lw  a5,4(zero) # 4 <static_var_2>

看起来 CPU 想要直接从 RAM 中加载值,从地址 0 开始,但它们一开始就没有放在那里。CPU是否以某种方式假设它将在启动/重置时具有预加载的RAM?“正常”CPU如何处理这种情况以及我应该如何解决我的问题?是否有一些设置会强制编译器首先将这些变量提取到 RAM 中?

这是一个与这个问题(RISC V Global variables access in assembly)略有相似的问题,但我真的不明白“编译器放松”如何真正有帮助,但也许我错了......

标签: compiler-errorscompilationlinkercpuriscv

解决方案


00000000 <_start>:

该二进制文件链接到地址 0 加载。这是不寻常的(大多数人希望将 NULL 指针与有效地址区分开来,而将代码放入零页不允许这种区分)。

Disassembly of section .data:
00000000 <static_var_1>:

这个二进制文件也链接到地址 0 处的 put.data部分。那是行不通的——你必须把它.data放在别的地方。

我的朋友帮我设置了链接器脚本,

该链接描述文件绝对是错误的。找一个更好的朋友;-)


推荐阅读