【发布时间】:2021-04-04 05:17:33
【问题描述】:
我正在尝试使用 ARM Compiler 5 为 Cortex A 微处理器编译以下两段代码:
第 1 部分:
static inline void cp15_write_sctlr(uint32_t value)
{
asm("mcr p15, 0, %0, c1, c0, 0" :: "r"(value));
}
static inline uint32_t cp15_read_actlr(void)
{
uint32_t actlr;
asm("mrc p15, 0, %0, c1, c0, 1" : "=r"(actlr));
return actlr;
}
第 2 部分:
static inline void dmb(void)
{
asm("dmb" ::: "memory");
}
static inline void dsb(void)
{
asm("dsb" ::: "memory");
}
static inline void isb(void)
{
asm("isb" ::: "memory");
}
在这两种情况下,我都会遇到编译错误。请参阅下面的示例。
line 64: Error: #18: expected a ")"
asm("dsb" ::: "memory");
是编译器版本(ARM compiler 5)不支持Extended Asm导致的错误吗?
如果我重新编写 第 1 部分 中的代码,如下所示,我不会收到任何错误。下面的代码是否等同于第 1 部分中的代码?
static inline void cp15_write_sctlr(uint32_t value)
{
__asm
{
MCR p15, 0, value, c1, c0, 0
}
}
static inline uint32_t cp15_read_actlr(void)
{
uint32_t actlr;
__asm
{
MRC p15, 0, actlr, c1, c0, 1
}
return actlr;
}
如果编译器不支持扩展 Asm,我该如何重写第 2 部分中的代码? 我想到了以下几点,但我不确定它是否相同。
static inline void dmb(void)
{
__schedule_barrier();
__asm("dmb");
__schedule_barrier();
}
static inline void dsb(void)
{
__schedule_barrier();
__asm("dsb");
__schedule_barrier();
}
static inline void isb(void)
{
__schedule_barrier();
__asm("isb");
__schedule_barrier();
}
任何帮助将不胜感激。
【问题讨论】:
-
什么,具体是您的错误?请编辑您的问题,并在单独的代码块中发布exact错误文本。您使用的是什么编译器(例如
gcc)?还有,什么汇编程序?编译器可能支持__asm和/或__asm__但不asm[它们具有相同的功能]。 -
@CraigEstey Post 已编辑。正如我在帖子中所写,编译器是 Arm Compiler 版本 5。谢谢。
-
当我完成 [商业] arm 开发时,我在 Ubuntu 下使用了
gcc交叉编译器。我以前从未听说过“arm compiler 5”。我查了一下,[AFAICT] 这是一个重新命名的 Keil 套件 [你必须付费]。众所周知,Keil 在某些事情上有些滞后。您可以将 asm 内容隔离到一个单独的文件中,并使用gcc对其进行编译,然后将.o加载到 IDE 中。来自:keil.com/support/man/docs/armcc/armcc_chr1359124246903.htm 似乎没有扩展了 asm。 -
或者,如果你隔离了 asm 代码,你可以把它放到
.s文件中定义的函数中。我怀疑性能会没问题[尽管没有纯内联那么快]。您可以使用 100% 的 asm 块并且是纯的 C 函数来实现相同的目的。它可能仍可用作static inline函数。我会反汇编.o文件以查看为给定函数生成的实际代码,以了解它的工作情况。
标签: c assembly arm inline-assembly keil