内联汇编

时间:2015-10-13 03:47:09

标签: powerpc

我正在尝试使用C中的内联汇编为powerpc64编写一个简单的函数,我的函数调用另一个函数,我有几个与之相关的问题。

1)如何在使用' bl'分支之前保存LR寄存器?到子程序?

具体来说,对于此代码:

void func(void *arg1, void *arg2)
{
   void *result;
   __asm__ volatile (
   ...
   ...
   "bl <address>\n"        //Call to subroutine
   "nop\n"
   ...
   : [result]"=r"(result)
   : [arg1]"r"(arg1),
     [arg2]"r"(arg2)
   );
   return result;
}

编译器为此生成序言代码而没有&#34; mflr 0; std 0,16(1)&#34;保存LR的指令,因为它不知道我的汇编代码中正在调用子程序。我是否在汇编代码中包含这些说明?如果是这样,我怎么知道编译器序言代码创建的堆栈大小到达函数调用&#39; func&#39;?的LR保存区域? (从developerWorks上的powerpc汇编教程中,LR寄存器需要保存在&#39;调用&#39;函数的堆栈框架中)

2)我相信在调用子程序之前我需要保存arg1和arg2,这是在进行子程序调用之前临时存储这些参数的正确位置 - 参数保存区域还是非易失性寄存器?我只是想知道这是在生产质量ppc64代码中完成的正确方法

提前致谢!

1 个答案:

答案 0 :(得分:1)

AFAIK没有办法正确地做到这一点。内联asm不是为调用函数而设计的。

您无法可靠地知道编译器生成的堆栈帧的大小,实际上整个函数可能是内联的,或者您认为编译器可能根本不会生成堆栈帧。

但是你没有 将LR存储在调用者堆栈框架中,如果你这样做最好,但不是100%要求。所以只需将它放在一个非易失性标记中,注册为破坏标记,并在返回途中恢复它。

您不需要保存arg1和arg2,但您必须做的是将所有易失性寄存器标记为已破坏。然后编译器将在调用asm之前保存易失性寄存器中的任何内容(如arg1和arg2)。还要记住,某些CR字段可能会被破坏。我还要给“clobbers”添加“记忆”,以便GCC对整个asm的优化感到悲观。

如果你做了可能的所有工作,除非我忘记了一些事情:)