GCC ARM:在参数中传递常量的内联汇编

3

我正在编写一个小型Cortex M0+引导程序。下面是一段内联汇编代码,它可以从Flash中的应用程序位置加载堆栈指针和复位处理程序,从而启动主应用程序。

#define FLASH_APP_START 0x1000

[...]

    __asm(
            // Update stack pointer from user code vector table
            "LDR     r0, =%0 \n"
            "LDR     r1, [r0] \n"
            "MOV     sp, r1 \n"

            // Load user code reset handler and jump to the user code
            "LDR     r0, [r0, #4] \n"
            "BX      r0 \n"
            :
            : "X"(FLASH_APP_START)
            :
        );

当编译此代码时,我收到以下错误信息:

错误:表达式不正确 -- “ldr r0,=#4096”

GCC在该常量之前添加了 #,这是不应该出现的。 如果将第一行替换为以下内容,则可以完美运行。

LDR r0, =0x1000

那么问题是如何使用已定义的常量?
非常感谢您提供的帮助。

1
一些想法:在这个模板中,您更改了r0和r1而没有清除它们。这似乎不好。至于“#”,您可以尝试“%c0”。 - David Wohlferd
字面池中大写的'R'作为约束条件在gcc手册中未被正确记录。David的建议是正确的;根据godbolt示例,使用'%creg'修饰符。手册将其列在“修改器描述”标题下。 - artless noise
一篇关于内联汇编和常量池的相关问题的问题链接 - artless noise
1个回答

1

首先,在这里没有使用内联汇编的理由,简单的解决方案是将此代码编写为普通的汇编语言文件。如果需要,在头文件中定义FLASH_APP_START宏,您可以将其包含在汇编和C源文件中。

如果您仍然想使用内联汇编,则下一个最简单的解决方案是让编译器为您完成大部分工作,并将汇编语句减少到只能做的事情:

    void ** const flash_vector_table = (void **) FLASH_APP_START;
    asm volatile ("mov sp, %[stack]\n\t"
                  "bx %[reset]\n"
                  :
                  :
                  [stack] "r" (flash_vector_table[0]),
                  [reset] "r" (flash_vector_table[1]));

正如应该的那样。谢谢! - pge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接