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++'.