在内联汇编程序中使用寄存器

时间:2012-03-12 15:37:12

标签: c gcc assembly

我正在为OpenRISC优化C代码,我想在寄存器中手动预先保存一些计算值,伪代码看起来像这样:

external loop
    compute eight values (heavy calculations)
    internal loop
        use values computed above

当我查看GCC ABI for OpenRISC时,我看到了两组寄存器:callee-saved和temporary?我应该使用哪些寄存器来存储这八个值?我的意思是,哪些寄存器可以放在内联asm的破坏列表中?

我需要硬编辑寄存器,因为我们在自定义OpenRISC上运行可执行文件。

1 个答案:

答案 0 :(得分:2)

答案是:无论你喜欢什么。

如果您使用被调用者保存寄存器,那么编译器将为您保存它们(只要您执行将它们标记为已破坏)。

如果你使用临时寄存器(a.k.a.calller-save),那么如果你进行函数调用,编译器将被强制保存它们。请注意,编译器也更喜欢将这些变量用于其他变量,因此如果你用掉了调用者保存的变量,那么它必须使用callee-save来处理其他事情,因此它可能最终会产生相同的差异。 / p>

在一天结束时,如果你正在进行繁重的计算,那么在开始之前将一些寄存器保存到堆栈中并不是一件大事。

有些寄存器包含您不得覆盖的重要值(例如堆栈指针)。其他的,比如GOT表指针则不那么重要,编译器会在你完成后恢复该值(只是确保你在此过程中不需要它。

但实际上,您不需要自己解决问题:编译器可以为您选择寄存器:

int a, b, c;

asm volatile ("whatever" : "=&w" (a), "=&w" (b), "=&w" (c));

不需要变量,但它们必须分配寄存器,因此它们可以有效地为您想要的任何内容保留寄存器。 &表示" early-clobber",这意味着他们不能与输入寄存器共享同一个寄存器(不是我的示例显示的任何寄存器)。