Using C headers in C++ code in GNU. Error including inline assembly: impossible constraint in 'asm'

ⅰ亾dé卋堺 提交于 2019-12-04 03:45:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!