我知道C编译器为函数参数分配了一些寄存器,以增强对函数内参数的访问,从而加快代码的速度。但我不确定这些寄存器的数量(不同的数字,我读过/听到)。
是否有4或5个登记册作此用途?
或者它可能依赖于编译器/硬件?
有什么参考资料吗?
发布于 2018-08-16 12:01:47
这个问题是非常普遍的,因为并非所有函数都是相同的(例如:编译用于在x86上的windows上运行的函数,而在ARM上运行的函数)。
简言之,它取决于:
编译器可以支持多个ABI,或者有自己的专有调用约定或特定的优化。
发布于 2018-08-16 12:05:44
这取决于ABI,而ABI是硬件、实现和部分操作系统的退步。convention
例如:
ARM (A32) 标准的32位ARM调用约定将15个通用寄存器分配为: r14是链接寄存器。(在子程序调用中使用的BL指令将返回地址存储在此寄存器中)。r13是堆栈指针。(“拇指”操作模式中的Push/Pop指令仅使用此寄存器)。r12是过程内调用划痕寄存器.r4到r11:用于保存局部变量。r0 to r3:用于保存传递给子例程的参数值,还保存从子例程返回的结果。 第16寄存器,r15,是程序计数器。 如果返回的值类型太大,无法适应r0到r3,或者其大小不能在编译时静态确定,则调用方必须在运行时为该值分配空间,并在r0中传递指向该空间的指针。 子程序必须保留r4到r11的内容和堆栈指针。(也许可以将它们保存到函数序言中的堆栈中,然后将它们用作划痕空间,然后从函数结尾的堆栈中恢复它们)。特别是,调用其他子程序的子程序在调用其他子程序之前必须将链接寄存器r14中的返回地址保存到堆栈中。但是,这样的子程序不需要将该值返回给R14--它们只需要将该值加载到程序计数器r15中才能返回。 ARM调用约定授权使用一个全面下降的堆栈。 此调用约定导致“典型”ARM子例程 在序言中,将r4推到r11到堆栈,并将r14中的返回地址推送到堆栈。(这可以通过一个STM指令来完成)。将任何传递的参数(在r0到r3中)复制到本地划痕寄存器(r4到r11)。将其他局部变量分配到剩余的本地划痕寄存器(r4到r11)。根据需要使用BL进行计算和调用其他子程序,假设r0到r3、r12和r14不会被保留。将结果放入r0中,从堆栈中将r4拉到r11,并将返回地址拉到程序计数器r15。(这可以通过一条LDM指令来完成)。
https://stackoverflow.com/questions/51876389
复制相似问题