C语言中寄存器变量(数据类型:寄存器)的概念?

时间:2010-09-28 19:11:09

标签: c memory

我只想了解如何在C程序可执行文件中处理寄存器变量。即在嵌入式系统和X86机器(桌面PC中可执行的C程序)的情况下,它在哪个位置(或寄存器)准确存储?

这个观点怎么样? (如果我错了,请纠正我)

假设我们已将函数内的一个变量声明/初始化为'int'数据类型。通常它会进入堆栈段,只有在运行时,当调用者调用包含局部变量的被调用者时,它才会出现在该部分中。但是如果我们将上面的局部变量声明为'register int',那么它也将转到堆栈段。但是在运行时,处理器将堆栈中的局部变量放入其通用寄存器位置(因为'register'关键字导致额外的编译器插入代码)以及从那里快速访问它。

这是它们之间的唯一区别是在运行时访问,并且它们之间没有内存加载差异。

__ Kanu

5 个答案:

答案 0 :(得分:10)

C中的register关键字(很少见过)只是编译器的提示,将变量保存在寄存器中以便更快访问可能会有用。

编译器可以自由地忽略提示,并在最佳情况下进行优化。

由于现代编译器在理解使用和速度方面要比人类好得多,现代编译器通常会忽略register关键字,在某些情况下,实际上可能会降低执行速度。

答案 1 :(得分:7)

来自K& R C:

  

寄存器变量建议   编译器认为变量有问题   将被大量使用。这个想法就是这样   寄存器变量将被放入   机器寄存器,可能导致   较小的&更快的程序。但   编译器可以自由地忽略这一点   建议。

无论变量是否实际放在寄存器中,都无法获取寄存器变量的地址。

因此,

register int x;
int *y = &x; // is illegal  

所以,你必须权衡无法获得寄存器变量的地址。

答案 2 :(得分:4)

除了加密的回答(我的投票),只需将关键字的名称register视为历史用词不当。它与您在类中学习的寄存器没什么关系,例如冯·诺依曼处理器模型,但只是提示编译器该变量不需要地址。

在现代机器上,无地址变量可以通过不同的方式实现(例如,立即汇编运算符)或完全优化。将变量标记为register可能是编译器的有用优化提示,也是程序员的有用规则。

答案 3 :(得分:1)

当编译器获取其内部代码并且后端将其转换为目标处理器的机器/汇编程序时,它会跟踪它在创建代码时生成指令的寄存器。如果有未使用的工作变量需要分配寄存器来加载或跟踪变量,那么它会将其标记为已使用并使用该寄存器生成指令。但是如果所有工作寄存器中都有某些内容,那么它通常会将某个寄存器中的某个寄存器的内容逐出,通常是ram,例如全局内存或堆栈(如果该变量有一个寄存器)。编译器可能或可能不聪明该决定,并可能驱逐高度使用的变量。通过使用register关键字,根据编译器,您可能会影响该决策,它可以选择将寄存器关键字变量保存在寄存器中,并根据需要将非注册关键字变量驱逐到内存。

答案 4 :(得分:0)

  

在嵌入式系统和>的情况下,它准确地存储哪个位置(或寄存器)。 X86机器(可在桌面PC中执行的C程序)?

如果没有打开汇编输出,你就不知道了,这可能会根据编译器的选择而改变。最好只为教育目的检查装配。

如果需要精确读写特定寄存器,则应在汇编模块中编写内联汇编或链接。

通常在为x86 / amd64(gcc,icc,cl)使用标准C编译器时,您可以合理地假设编译器将在大多数情况下充分优化。

但是,如果您使用的是非标准编译器,例如,为新的嵌入式系统做了准备,那么考虑手动优化是个好主意。如果架构是新的,那么考虑手动优化可能也是一个好主意。