谁决定寄存器存储的实际存储class?
who decide actual storage of register storage class?
最近在面试中被问到以下问题:
谁真正决定寄存器变量将存储在哪里(在 RAM 或寄存器中)。
我在 google 上搜索过,我得到的答案是由编译器决定的。
但是编译器如何决定呢?按照我的理解,应该在运行的时候决定。
如果我们在不同的机器上编译和 运行 程序会怎么样,那么编译器如何决定将寄存器存储 class 值存储在何处。
编译器进行了几种类型的优化,在编译时根据这些优化,请求被批准或拒绝。
The third last phase of compilation --- intermediate code generation keeps the basis of generating an intermediate three-address(opcode) based
coding,which is further optimised in the second last phase of
compiler-optimisation. The last phase of compiler --- target
code generation
makes it guaranteed whether the register storage
class variable will be granted the register or not.
授予对变量的寄存器访问权限的请求是由程序发出的,但是,最终由编译器决定变量在寄存器中的内存分配取决于:-
CPU 中寄存器的可用性。
更稳定的优化等
register
storage class 说明符提示编译器访问变量应该“尽可能快”,暗示(在寄存器架构上)它的存储应该是分配给一个寄存器。这禁止了一些事情,比如获取变量的地址——寄存器没有地址。但是,编译器可以随意忽略此提示 (§6.7.1¶5):
A declaration of an identifier for an object with storage-class specifier register
suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.
编译代码时,编译器必须选择如何将局部变量和算术运算映射到 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
后者更有效,因为它更喜欢寄存器访问而不是内存访问。实际上,现代编译器具有智能寄存器分配算法,使此存储 class 说明符变得不必要。
最近在面试中被问到以下问题: 谁真正决定寄存器变量将存储在哪里(在 RAM 或寄存器中)。
我在 google 上搜索过,我得到的答案是由编译器决定的。 但是编译器如何决定呢?按照我的理解,应该在运行的时候决定。
如果我们在不同的机器上编译和 运行 程序会怎么样,那么编译器如何决定将寄存器存储 class 值存储在何处。
编译器进行了几种类型的优化,在编译时根据这些优化,请求被批准或拒绝。
The third last phase of compilation --- intermediate code generation keeps the basis of generating an intermediate three-address(opcode) based coding,which is further optimised in the second last phase of compiler-optimisation. The last phase of compiler ---
target code generation
makes it guaranteed whether the register storage class variable will be granted the register or not.
授予对变量的寄存器访问权限的请求是由程序发出的,但是,最终由编译器决定变量在寄存器中的内存分配取决于:-
CPU 中寄存器的可用性。
更稳定的优化等
register
storage class 说明符提示编译器访问变量应该“尽可能快”,暗示(在寄存器架构上)它的存储应该是分配给一个寄存器。这禁止了一些事情,比如获取变量的地址——寄存器没有地址。但是,编译器可以随意忽略此提示 (§6.7.1¶5):
A declaration of an identifier for an object with storage-class specifier
register
suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.
编译代码时,编译器必须选择如何将局部变量和算术运算映射到 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
后者更有效,因为它更喜欢寄存器访问而不是内存访问。实际上,现代编译器具有智能寄存器分配算法,使此存储 class 说明符变得不必要。