有没有办法让gcc为asm内联内部使用分配一个寄存器?这是一个例子(在伪asm中),其中r5直接在asm中使用,但它可以是任何通用寄存器,它仅供内部使用,因此既不是输入也不是输出:
asm("load_immediate_value %%r5,0;"
/* ... */
"add_immediate_value %%r5,%%r5,42"
/* ... */
:
:
: "r5");
在这个例子中,我选择注册r5并告诉gcc我通过clobber列表使用它。但是如果r5是ABI寄存器怎么办?!我需要一种方法来简单地询问一个寄存器,而不必自己命名。
答案 0 :(得分:0)
通常这样做的方式是:
static __inline__ void set_archctrl0(unsigned long val) {
register unsigned long archctrl0 __asm__("archctrl0") = val;
__asm__ __volatile__("" : "+r"(archctrl0) : : "cc", "memory");
}
empty asm
语句只是强制编译器而不是来优化整个事情。
或者,更实际的例子是,读取堆栈指针寄存器可以像:
static __inline__ void * getSP(void) {
register void * sp asm("sp");
asm ("" : "=r"(sp));
return sp;
}
将变量绑定到特定寄存器的方法记录在GCC手册的Explicit Register Variables部分中。
当然,如果编写特定于arch的寄存器需要一个自定义指令(即不能使用CPU通常用来初始化寄存器值的任何类型的“移动”或“加载”),你宁愿需要像:
static __inline__ void set_archctrl0(unsigned long val) {
__asm__ __volatile__("setarchctrl0 %0" : : "r"(val) : "cc", "memory");
}
所有这些显然只适用于不被“普通”代码使用的寄存器(即在平台ABI之外/由平台ABI显式保留为全局/注册不是被编译的代码触及。)
您无法通过这种方式指示编译器“保持通用寄存器”。据我所知,这在gcc中是不可能的。