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

时间:2012-10-05 18:48:20

标签: c inline-assembly extern cortex-m3 iar

我在硬故障处理程序中有一些装配。该程序集基本上是指将当前堆栈指针作为参数传递(在R0中)。它看起来像......

__asm("    mov     r0, sp\n"
  "    bl      SavePC\n"
  "    bx      lr");

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

__asm("IMPORT SavePC\n"
" mov r0, sp\n"
" bl SavePC\n"
" 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);

建议?

2 个答案:

答案 0 :(得分:1)

即使拨打正确的电话,您的代码也无效。

bl _SavePC
bx lr

您认为LR指令中bx lr寄存器的值是什么? 指令本身的地址! bl指令将其放在那里。 这实际上是带有bx指令的while (1);

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

push lr
bl _SavePC
pop pc

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

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

答案 1 :(得分:1)

使用extern是一个坏习惯,因为它容易出错。 C-99标准为extern提供了一种安全的替代方案。您应该在头文件中编写函数原型而不使用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, sp\n"
  "    bl      SavePC\n"
  "    bx      lr");

.
.
.
}