【问题标题】:How do make sure if a variable defined with "register" specifier got stored in CPU register?如何确保使用“寄存器”说明符定义的变量是否存储在 CPU 寄存器中?
【发布时间】:2016-04-29 11:46:29
【问题描述】:

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

【问题讨论】:

  • 由于您使用过去时,我将您的问题解释为“我如何找出编译器做了什么”而不是“我如何强迫它做某事”,但似乎没有人其他人是这么看的——你能澄清一下你的意思吗?
  • 代码可以使用int a; register int b; int c;,然后检查a,c的地址是否连续。当然,这并不能证明 b 在寄存器中,但它暗示b 可能在也可能不在寄存器中。

标签: c cpu-registers register-keyword


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          }

          【讨论】:

            【解决方案6】:

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

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

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

            【讨论】:

            • 在具有 register 说明符的对象上使用 address-of 运算符始终是语法错误。它实际上是否在 CPU 寄存器中并不重要。 register 关键字更多地是关于 storage durationlinkage 而不是优化器提示。
            • 谢谢你的指正,这意味着对于一个新手来说很难确定一个寄存器是否分配给一个变量。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-23
            • 1970-01-01
            • 2012-07-22
            • 2021-03-25
            • 2018-01-14
            • 2013-04-01
            相关资源
            最近更新 更多