【问题标题】:RISC-V: Global variablesRISC-V:全局变量
【发布时间】:2021-07-12 11:05:25
【问题描述】:

所以,我最近完成了自制的 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) 稍微相似的问题,但我真的不明白“编译器放松”如何真正有帮助,但也许我错了......

【问题讨论】:

  • 您是否编写了自己的链接器脚本?
  • @Eraklon 我的朋友帮我设置了链接器脚本,不幸的是我真的不知道它是如何工作的
  • 您是否要求objdump 显示重新定位?
  • @ErikEidt 一旦我知道它是什么,我会这样做
  • @ErikEidt 也许我做错了,也许我不知道我在寻找什么,但我什么也没找到

标签: compiler-errors compilation linker cpu riscv


【解决方案1】:

00000000 &lt;_start&gt;:

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

Disassembly of section .data:
00000000 &lt;static_var_1&gt;:

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

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

那个链接器脚本肯定错了。找一个更好的朋友;-)

【讨论】:

  • 但是 CPU 从地址 0 开始执行,所以那里肯定有东西。即使 .data 部分在主程序中,它仍然是无效指令,CPU 将停止。我认为我需要将 .data 部分重新定位并解码为有效指令;例如,0x4 可能是:addi t0, zero, 4 sw t0, 0(zero) 我稍后会发布链接器脚本,但我不确定朋友的变化:)))
  • 好的,经过内部讨论,归结为“我们需要一个新的链接器脚本”。哦,好吧,从哪里开始......
猜你喜欢
  • 2021-08-02
  • 2023-03-12
  • 2016-05-14
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2016-03-14
相关资源
最近更新 更多