5

我想知道,我们如何确保使用register说明符定义的变量是否存储在 CPU 寄存器中?

4

6 回答 6

10

基本上,你不能。C 标准中绝对没有任何内容可以让控制。

使用register关键字给编译器一个提示,即变量可能存储到寄存器中(即,允许最快的访问)。编译器可以随意忽略它。每个编译器可以有不同的方式来接受/拒绝提示

引用C11,第 §6.7.1 章,(强调我的

使用存储类说明符为对象声明标识符register 建议尽可能快地访问该对象。此类建议的有效程度由实施定义。

FWIW,大多数现代编译器可以检测最常用的变量,并在需要时将它们分配到实际寄存器中。请记住,CPU 寄存器是一种稀缺资源。

于 2016-04-29T11:48:22.463 回答
4

反汇编代码并检查。那时可能还不清楚,因为变量并不真正存在,它们只是将生产者与消费者联系起来的名称。因此,不一定为该变量保留一个寄存器 - 也许它完全消失了,也许它在其生命周期中存在于多个寄存器中,也许以上都不是。

于 2016-04-29T11:49:41.430 回答
1

从历史上看,该register关键字是在几十年前作为对编译器的优化提示引入的。如今,当处理器有更多的通用寄存器时,编译器通常会在没有被告知的情况下将变量放在寄存器中(当使用优化编译代码时)。

作为一个提示而不是强制执行,你不能做任何事情来强迫它。但是,您可以在汇编程序中编写该部分代码。这样您就可以完全控制变量的存储位置。

于 2016-04-29T11:54:04.893 回答
1

如果变量存储在寄存器中,则意味着它不存储在内存中。因此,靶心是尝试使用 printf 访问变量的地址。如果输出给出了一些地址,则结论是它存储在内存中,因此它将充当自动存储类变量(并且它不存储在寄存器中)。但是如果它给出错误“内置函数'printf'的不兼容隐式声明”..这意味着变量存储在寄存器中并且将表现为寄存器存储类变量..

于 2016-12-09T05:12:19.670 回答
0

也许调用汇编指令会有所帮助:

/// 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 );

}

于 2016-04-29T12:07:02.847 回答
0

我不知道我是对还是错,但是我们知道一个普通的变量存储在具有地址的内存中,但是我们知道如果我们写,register int a;那么可能会为该变量分配一个寄存器,但是我们知道寄存器有名称,而不是地址,所以我们不能分配指针指向寄存器,因为指针只存储地址,所以如果我们写如下: -

#include<stdio.h>
int main()
{
    register int reg = 5;
    int *p = &reg;
    printf("%d",reg);
}

如果寄存器已成功分配给我们的变量,那么它应该给出错误:“请求寄存器变量'reg'的地址”,如果没有分配寄存器,则可以将内存地址分配给指针,因此不应该出现错误。 重要提示:-这是我在stackoverflow上的第一个答案,我可能错了,如果我错了,请纠正我,我还在学习。

于 2021-04-16T05:29:47.600 回答