在编译期间记录使用情况

时间:2019-01-26 09:34:27

标签: cpu cpu-registers nios

我发现以下信息:编译器使用通用寄存器r1-r23和r26-r28来存储局部变量,但是它们还有其他用途吗?该寄存器还属于(高速缓存/ RAM)哪个存储器? 最后,寄存器r26中的全局指针gp指向什么?

1 个答案:

答案 0 :(得分:2)

  

此寄存器还属于(缓存/ RAM)的哪个内存?

寄存器是处理器上的存储器,可实现快速数据传输(每个周期2读/ 1写)。它们存储可以表示内存地址的变量,但除此之外,它们与内存或缓存完全无关。

  

我发现以下信息:编译器使用通用寄存器r1-r23和r26-r28来存储局部变量,但是它们还有其他用途吗?

寄存器用于硬件或软件约定。硬件约定与指令集体系结构有关。例如,call指令将控制权转移到子例程,并将返回地址存储在寄存器r31 (ra)中。如果您在没有任何预防措施的情况下以任何方式覆盖r31注册,则可能会发生非常讨厌的事情。如果在软件中一致使用软件约定,则应确保行为正确。它们指示哪个寄存器有特殊用途,在上下文切换等时需要保存这些寄存器。无需更改硬件即可更改这些约定,但是这样做可能需要更改几个软件工具(编译器,链接器,加载器,OS等)。 )。

  

通用寄存器r1-r23和r26-r28被编译器用来存储局部变量

实际上,某些寄存器是保留的。

r1由asm用于宏扩展。 (SW)

r2-r7由编译器用来将参数传递给函数或获取返回值。 (SW)

r24-r25仅可由异常处理程序使用。 (SW)

r26-r28包含不同的指针(全局,堆栈,框架),这些指针是由运行时或编译器设置的,程序员无法对其进行修改。(sw)

r29-r31是经过硬件编码的子程序或中断/异常的返回地址。 (hw)

因此编译器只能使用r8-r23

  

但是他们还有其他目的吗?

否,这就是为什么编译器或程序员可以自由使用它们的原因。

  

最后,寄存器r26中的全局指针指向什么?

通过加载或存储访问内存具有基于内存的寻址。通过添加寄存器和立即数16位来计算ldxstx(其中'x'是b,bu,h等,取决于数据特性)的有效地址。这仅允许进入一个距离寄存器内容+/- 32k以内的地址。

如果处理器在寄存器中具有var的地址(例如malloc返回的值),则立即数允许进行位移以访问结构中的字段,下一个数组值等。 / p>

如果地址是本地或全局地址,则必须由程序计算。指针寄存器用于此目的。通过将立即数添加到堆栈指针(r27sp)来计算局部变量地址。

全局变量或静态变量的地址是通过将一个整数添加到全局指针(r26gp)来计算的。 gp的内容对应于内存数据段的开始,并且在程序执行之前由加载程序初始化,因此不得对其进行修改。链接器定义内存布局时,它会计算相对于数据段开始的立即位移。

请注意,由于16位立即宽度,这仅允许访问64k内存。如果全局/静态变量的大小超过此值,并且var不在此范围内,则需要几个指令来在数据传输之前输入var地址的32位。使用gp并不是必须的,它是一种提供对全局变量的更快访问的方法。