gcc中的全局寄存器变量

时间:2014-12-08 15:24:47

标签: c gcc

最近我在接受采访时被问及全局寄存器变量。我搞砸了说任何全局变量都将存储在数据段中。但后来我被问及GCC。在采访后我得出结论gcc支持全局寄存器变量

#include<stdio.h>

register int var asm("ebx");  //storing global variable in register explicitly

int main(void)
{
.......
}

这是链接 https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars

但现在我对它的生命周期和范围感到困惑,以及它是作为普通的全局变量还是作为寄存器变量工作?还有任何方法或gcc上的命令,以便我们确保编译器不会简单地忽略register关键字并将存储在实际的寄存器中吗?

1 个答案:

答案 0 :(得分:5)

正如许多人所指出的那样,在全球范围内保留注册通常是一个坏主意。我相信这里的原始意图是(来自docs):

  

这在编程语言等程序中可能很有用   具有几个被访问的全局变量的解释器   经常。

这是否真的有用,或者只是让事情变得更糟可能只能针对特定情况来确定。在您的情况下(面试问题),这并不重要。

像这样的声明的范围就是看到声明的所有内容,正如您对任何全局声明所期望的那样。

然而,实施有点棘手。再次引用文档:

  

在某个寄存器储备中定义全局寄存器变量   完全注册用于此用途,至少在当前   汇编即可。该登记册不会被分配用于任何其他目的   当前编译中的函数,并没有保存和   通过这些功能恢复。

因此,使用该声明进行COMPILED的所有代码都将保留该用途的寄存器。但是,如果您链​​接到未使用此预留编译的其他代码,则不会将其保留用于此目的。

文档为qsort提供了一个很好的例子。如果您的代码是使用此声明编译的,然后它从c运行时调用qsort(可能是没有使用此声明编译),然后qsort调用回代码(对于compare函数),回调可以& #39;在调用比较函数之前,请确保qsort没有踩踏寄存器。

如果调用任何库函数可以踩踏寄存器,它怎么能工作?再次来自文档:

  

选择通常按功能保存和恢复的寄存器   在您的机器上调用,以便库例程不会破坏它。

即便如此:

  

从信号中访问全局寄存器变量是不安全的   处理程序,或来自多个控制线程,因为系统   库例程可以暂时使用寄存器来执行其他操作   (除非你专门针对手头的任务重新编译它们。)

至于问题的最后部分:

  

编译器不会简单地忽略register关键字并将存储在   实际登记册

我不确定你的意思。如果(某种程度上)编译器忽略了asm("ebx"),那么它将不会存储在寄存器中。使用它的关键是确保var存储在实际的ebx寄存器中。