问题
I have a weird one. I'm working on an embedded system, using the vendors header files. I'm compiling the files using GCC 4.6.3. I want to use C++ for my code, I have error I can't figure out. I'm running a vendor example program, and all I've done is changed the name of the main.c file to main.cpp. As a result, I assume, the header files are being interpreted by the C++ compiler. One of them contains the following lines:
__attribute__((naked)) static return_type signature \
{ \
__asm( \
"svc %0\n" \
"bx r14" : : "I" (number) : "r0" \
); \
}
The files compile properly if the name of the file is main.c, I assume this is because the file is being processed by the C compiler. The error I get if I use C++ is
error: impossible constraint in 'asm'
But again, I have no problem with the C compiler. I need to call functions that use this define in C++ files. I've considered writing wrapper functions that stay on the c side and linking to them, but it would be a real pain, and less efficient. Any suggestions?
回答1:
svc also known as swi
is the ARM/Thumb software interrupt instruction. It only takes constants, but they are different from other register constants. Ie, mov r0, #4096
. You need to use the preprocessor and token pasting if you wish to specify an immediate. number
can not be a variable or register.
#define syscall(number) __attribute__((naked)) static return_type signature \
{ \
__asm( \
"svc " #number "\n" \
"bx r14" : : : "r0" \
); \
}
will work. Note: The #
is the 'C' preprocessors stringify. Also note that it is in-efficient to look at the SVC
number as it is in the I-CACHE
and inspecting requires D-CACHE
. Generally it is always constant
and the function number is passed in a register for faster syscall's.
The gcc manual says,
'I'- Integer that is valid as an immediate operand in a data processing instruction. That is, an integer in the range 0 to 255 rotated by a multiple of 2
This is typical of Data-processing operands - immediate, section A5.1.3 of the ARM ARM. The SVC
operands are either fixed 8-bits in thumb mode or fixed 24-bits in ARM mode. It maybe possible with some other constraint that I am unaware of, but at least the preprocessor's stringification will work as long as a numeric constant is passed to the macro.
I guess it is lucky that this worked from gcc
and unlucky that g++
did not. You can get further insight by using -S
and looking at (and posting) the output using both tools.
Edit: Your code does seem to work with gcc-4.7.2
, but number
is a const int
local in my case, the use of number
maybe the issue. Perhaps it has a subtle semantic change from 'C' to 'C++'.
回答2:
Check the GCC manual (inline assembler) for the exact meaning of the constraints for your machine. Older GCC versions have been notoriously sloppy in the checking of constraints, perhaps you are being bitten by this. It is strange that gcc
and g++
(same version?) handle the code differently, it just might be a compiler bug, but I'd consider that only after all other explanations have been exhausted.
来源:https://stackoverflow.com/questions/15712894/using-c-headers-in-c-code-in-gnu-error-including-inline-assembly-impossible