使用GCC的内联汇编直接调用

Job*_*Job 11 c c++ gcc inline-assembly function-call

如果要从内联汇编中调用C/C++函数,可以执行以下操作:

void callee() {}
void caller()
{
    asm("call *%0" : : "r"(callee));
}
Run Code Online (Sandbox Code Playgroud)

然后GCC将发出如下所示的代码:

movl $callee, %eax
call *%eax
Run Code Online (Sandbox Code Playgroud)

这可能会有问题,因为间接调用会破坏旧CPU上的管道.

由于地址callee最终是常量,可以想象可以使用i约束.引自GCC在线文档:

'我"

允许使用立即整数操作数(具有常量值的操作数).这包括符号常量,其值仅在汇编时或以后知道.

如果我尝试这样使用它:

asm("call %0" : : "i"(callee));
Run Code Online (Sandbox Code Playgroud)

我从汇编程序中收到以下错误:

错误:后缀或操作数对`call'无效

这是因为GCC会发出代码

call $callee
Run Code Online (Sandbox Code Playgroud)

代替

call callee
Run Code Online (Sandbox Code Playgroud)

所以我的问题是是否可以使GCC输出正确call.

Job*_*Job 11

我从GCC的邮件列表中得到了答案:

asm("call %P0" : : "i"(callee));
Run Code Online (Sandbox Code Playgroud)

现在我只需要找出%P0实际意味着什么,因为它似乎是一个没有文档的功能......

编辑:在查看GCC源代码之后,并不清楚P约束前面的代码是什么意思.但是,除其他外,它阻止了GCC $在常数值之前.这正是我在这种情况下所需要的.