c中分配给函数参数的最大寄存器数

时间:2018-08-16 11:50:32

标签: c function compiler-optimization

我知道C编译器会向函数参数分配一些寄存器,以增强对函数内部参数的访问,从而使代码更快。但是我不确定这些寄存器的数量(我已经读过/听到过的不同数量)。
有4个或5个寄存器用于此目的吗?
还是可能依赖于编译器/硬件?
是否有相关参考?

2 个答案:

答案 0 :(得分:7)

这个问题非常笼统,因为并非所有功能都相同(例如:一个编译为在x86上的Windows上运行的函数与一个编译为在ARM上的Linux上运行的函数)

简而言之,取决于:

编译器可以支持多个ABI,或者具有自己的专有调用约定或特定的优化方法。

答案 1 :(得分:0)

这取决于ABI,它是硬件,实现和部分依赖OS的组件。 https://en.wikipedia.org/wiki/Calling_convention

例如:

  

ARM(A32)

     

标准的32位ARM调用约定分配了15   通用寄存器为:

     

r14是链接寄存器。 (在子例程调用中使用的BL指令将返回地址存储在此寄存器中)。   r13是堆栈指针。 (在“ Thumb”操作模式下的Push / Pop指令仅使用该寄存器)。   r12是过程内调用暂存寄存器。   r4至r11:用于保存局部变量。   r0到r3:用于保存传递给子例程的参数值,还保留从子例程返回的结果。

     

第16个寄存器r15是程序计数器。

     

如果返回的值的类型太大而无法适合r0到r3,或者   其大小无法在编译时静态确定,则   调用者必须在运行时为此值分配空间,并传递   指向r0中该空间的指针。

     

子例程必须保留r4到r11的内容以及堆栈   指针。 (也许通过将它们保存到函数中的堆栈中   序幕,然后将它们用作暂存空间,然后从   函数结尾中的堆栈)。特别是,   调用其他子例程必须将返回地址保存在链接中   在调用其他子例程之前,将r14注册到堆栈。   但是,此类子例程无需将该值返回给r14,它们   只需要将该值加载到程序计数器r15中即可   返回。

     

ARM调用约定要求使用全降序堆栈。[14]

     

此调用约定使“典型” ARM子例程进入

     

在序言中,将r4到r11压入堆栈,然后将r14中的返回地址压入堆栈。 (这可以通过一个STM完成   指令)。   将所有传递的参数(在r0至r3中)复制到本地暂存寄存器(r4至r11)。   将其他局部变量分配给其余的局部暂存寄存器(r4至r11)。   假设不保存r0至r3,r12和r14,则使用BL进行计算并根据需要调用其他子例程。   将结果放入r0   在结语中,将r4从堆栈拉到r11,并将返回地址拉到程序计数器r15。 (这可以通过   单个LDM指令)。