c - GCC:禁止使用某些寄存器

标签 c gcc assembly gnu-assembler register-allocation

这是一个奇怪的要求,但我觉得这是可能的。我想要的是将一些编译指示或指令插入我的代码区域(用 C 编写),以便 GCC 的寄存器分配器不会使用它们。

我知道我可以做这样的事情,可能为这个变量留出这个寄存器

register int var1 asm ("EBX") = 1984;
register int var2 asm ("r9") = 101;

问题是我正在直接插入新指令(用于硬件模拟器),而 GCC 和 GAS 还不能识别这些指令。我的新指令可以使用现有的通用寄存器,我想确保保留其中的一些(即 r12->r15)。

现在,我在模型环境中工作,我想快速进行实验。将来我会追加 GAS 并将内在函数添加到 GCC 中,但现在我正在寻找快速修复。

谢谢!

最佳答案

在编写 GCC 内联汇编器时,您可以指定一个“clobber 列表”——一个可能被您的内联汇编器代码覆盖的寄存器列表。然后,GCC 将在内联 asm 段的过程中做任何必要的事情来保存和恢复这些寄存器中的数据(或者首先避免使用它们)。您还可以将输入或输出寄存器绑定(bind)到 C 变量。

例如:

inline unsigned long addone(unsigned long v)
{
    unsigned long rv;
    asm("mov $1, %%eax;"
        "mov %0, %%ebx;"
        "add %%eax, %%ebx"
        : /* outputs */  "b" (rv)
        : /* inputs */   "g" (v) /* select unused general purpose reg into %0 */
        : /* clobbers */ "eax"
       );
}

有关详细信息,请参阅 GCC-Inline-Asm-HOWTO .

关于c - GCC:禁止使用某些寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6682733/

相关文章:

C、用指针将字符串按空格分割成字符串

编译已经编写的 C 脚本。 Visual Studio 2017

linux - LD_LIBRARY_PATH 似乎不起作用

assembly - 寄存器的十六进制值? x86

c - 理解一个简单的 C 程序生成的汇编代码

c - 为字符串数组分配内存

c - 使用基数排序对日期进行排序

c++ - 逗号的左手操作数没有效果?

c - 是否允许这种枚举构造和赋值?

c - 来自 C 的 NASM 中的简单循环