使用GCC编译器为代码的特定部分保留寄存器



是否可以为C代码的特定部分保留寄存器?

-ffixed-reg选项或声明全局寄存器变量不是我要寻找的答案。我想保留特定范围的寄存器值(例如,特定功能(。

不可能使用本地寄存器变量,因为它不能保证在整个范围内保留寄存器的值。我正在寻找诸如ASM挥发性的Clobber列表之类的东西,但对于C语句。

gcc给出三个机甲,

  1. asm clobber
  2. 本地寄存器变量
  3. 全局寄存器变量

重要的是要注意,编译器寄存器分配对于现代优化至关重要,并且保留寄存器可以生成更糟糕的编译代码。使用ARM模式和16个寄存器(只有13个可用(,您应该能够保留一个像这样的登记册,以毫无损害。但是,您不应该轻轻地使用这些设施,并且发现一些性能问题也就不足为奇了。

听起来全局寄存器变量最适合您。只需在需要它的每个" C"模块的开始时register int *foo asm ("r4");即可。

如果您的功能群/树群很小,则可以使用宏保留并将其包含在一个" C"单元中。

#define RESERVE_REG(reg)  register int RR_##reg asm (#reg) 
                                 __attribute__((unused))
int bar(int a) { 
  RESERVE_REG(R4); 
  int b; 
  b += CRAZY_ASM(a); 
  return b;
}
void foo(void) { 
 RESERVE_REG(R4); 
 CRAZY_ASM_SET_R4(82);
 printf("value is %dn", bar(1));
}

知道变量的使用很重要,因为有更有效的方法(例如asm Clobber(可以在某些可变的寿命和用途中获得相同的效果。在大多数情况下,人们只会声明一个参数。即,最好让编译器知道您正在使用的方法,因为它可以就何时溢出做出明智的决定。

很难想到保留寄存器的情况不会被误导。一个可能有用的示例是与跨语言/解释器进行交互。以上宏应作为一种快速的方法来通过保留寄存器在例程之间传递信息。

您不应该使用R0-R3,因为您将限制可以在例程之间传递的参数。ARM ABI通过R0-R3中的参数。鉴于您可以灵活地选择寄存器,因此选择R4-R9(甚至可能是R9是不限制的(,因为这些是" Callee"保存的寄存器,而无需任何特殊用途。同样,如果您选择R0-R3,则可以不是调用标准'C'库例程,或者保留的寄存器将保存在堆栈中。

参考: GCC本地寄存器变量
p>

最新更新