If you want to call a C/C++ function from inline assembly, you can do something like this:
void callee() {}
void caller()
{
asm("call *%0" : : "r"(callee));
}
GCC will then emit code which looks like this:
movl $callee, %eax
call *%eax
This can be problematic since the indirect call will destroy the pipeline on older CPUs.
Since the address of callee
is eventually a constant, one can imagine that it would be possible to use the i
constraint. Quoting from the GCC online docs:
`i'
An immediate integer operand (one with constant value) is allowed. This includes symbolic constants whose values will be known only at assembly time or later.
If I try to use it like this:
asm("call %0" : : "i"(callee));
I get the following error from the assembler:
Error: suffix or operands invalid for `call'
This is because GCC emits the code
call $callee
Instead of
call callee
So my question is whether it is possible to make GCC output the correct call
.
__attribute__((used))
on the function so it doesn't get optimized out. You don't have to worry about portability if you have a single target OS and cpu architecture. By the way, are you really using C++ in kernel code?? – Mantis