我无法理解我的编译器。我们使用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函数,但我还没有通过编译器。
如果您的编译器是C ++编译器,则需要像这样使用extern“C”;
extern "C" {
void IRQHandler_real( uint32_t *sp )
{
// Do some work
}
}
似乎编译器在评估所有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
,所以我很乐意接受一个“更正确”的答案,如果存在。