0

有没有办法让 gcc 为 asm 内联内部使用分配一个寄存器?这是一个示例(在伪 asm 中),其中 r5 直接在 asm 中使用,但它可以是任何通用寄存器,它仅供内部使用,因此既不是输入也不是输出:

asm("load_immediate_value %%r5,0;"
    /* ... */
    "add_immediate_value %%r5,%%r5,42"
    /* ... */
    :
    :
    : "r5");

在这个例子中,我选择了寄存器 r5 并通过 clobber 列表告诉 gcc 我正在使用它。但是如果 r5 是一个 ABI 寄存器呢?我需要一种方法来简单地要求注册,而不必自己命名。

4

1 回答 1

0

通常这样做的方式是:

static __inline__ void set_archctrl0(unsigned long val) {
    register unsigned long archctrl0 __asm__("archctrl0") = val;

    __asm__ __volatile__("" : "+r"(archctrl0) : : "cc", "memory");
}

语句 asm只是为了强制编译器不要优化整个事情。

或者,一个更实际的例子,读取堆栈指针寄存器可以这样完成:

static __inline__ void * getSP(void) {
    register void * sp asm("sp");
    asm ("" : "=r"(sp));
    return sp;
}

将变量绑定到特定寄存器的方法记录在 GCC 手册的显式寄存器变量部分。

当然,如果编写特定于架构的寄存器需要自定义指令(即不能使用 CPU 通常用于初始化寄存器值的任何类型的“移动”或“加载”来完成),你宁愿需要类似的东西:

static __inline__ void set_archctrl0(unsigned long val) {
    __asm__ __volatile__("setarchctrl0 %0" : : "r"(val) : "cc", "memory");
}

显然,所有这些仅适用于“正常”代码使用的寄存器(即在平台 ABI 之外/由平台 ABI 明确保留为全局变量/作为不被编译代码触及的 regs)。

您不能以这种方式指示编译器“不使用通用寄存器”。据我所知,这在 gcc 中是不可能的。

于 2013-04-19T09:00:33.920 回答