我有一个奇怪的。我正在使用供应商头文件在嵌入式系统上工作。我正在使用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端并链接到它们的包装函数,但这将是一个真正的痛苦,而且效率较低。有什么建议?
答案 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
一起使用,但在我的情况下,number
是const int
本地代码,使用{{1}也许是问题。也许它从“C”到“C ++”有一个微妙的语义变化。
答案 1 :(得分:0)
检查GCC manual(内联汇编程序),了解机器约束的确切含义。较旧的GCC版本在检查约束方面一直都很邋of,也许你会被这种情况所困扰。奇怪的是,gcc
和g++
(相同的版本?)处理代码的方式不同,它只是可能是一个编译器错误,但我认为只有在所有其他错误之后解释已经用尽。