FPGA 上 RISCV CPU 的链接器脚本,堆栈不在我期望的位置?

问题描述 投票:0回答:1

在过去的几个月里,我在 FPGA 上实现了 RV32I CPU。到目前为止,我只是使用一些汇编代码对其进行了测试。这周我决定用 C 语言尝试一个简单的测试程序。源码如下:

int main(){
        register unsigned int a = 1;
        register unsigned int b = 1;
        while(1){
                a = a << b;
                if(a == 0x80000000){
                        a = 1;
                }
        }
        return 0;
}

这一切都简单明了,这样我就可以在分配了“a”的寄存器中看到步行模式。

在进行 objdump 时,我仍然对堆栈放置的位置感到非常困惑:

test.elf:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <main>:
   0:   ff010113                add     sp,sp,-16
   4:   00112623                sw      ra,12(sp)
   8:   00812423                sw      s0,8(sp)
   c:   00912223                sw      s1,4(sp)
  10:   01010413                add     s0,sp,16
  14:   00100093                li      ra,1
  18:   00100493                li      s1,1
  1c:   009090b3                sll     ra,ra,s1
  20:   800007b7                lui     a5,0x80000
  24:   fef09ce3                bne     ra,a5,1c <main+0x1c>
  28:   00100093                li      ra,1
  2c:   ff1ff06f                j       1c <main+0x1c>

鉴于我在链接描述文件中说了我的内存在哪里,我不明白为什么编译器使用低于 4GB 限制的最高可能地址作为堆栈基地址。这可以在前四个指令中看到,我们将值保存到堆栈中。我的链接器脚本如下:

ENTRY(main)

BRAM_SIZE = 1024;

MEMORY{
        INSTR(RX)  : ORIGIN =0x00000000 , LENGTH = BRAM_SIZE 
        DATA(RWX)  : ORIGIN =0x01000000 , LENGTH = BRAM_SIZE
}

STACK_SIZE = 0x100;

/* Section Definitions */
SECTIONS
{
    .text :
    {
        KEEP(*(.vectors .vectors.*))
        *(.text*)
        *(.rodata*)
    } > INSTR

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        *(.bss*)
        *(COMMON)
    } > DATA

    .data :
    {
        *(.data*);
    } > DATA AT >INSTR

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        . = . + STACK_SIZE;
        . = ALIGN(8);
    } > DATA

    _end = . ;
}

我正在使用以下命令和工具链进行编译:

riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -nostdlib -ffreestanding -T  linkerscript_reduced.ld -o test.elf test.c

我做错了什么?预先感谢,并对菜鸟问题表示歉意。

gcc embedded riscv linker-scripts
1个回答
0
投票

由于您添加了选项“-nostdlib -ffreestand”,您需要自己提供每个细节。这包括标准所承诺的 C 环境设置,以及您的特定目标期望的任何内容。

这说的是链接选项的文档(我强调过):

-nostdlib

链接时不要使用标准系统启动文件或库。 没有启动文件,仅将您指定的库传递给链接器,并且忽略指定系统库链接的选项,例如

-static-libgcc
-shared-libgcc

这说明了 C 方言选项的文档:

-ffreestanding

断言编译目标是独立环境。这意味着

-fno-builtin
。独立环境是标准库可能不存在的环境,程序启动不一定在
main

因此,您需要添加代码,将堆栈指针初始化为您想要的值,将其归零

.bss
并将初始化的数据复制到
.data
部分。这通常是用汇编语言编写的,但是通过一些内联汇编,您也可以编写 C 源代码。

© www.soinside.com 2019 - 2024. All rights reserved.