是否可以将整个数组保存在cpu寄存器中

时间:2013-06-27 12:14:47

标签: c compiler-construction embedded microcontroller microprocessors

在下面的代码中,

int main( )
{
    register int arr[4];
    /* ... */
}

是否有可能在某些cpu寄存器中分配'arr'。 (考虑到cpu有4个或更多寄存器)。

或者编译器会忽略数组的 register 存储类。

5 个答案:

答案 0 :(得分:11)

根据我的理解,答案是 YES NO

因为,

  1. 任何数组元素必须是显式可寻址的(例如,对于16位uC / uP,其地址应始终位于0x0000至0xFFFF地址空间之间。)

  2. 使用寄存器直接寻址模式(例如 mov r2,#100 )访问CPU寄存器。 该寻址模式没有有效地址。 (即使它不被视为寻址模式

  3. 数组元素必须驻留在连续的内存位置。 (对于指针运算,使用数组的主要原因)

  4. 因为,

    1. 编译器可以为上面的数组分配寄存器,这样我们就可以对它执行一些有限的操作。 但是不能使用内部使用地址进行优化的操作。
    2. 见下面的代码。

      int main( )
      {
        register int arr[4];
        int i;
      
        arr[0] = 10;      /* OK */
        arr[1] = 20;      /* OK */
        arr[2] = 30;      /* OK */
        arr[3] = 40;      /* OK */
      
        for(i=0;i<4;i++)
          arr[i]=10;    /* Error : "address of register variable 'arr' requested" */
      
        return 0;
      }
      

      所以我最后的结论是,理想情况下 register 存储类永远不应该与数组一起使用,即使您的编译器允许它。

      请更正我或提供更多意见。 : - )

答案 1 :(得分:8)

不要将register作为关键字与CPU寄存器混合使用。你的代码

register int arr[4];

使arr完全无法访问,因为您无法获取对象的地址。基本上你唯一能做的就是sizeof arr

答案 2 :(得分:6)

我写了这段代码:

int foo(int x, int y)
{
    register int a[2] = {x, y};
    return a[0] + a[1];
}

并使用Apple clang 4.0版用cc -O3 -std=c99 -S编译它,并生成此程序集(省略了各种调试和无关的装饰):

_foo:
    pushq   %rbp
    movq    %rsp, %rbp
    addl    %esi, %edi
    movl    %edi, %eax
    popq    %rbp
    ret

因此,从某种意义上说,数组保存在寄存器中。但是,这更像是一个优化工件,而且所有对数组的引用都是通过常量索引而不是register关键字。所以答案是“嗯,从理论上讲,它可能会发生。但它很少或没有实际用途,你通常不能依赖它。“

某些处理器具有可索引的寄存器,例如ARM处理器上的NEON寄存器,其中包含可在某些指令中独立寻址(通过立即值)的多个值。我可以设想编译器在NEON寄存器中保留一小组值并独立访问它们,前提是源代码引用可以在编译时解析为常量。

答案 3 :(得分:5)

C89标准不允许对寄存器存储类的变量采取地址或任何类似操作(至少我没有的草案:3.5.1,参见注释49)。它甚至提到只有sizeof运算符对这样的数组有效。 C99标准是指6.7.1中的寄存器存储类,其中注释103声明与C89草案完全相同。

总而言之,寄存器存储类和数组实际上不应该混合在一起。声明本身是有效的,但从技术上讲它是没用的。

否则一般情况下,如果您有疑问,请检查反汇编列表。一些针对8位控制器的编译器可能会做一些令人惊讶的事情。

答案 4 :(得分:1)

优化编译器可能会临时分配它认为适合CPU寄存器的任何数组元素,并且只会在那里进行操作。

但如果你问是否有可能强制该阵列注册,那么我不知道如何做到这一点。对于单变量(在gcc中),您可以使用&#34;显式寄存器变量&#34; (见http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html)。