C -谁决定实际存储的寄存器存储类



最近在面试中被问到以下几个问题:谁实际决定寄存器变量将存储在哪里(RAM或寄存器)。

我在谷歌上搜索过,然后我得到了编译器的决定。但是编译器如何决定呢?根据我的理解,这应该在运行时决定。

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

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

使用存储类说明符register声明对象的标识符表明对该对象的访问尽可能快。这些建议的有效程度是由实现定义的。

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

假设我们有一个非常naïve的编译器,它完全按照我们说的做,不优化任何东西。如果我们给它这样的代码:

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

后者更有效,因为它更喜欢寄存器访问而不是内存访问。在实践中,现代编译器具有智能寄存器分配算法,使得该存储类说明符不再需要。

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

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

授予对变量的寄存器访问权的请求是由程序发出的,但是,最终是由编译器决定变量在寄存器中的内存分配,这取决于:-

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

  2. 更稳定的优化等

相关内容

  • 没有找到相关文章

最新更新