在GNU中使用C ++代码中的C头。错误包括内联汇编:'asm'中不可能的约束

时间:2013-03-29 23:14:26

标签: c++ gcc embedded arm inline-assembly

我有一个奇怪的。我正在使用供应商头文件在嵌入式系统上工作。我正在使用GCC 4.6.3编译文件。我想将C ++用于我的代码,我有错误,我无法弄清楚。我正在运行一个供应商示例程序,我所做的就是将main.c文件的名称更改为main.cpp。因此,我认为,头文件正由C ++编译器解释。其中一个包含以下几行:

__attribute__((naked)) static return_type signature \
  { \
     __asm( \
         "svc %0\n" \
         "bx r14" : : "I" (number) : "r0" \
     ); \
}

如果文件名是main.c,文件编译正确,我认为这是因为C编译器正在处理该文件。如果我使用C ++,我得到的错误是

error: impossible constraint in 'asm'

但同样,我对C编译器没有任何问题。我需要在C ++文件中调用使用此定义的函数。我已经考虑过编写保留在c端并链接到它们的包装函数,但这将是一个真正的痛苦,而且效率较低。有什么建议?

2 个答案:

答案 0 :(得分:1)

svc也称为swi ARM / Thumb 软件中断指令。它只需要常量,但它们与其他寄存器常量不同。即,mov r0, #4096。如果要指定立即数,则需要使用预处理程序和标记粘贴。 number不能是变量注册

#define syscall(number) __attribute__((naked)) static return_type signature \
  { \
     __asm( \
         "svc " #number "\n" \
         "bx r14" : : : "r0" \
     ); \
  }

会奏效。 注意: #'C'预处理程序stringify。另请注意,查看SVC中的I-CACHE号码并检查需要D-CACHE是不合时宜的。通常它总是constant并且函数编号在寄存器中传递以获得更快的系统调用。

gcc手册说,

  

'我' - 作为数据中的直接操作数有效的整数            处理指令。也就是说,范围为0的整数            到255旋转了2的倍数

这是典型的数据处理操作数 - 立即,ARM ARM的A5.1.3节。 SVC操作数在拇指模式下固定为8位,在ARM模式下固定为24位。可能还有其他一些我不知道的约束,但至少只要数值常量传递给宏,预处理器的字符串化就会起作用。

我想幸运的是,gcc这很有用,而g++没有,这是不幸的。您可以使用-S并使用这两种工具查看(并发布)输出来获得进一步的见解。

修改:您的代码似乎与gcc-4.7.2一起使用,但在我的情况下,numberconst int本地代码,使用{{1}也许是问题。也许它从“C”到“C ++”有一个微妙的语义变化。

答案 1 :(得分:0)

检查GCC manual(内联汇编程序),了解机器约束的确切含义。较旧的GCC版本在检查约束方面一直都很邋of,也许你会被这种情况所困扰。奇怪的是,gccg++(相同的版本?)处理代码的方式不同,它只是可能是一个编译器错误,但我认为只有在所有其他错误之后解释已经用尽。