简体   繁体   English

gcc中的全局寄存器变量

[英]Global register variables in gcc

Recently I was asked about global register variables in an interview.I messed up saying that any global variable will be stored in Data segment.But then i was asked about GCC.After interview i came to conclusion that gcc supports global register variables. 最近我在一次采访中被问到全局寄存器变量。我搞砸了说任何全局变量都将存储在数据段中。但后来我被问及GCC。在采访后我得出结论gcc支持全局寄存器变量。

#include<stdio.h>

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

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

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

But now i am confused about its lifetime and scope and whether it will work as normal global variable or as register variable? 但现在我对它的生命周期和范围感到困惑,是否它将作为普通的全局变量或寄存器变量工作? Also is there any method or some command on gcc so that we will be sure that compiler will not simply ignore register keyword and will be stored in actual register? gcc上还有任何方法或命令,以便我们确保编译器不会简单地忽略register关键字并存储在实际的寄存器中吗?

As a number of people have pointed out, reserving a register globally is generally a bad idea. 正如许多人所指出的那样,在全球范围内保留登记册通常是一个坏主意。 I believe the original intent here was (from the docs ): 我相信这里最初的意图是(来自文档 ):

This may be useful in programs such as programming language interpreters that have a couple of global variables that are accessed very often. 这在诸如编程语言解释器之类的程序中可能是有用的,这些程序语言解释器具有经常访问的几个全局变量。

Whether this is really useful, or just ends up making things worse can probably only be determined for specific cases. 这是否真的有用,或者只是让事情变得更糟可能只能针对特定情况来确定。 In your case (interview question), that isn't really important. 在您的情况下(面试问题),这并不重要。

The scope of a declaration like this is everything that sees the declaration, just as you would expect with any global declaration. 像这样的声明的范围就是看到声明的所有内容,正如您对任何全局声明所期望的那样。

However, implementation is a bit tricky. 但是,实现有点棘手。 Again, quoting from the docs: 再次引用文档:

Defining a global register variable in a certain register reserves that register entirely for this use, at least within the current compilation . 在某个寄存器中定义一个全局寄存器变量,该寄存器完全用于此用途, 至少在当前编译中 The register is not allocated for any other purpose in the functions in the current compilation, and is not saved and restored by these functions. 寄存器不会在当前编译的功能中分配用于任何其他目的,并且不会由这些功能保存和恢复。

So, all code that is COMPILED using that declaration will reserve the register for that use. 因此,使用该声明进行COMPILED的所有代码都将保留该用途的寄存器。 However, if you LINK to other code that was not compiled with this reservation, it will not be reserved for that purpose. 但是,如果您链​​接到未使用此预留编译的其他代码,则不会将其保留用于此目的。

The docs give an excellent example with qsort. 文档给出了qsort的一个很好的例子。 If your code is compiled with this declaration, and then it calls qsort from the c runtime (which presumably isn't compiled with this declaration), and then qsort calls back into your code (for the compare function), the callback can't be sure that qsort doesn't stomp on the register before calling your compare function. 如果您的代码是使用此声明编译的,然后它从c运行时调用qsort(可能不会使用此声明编译),然后qsort调用回代码(对于compare函数),回调不能在调用比较函数之前,请确保qsort没有踩踏寄存器。

How can this ever work if calling any library function can stomp on the register? 如果调用任何库函数可以踩踏寄存器,它怎么能工作? Again from the docs: 再次来自文档:

Choose a register that is normally saved and restored by function calls on your machine, so that library routines will not clobber it. 选择一个通常由机器上的函数调用保存和恢复的寄存器,这样库例程就不会破坏它。

Even at that: 即便如此:

It is not safe to access the global register variables from signal handlers, or from more than one thread of control, because the system library routines may temporarily use the register for other things (unless you recompile them specially for the task at hand). 从信号处理程序或多个控制线程访问全局寄存器变量是不安全的,因为系统库例程可能暂时将该寄存器用于其他事情(除非您专门针对手头的任务重新编译它们)。

As for the last part of your question: 至于你问题的最后部分:

compiler will not simply ignore register keyword and will be stored in actual register 编译器不会简单地忽略register关键字,而是存储在实际的寄存器中

I'm not sure what you mean. 我不确定你是什么意思。 If (somehow) the compiler ignored the asm("ebx") , then it would NOT be stored in a register. 如果(某种程度上)编译器忽略了asm("ebx") ,那么它就不会存储在寄存器中。 The whole point of using this is to ensure that var is stored in the actual ebx register. 使用它的全部要点是确保var存储在实际的ebx寄存器中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 gcc,未初始化的全局变量 - gcc, uninitialized global variables 为什么gcc(ARM)不使用全局寄存器变量作为源操作数? - Why gcc (ARM) aren't using Global Register Variables as source operands? 从gcc的内联汇编中引用全局变量 - referencing global variables from inline assembly in gcc 不能在 gcc 中使用全局变量 - Can't use global variables with gcc 为什么不能将注册变量设为全局变量? - Why cant register variables be made global? GCC 将寄存器 args 放在堆栈上,在局部变量下方有一个间隙? - GCC placing register args on the stack with a gap below local variables? 与gcc相比,为什么clang与寄存器变量表现得很奇怪? - Why does clang behave weirdly with register variables compared to gcc? 无论是否使用-c选项,gcc都不解析外部全局变量 - gcc does not resolve extern global variables, with or without -c option 为什么gcc垃圾回收对于已初始化的全局变量和未初始化的全局变量会有不同的行为? - Why gcc garbage collection behave differently for initialized global variables and uninitialized global variables? C语言标准是否指定了对全局寄存器变量的支持 - Do the C language standards specify support for global register variables
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM