c - gcc 中的全局寄存器变量

标签 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 关键字并将存储在实际寄存器中?

最佳答案

正如许多人指出的那样,在全局范围内保留寄存器通常不是一个好主意。我相信这里的初衷是(来自 docs ):

This may be useful in programs such as programming language interpreters that have a couple of global variables that are accessed very often.

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

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

但是,实现起来有点棘手。再次引用文档:

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.

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

文档给出了一个很好的 qsort 示例。如果你的代码是用这个声明编译的,然后它从 c 运行时调用 qsort(大概不是用这个声明编译的),然后 qsort 回调到你的代码中(用于比较函数),回调不能在调用您的比较函数之前,请确保 qsort 不会踩踏寄存器。

如果调用任何库函数都可以踩到寄存器,这怎么能起作用呢?再次来自文档:

Choose a register that is normally saved and restored by function calls on your machine, so that library routines will not clobber it.

即便如此:

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).

至于你问题的最后一部分:

compiler will not simply ignore register keyword and will be stored in actual register

我不太清楚你的意思。如果(不知何故)编译器忽略了 asm("ebx"),那么它就不会存储在寄存器中。使用它的全部意义在于确保 var 存储在实际的 ebx 寄存器中。

关于c - gcc 中的全局寄存器变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361194/

相关文章:

c - 应该相同但会发生变化的值

c - 使用循环打印结构

转换为非标量类型

c - 如何在 Code::Blocks 中生成程序集列表?

c++ - gcc 4.9 递归 lambda 返回时的内部编译器错误

c - 如何链接linux/gpio.h?

c - 参数的字节大小会影响不透明函数调用的开销吗?

c - 一种在两个 10 位数字之间找到正交路径的算法

c - lua51 c 共享库问题

c - 为什么 GCC 开始警告取空表达式的地址?