我只想了解如何在C程序可执行文件中处理寄存器变量。即在嵌入式系统和X86机器(桌面PC中可执行的C程序)的情况下,它在哪个位置(或寄存器)准确存储?
这个观点怎么样? (如果我错了,请纠正我)
假设我们已将函数内的一个变量声明/初始化为'int'数据类型。通常它会进入堆栈段,只有在运行时,当调用者调用包含局部变量的被调用者时,它才会出现在该部分中。但是如果我们将上面的局部变量声明为'register int',那么它也将转到堆栈段。但是在运行时,处理器将堆栈中的局部变量放入其通用寄存器位置(因为'register'关键字导致额外的编译器插入代码)以及从那里快速访问它。
这是它们之间的唯一区别是在运行时访问,并且它们之间没有内存加载差异。
__ Kanu
答案 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编译器时,您可以合理地假设编译器将在大多数情况下充分优化。
但是,如果您使用的是非标准编译器,例如,为新的嵌入式系统做了准备,那么考虑手动优化是个好主意。如果架构是新的,那么考虑手动优化可能也是一个好主意。