使用寄存器存储类声明变量时使用了多少个寄存器?

时间:2017-08-10 13:13:10

标签: c cpu-registers storage-class-specifier

我的问题很简单,C编译器将使用register存储类声明的变量使用多少个寄存器: register int a。我已经阅读了这个答案How many register and what kind of register are available for the storage class REGISTER in c language但是不太了解。我知道它可以依赖于实现,但是这个寄存器是有限的,所以什么时候编译器会忽略声明或者它会产生错误?

2 个答案:

答案 0 :(得分:4)

C11仍支持register

  

具有存储类的对象的标识符声明   说明符寄存器表明对对象的访问速度最快   可能。这些建议有效的程度如下   实现定义的。

在笔记中:

  

实施可以将任何注册申报简单地视为   自动申报。

那么将使用多少个寄存器?一个可能的答案是'none',因为关键字可能会被忽略。

也就是说,在实践中,在任何现代平台上实现的定义int的宽度都比典型平台“word”的宽度宽,这是非常罕见的。因此,如果某个实现尊重register int a;,则register int a不太可能分配给多个寄存器,register int a可能是0,1或2个寄存器。

当然,在某些硬件上,并非所有寄存器都具有相同的大小,有时不同的指令将寄存器视为单独或连接。多少个寄存器可能没有意义。

正如其他人所指出的那样,在C中广泛不鼓励使用关键字。的确,它的含义现在从C ++中删除了(尽管关键字保留为保留)。

我认为这在C语言中是严苛的,它仍然关注微控制器环境,程序员最接近想要指定这些细节。

所有这些都说'回到当天'(25年前)我使用的编译器忽略了register但是将前2个(我认为)声明的变量分配给了寄存器,并且在这种情况下问题是函数中的第三个循环是最长的,并且通过首先声明大循环索引来显着改善性能。

这一切似乎很久以前,没有人应该把它作为现代经验。

答案 1 :(得分:0)

register建议编译器尽可能将变量保存在寄存器中。但现代编译器却忽略了它。所以回答你的问题 - 根据所使用的优化选项,编译器可以决定零或更多。

有些编译器在寄存器中有特殊形式的binging变量。

gcc版

       register int *foo asm ("r12");

它可以是全局或本地绑定。

全局绑定:寄存器变量保存在整个程序执行的寄存器中,寄存器从编译寄存器池中取出。它可以使编译器优化效率降低。

本地绑定:寄存器变量仅在函数范围内与寄存器绑定。

但不能保证在没有-ffixed-reg选项的情况下编译的库例程会使该寄存器不受影响。同样适用于setjump& longjump因为恢复寄存器的内容是特定于机器的。

需要深入了解机器代码生成才能有效地使用它。现在很少使用。使用示例 - 减少响应中断请求的等待时间等。