Assembly 正在将链接器脚本与程序集文件[risc-v]连接

Assembly 正在将链接器脚本与程序集文件[risc-v]连接,assembly,linker,linker-errors,riscv,Assembly,Linker,Linker Errors,Riscv,我正在使用,我需要将链接器脚本“变量”连接到汇编文件指令,例如: 在我的链接器脚本(.ld)中,我有以下行: ENTRY(_start) _estack = 0x1FFFC; /* end of RAM */ ... 由此,我需要在start.S文件中创建一条汇编指令,如下所示: li sp, _estack 我试过很多东西,比如: .word _estack # - or - .global _estack li sp, _estack 但它们似乎都不起作用,它传达了这样一个信息

我正在使用,我需要将链接器脚本“变量”连接到汇编文件指令,例如:

在我的链接器脚本(.ld)中,我有以下行:

ENTRY(_start)
_estack = 0x1FFFC;    /* end of RAM */
...
由此,我需要在start.S文件中创建一条汇编指令,如下所示:

li sp, _estack
我试过很多东西,比如:

.word _estack
# - or -
.global _estack

li sp, _estack
但它们似乎都不起作用,它传达了这样一个信息:

App/src/start.S: Assembler messages:
App/src/start.S:59: Error: illegal operands `li sp,_estack'
make: *** [build/start.o] Error 1
对于上下文,以下是我的start.S文件:

.global _start

.section .text.prologue, "ax"

.word _estack
# .global _estack


_start:
    li sp, _estack
    jal  ra, main
    j _exit

_exit:  j _exit
这是一个“试试看”的事情

假设gcc检查编译器输出

fun:
    lui a5,%hi(_estack)
    lw  a0,%lo(_estack)(a5)
    ret
因此,对于gnu汇编程序(汇编语言是特定于工具而不是目标的)

还有ori

就像任何其他常量一样,您需要从lui开始设置高位,然后您可以处理其他指令中的低位。汇编程序可能对此有一条伪指令,在其中选择解决方案(例如,如果常量为0x12340000,则只需要lui)。但是假设伪指令是特定于汇编程序的,而不是特定于目标的。

这是一种“试试看”的方法

假设gcc检查编译器输出

fun:
    lui a5,%hi(_estack)
    lw  a0,%lo(_estack)(a5)
    ret
因此,对于gnu汇编程序(汇编语言是特定于工具而不是目标的)

还有ori


就像任何其他常量一样,您需要从lui开始设置高位,然后您可以处理其他指令中的低位。汇编程序可能对此有一条伪指令,在其中选择解决方案(例如,如果常量为0x12340000,则只需要lui)。但是假设伪指令是特定于汇编程序而不是目标的。

在crt0文件中,您需要替换:
li sp,\u estack
by
la sp,\u estack
li
仅用于立即,因为
\u estack
是必须使用的符号
la

在链接器脚本中,需要提供符号,否则将出现未定义的引用错误。替换
\u estack=0x1FFFC;/*RAM结尾*/


通过
提供(_estack=0x1ffc);/*在您的crt0文件中,RAM的末尾*/

需要替换:
li sp,\u estack
la sp,\u estack
li
仅用于立即,因为
\u estack
是必须使用的符号
la

在链接器脚本中,需要提供符号,否则将出现未定义的引用错误。替换
\u estack=0x1FFFC;/*RAM结尾*/


通过
提供(_estack=0x1ffc);/*RAM结束*/

为什么用0x1FFC而不是0x20000?您是否保留了内存的最后一个字?为什么是0x1ffc而不是0x20000?您是否保留了内存的最后一个字?li是人们通常希望在这里使用的伪指令,但它似乎不适用于简单的li sp,因此可能需要更多语法。我有问题,这整个把堆栈在链接器的事情,但YMMV。在本例中,如果它是我,我只会使用lui sp,0x20;如果语法支持,则使用lui sp,0x20000>>12。(这不是一个愿望,这实际上是我为risc-v所做的)。YMMV注意到只需几秒钟的谷歌搜索就能找到答案。我不需要花时间使用C编译器,即使这也能找到答案。还要注意的是,现有的gcc和binutils源代码现在包括risc-v。li是人们通常希望在这里使用的伪指令,但它似乎不能与简单的li sp一起工作,因此可能需要更多语法。我有问题,这整个把堆栈在链接器的事情,但YMMV。在本例中,如果它是我,我只会使用lui sp,0x20;如果语法支持,则使用lui sp,0x20000>>12。(这不是一个愿望,这实际上是我为risc-v所做的)。YMMV注意到只需几秒钟的谷歌搜索就能找到答案。我不需要花时间使用C编译器,即使这样也能找到答案。
lui x15,%hi(_estack)
lw  sp,%lo(_estack)(x15)

_estack = 0x1FFFC;
MEMORY
{
    ram : ORIGIN = 0x00000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > ram
}

Disassembly of section .text:

00000000 <.text>:
   0:   000207b7            lui x15,0x20
   4:   ffc7a103            lw  x2,-4(x15) # 1fffc <_estack>
lui sp,%hi(_estack)
addi sp,sp,%lo(_estack)