从用__asm定义的ARM函数中调用C函数

时间:2018-06-26 16:22:46

标签: c arm inline-assembly cortex-m armcc

我无法理解我的编译器。我们使用Scons实用程序为M0 +处理器编译ARM代码(如果重要的话,在Windows上。这是ARMCC编译)。我试图使用this question的答案在中断期间捕获堆栈指针的地址。

对于我的编译器,我得到以下信息:Error: #20: identifier "asm" is undefined 我能够(主要)进行编译的唯一方法是使用以下代码:

  void IRQHandler_real( uint32_t *sp )
  {
     // Do some work
  }

  __asm void IRQHandler( void )
  {
     MOV R0,SP
     ADDS R0, #1
     LDR R1, =IRQHandler_real //<<-- This line fails
     BX R1
  }

错误代码是

  Error: A1516E: Bad symbol 'IRQHandler_real', not defined or external

BL IRQHandler_real替换最后两条装配线会导致相同的错误。

This answer解释说,内联汇编非常依赖于编译器,因此我无法找到与我的代码匹配的示例。

我读过here,我需要一个“ extern C”调用,但是我还没有找到关于它的外观的详细信息。

我仔细检查了已编译处理器代码的语法,它看起来与我使用的命令相同。我认为在评估程序集时未定义该符号。我只是还没有弄清楚如何定义和链接符号。

TL:DR,我需要从ARM程序集中调用C函数,但是我还没有跳过编译器。

2 个答案:

答案 0 :(得分:1)

如果您的编译器是C ++编译器,则需要使用extern“ C”;

extern "C" {
  void IRQHandler_real( uint32_t *sp )
  {
     // Do some work
  }
}

答案 1 :(得分:1)

似乎编译器正在评估所有C代码之后以及之后评估ARM代码。我通过导入功能修复了它 IMPORT命令。我的最终代码如下:

IMPORT IRQHandler_real
PUSH { R4, lr }
MOV R4, SP; The compiler does this from the C code, I'm assuming to avoid a hardware limitation.
MOV R0, R4
BL IRQHandler_real
POP { R4, PC }
ENDP

这适用于ARMCC 5.6。我认为目前大多数文档都是针对GCC ARM(asm("statement");)的。我仍然收到Warning: #667-D: "asm" function is nonstandard,因此,如果有答案,我将很乐意接受“更正确”的答案。