如何从 IAR EWARM 中的内联汇编器调用另一个模块中的 C 函数



我在硬错误处理程序中有一些组装。程序集基本上旨在将当前堆栈指针作为参数传递(在 R0 中)。看起来是这样...

__asm("    mov     r0, spn"
  "    bl      SavePCn"
  "    bx      lr");

当保存PC位于同一c文件中时,这工作正常。但是,当SavePC放置在另一个c文件中时,我没有运气。我尝试像这样导入函数...

__asm("IMPORT SavePCn"
" mov r0, spn"
" bl SavePCn"
" bx lr");

。但我一定是做错了什么。编译器报告以下内容...

Error[Og005]: Unknown symbol in inline assembly: "IMPORT" 
Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
Error[Og006]: Syntax error in inline assembly: "Error[54]: Expression can not be forward"
Error[Og005]: Unknown symbol in inline assembly: "SavePC" 
Error while running C/C++ Compiler 

带有程序集的 c 文件包括带有 SavePC 原型的头文件...

extern void SavePC(unsigned long);

建议?

即使使用

正确的调用,您的代码也无法正常工作。

bl _SavePC
bx lr

您认为bx lr指令中LR寄存器中的值是多少?指令本身的地址!bl指令把它放在那里。这实际上是一个带有 bx 指令的while (1);

嵌套函数调用看起来更像这样:

push lr
bl _SavePC
pop pc

要获取堆栈寄存器,请使用相应的CMSIS函数:

  • 主堆栈指针 (MSP) 的__get_MSP()
  • 进程堆栈指针 (PSP) 的__get_PSP()

使用 extern 是一个坏习惯,因为它容易出错。C-99标准为外部提供了一种安全的替代方案。您应该在没有 extern 关键字的头文件中编写函数原型。然后将头文件包含在两个 C 文件中。然后,链接器负责链接不同文件中的函数。

例:

文件 : custom_header.h

void SavePC(unsigned long);

文件 : source_c_file.c

#include "custom_header.h"
void SavePC(unsigned long)
{
      ....
      ....
      ....
}

文件 : user_c_file.c

#include "custom_header.h"
void someFunction(void)
{
.
.
.
__asm("    mov     r0, spn"
  "    bl      SavePCn"
  "    bx      lr");
.
.
.
}

最新更新