I got the answer from GCC’s mailing list:
asm("call %P0" : : "i"(callee)); // FIXME: missing clobbers
Now I just need to find out what %P0
actually means because it seems to be an undocumented feature…
Edit: After looking at the GCC source code, it’s not exactly clear what the code P
in front of a constraint means. But, among other things, it prevents GCC from putting a $
in front of constant values. Which is exactly what I need in this case.
For this to be safe, you need to tell the compiler about all registers that the function call might modify, e.g. : "eax", "ecx", "edx", "xmm0", "xmm1", ..., "st(0)", "st(1)", ...
.
See Calling printf in extended inline ASM for a full x86-64 example of correctly and safely making a function call from inline asm.