如何确定用 "register" 说明符定义的变量是否存储在 CPU 寄存器中?
How do make sure if a variable defined with "register" specifier got stored in CPU register?
我想知道,我们如何确定用 register
说明符定义的变量是否存储在 CPU 寄存器中?
基本上,你不能。 C 标准中绝对没有任何东西可以让 你 控制。
使用 register
关键字给编译器一个 提示 变量 可能 存储到寄存器中(即, 允许尽可能快的访问)。编译器可以忽略它。每个编译器都可以有不同的方式 accepting/rejecting hint.
引用 C11
,章节 §6.7.1,(强调我的)
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.
FWIW,大多数现代编译器可以检测最常用的变量并将它们分配到实际寄存器中,如果需要。请记住,CPU 寄存器是一种稀缺资源。
反汇编代码并检查。那时可能还不是很清楚,因为变量并不真正存在,它们只是 link 生产者和消费者的名称。因此,不一定有为该变量保留的寄存器 - 也许它完全消失了,也许它在其生命周期中存在于多个寄存器中,也许是上面的 none。
从历史上看,register
关键字是在几十年前作为对编译器的优化提示引入的。现在,当处理器有更多的通用寄存器时,编译器通常会在没有被告知的情况下将变量放在寄存器中(当代码经过优化编译时)。
这只是一个提示而不是强制执行,您不能做任何事情来强制执行它。但是,您可以用汇编程序编写该部分代码。这样您就可以完全控制变量的存储位置。
也许调用汇编指令会有所帮助:
/// Function must be something like this:
int check_register_storing()
{
__asm__ (
pushad // Save registers
and ebx, ebx // Set Zero
and eax, eax
and ecx, ecx
and edx, edx
);
// Set test number.
register int a = 8; // Initial value;
int from_register = 0;
asm(
add eax, ebx // If, 'a' variable set on CPU register,
add eax, ecx // Some of main usage registers must contain 8
add eax, edx // Others must contain 0
mov %from_register, eax
popad // Return default parameters to registers
}
/// Check result
printf( "Original saved number: %d, Returned number from main registers: %d\n", a, from_register );
}
如果变量存储在寄存器中意味着它没有存储在内存中。
因此,靶心是尝试使用 printf 访问变量的地址。如果输出给出了一些地址,结论是它存储在内存中,因此它将充当自动存储 class 变量(并且它不存储在寄存器中)。
但如果它给出错误 "incompatible implicit declaration of built-in function 'printf' "..这意味着变量存储在寄存器中并且将表现为寄存器存储 class 变量..
我不知道我是对还是错,但是我们知道一个普通的变量存储在有地址的内存中,但是我们知道如果我们写register int a;
那么可能会分配一个寄存器对于变量,但是我们知道寄存器有名称,没有地址,所以我们不能将指针指向寄存器,因为指针只存储地址,所以如果我们这样写:-
#include<stdio.h>
int main()
{
register int reg = 5;
int *p = ®
printf("%d",reg);
}
如果寄存器已成功分配给我们的变量,则它应该给出错误:“请求的寄存器变量‘reg’的地址”,如果寄存器未分配,则可以将内存地址分配给指针,因此应该没有错误在那里。
重要提示:-这是我在 Whosebug 上的第一个答案,我可能错了,如果我错了请纠正我,我还在学习。
我想知道,我们如何确定用 register
说明符定义的变量是否存储在 CPU 寄存器中?
基本上,你不能。 C 标准中绝对没有任何东西可以让 你 控制。
使用 register
关键字给编译器一个 提示 变量 可能 存储到寄存器中(即, 允许尽可能快的访问)。编译器可以忽略它。每个编译器都可以有不同的方式 accepting/rejecting hint.
引用 C11
,章节 §6.7.1,(强调我的)
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.
FWIW,大多数现代编译器可以检测最常用的变量并将它们分配到实际寄存器中,如果需要。请记住,CPU 寄存器是一种稀缺资源。
反汇编代码并检查。那时可能还不是很清楚,因为变量并不真正存在,它们只是 link 生产者和消费者的名称。因此,不一定有为该变量保留的寄存器 - 也许它完全消失了,也许它在其生命周期中存在于多个寄存器中,也许是上面的 none。
从历史上看,register
关键字是在几十年前作为对编译器的优化提示引入的。现在,当处理器有更多的通用寄存器时,编译器通常会在没有被告知的情况下将变量放在寄存器中(当代码经过优化编译时)。
这只是一个提示而不是强制执行,您不能做任何事情来强制执行它。但是,您可以用汇编程序编写该部分代码。这样您就可以完全控制变量的存储位置。
也许调用汇编指令会有所帮助:
/// Function must be something like this:
int check_register_storing()
{
__asm__ (
pushad // Save registers
and ebx, ebx // Set Zero
and eax, eax
and ecx, ecx
and edx, edx
);
// Set test number.
register int a = 8; // Initial value;
int from_register = 0;
asm(
add eax, ebx // If, 'a' variable set on CPU register,
add eax, ecx // Some of main usage registers must contain 8
add eax, edx // Others must contain 0
mov %from_register, eax
popad // Return default parameters to registers
}
/// Check result
printf( "Original saved number: %d, Returned number from main registers: %d\n", a, from_register );
}
如果变量存储在寄存器中意味着它没有存储在内存中。 因此,靶心是尝试使用 printf 访问变量的地址。如果输出给出了一些地址,结论是它存储在内存中,因此它将充当自动存储 class 变量(并且它不存储在寄存器中)。 但如果它给出错误 "incompatible implicit declaration of built-in function 'printf' "..这意味着变量存储在寄存器中并且将表现为寄存器存储 class 变量..
我不知道我是对还是错,但是我们知道一个普通的变量存储在有地址的内存中,但是我们知道如果我们写register int a;
那么可能会分配一个寄存器对于变量,但是我们知道寄存器有名称,没有地址,所以我们不能将指针指向寄存器,因为指针只存储地址,所以如果我们这样写:-
#include<stdio.h>
int main()
{
register int reg = 5;
int *p = ®
printf("%d",reg);
}
如果寄存器已成功分配给我们的变量,则它应该给出错误:“请求的寄存器变量‘reg’的地址”,如果寄存器未分配,则可以将内存地址分配给指针,因此应该没有错误在那里。 重要提示:-这是我在 Whosebug 上的第一个答案,我可能错了,如果我错了请纠正我,我还在学习。