谁决定寄存器存储类的实际存储?

时间:2015-05-18 06:11:18

标签: c compiler-construction compilation compiler-optimization storage-class-specifier

最近我在接受采访时被问到以下问题: 谁实际上决定寄存器变量将存储在哪里(在RAM或寄存器中)。

我在google上搜索过,我得到了编译器的决定权。 但编译器如何决定?应根据我的理解在运行时决定。

如果我们在不同的机器上编译运行程序,那么编译器如何决定存储寄存器存储类值的位置。

2 个答案:

答案 0 :(得分:3)

register存储类说明符是编译器的提示,访问变量应该“尽可能快”,这意味着(在寄存器体系结构上)应该将其存储分配给寄存器。这禁止了一些事情,比如取变量寄存器的地址没有地址。但是,编译器可以自由地忽略这个提示(§6.7.1¶5):

  

具有存储类说明符register的对象的标识符声明建议尽可能快地访问对象。这些建议有效的程度是实施定义的。

编译代码时,编译器必须选择如何将局部变量和算术运算映射到CPU寄存器和堆栈存储器上的操作。这称为寄存器分配;这些决定是在编译时完成的,并且被编入函数的编译代码中。

假设我们有一个非常天真的编译器,它正是我们所说的,并没有优化任何东西。如果我们给它这个代码:

int x;
x = 2;
x += 5;

然后我们可能希望在x86机器上看到此输出:

sub esp, 4          ; allocate stack space for an integer
mov dword [esp], 2
add dword [esp], 5

但如果我们写:

register int x;
x = 2;
x += 5;

然后我们可能会看到:

mov eax, 2
add eax, 5

后者更有效,因为它更喜欢通过内存访问进行寄存器访问。在实践中,当代编译器具有智能寄存器分配算法,这使得该存储类说明符不必要。

答案 1 :(得分:1)

编译器在编译期间进行了几种类型的优化,并且根据这些优化,请求被授予或拒绝。

  

编译的第三个阶段---中间代码生成保持生成基于中间三地址(操作码)的基础   编码,在第二个最后阶段进一步优化   编译器的优化。编译器的最后阶段--- target code generation使得它保证了寄存器是否存储   类变量将被授予注册表。

授予寄存器访问变量的请求由程序完成,但最后,编译器根据以下内容决定寄存器中变量存储器的分配: -

  1. CPU中寄存器的可用性。

  2. 更稳定的优化等。