创建时间: | 2022/1/11 21:37 |
更新时间: | 2022/1/11 21:43 |
作者: | gi51wa2j |
标签: | bingo, C, 汇编, 细节知识 |
参考资料:
在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规则,ATPCS规定了一些函数间调用的基本规则。
ATPCS即ARM-THUMB procedure call standard(ARM-Thumb过程调用标准)的简称,是基于ARM指令集和THUMB指令集过程调用的规范,规定了调用函数如何传递参数,被调用函数如何获取参数,以何种方式传递函数返回值。
寄存器R0~R15在ATPCS规则的使用:
在函数中,通过寄存器R0~R3来传递参数,被调用的函数在返回前无需恢复寄存器R0~R3的内容
在函数中,通过寄存器R4~R11来保存局部变量
寄存器R12用作函数间scratch寄存器
寄存器R13用作栈指针,记作SP,在函数中寄存器R13不能用做其他用途,寄存器SP在进入函数时的值和退出函数时的值必须相等
寄存器R14用作链接寄存器,记作LR,它用于保存函数的返回地址,如果在函数中保存了返回地址,则R14可用作其它的用途
寄存器R15是程序计数器,记作PC,它不能用作其他用途
当参数小于等下4个时,使用寄存器R0~R3来进行参数传递
当参数大于4个时,前四个参数按照上面方法传递,剩余参数传送到栈中,入栈的顺序与参数顺序相反,即最后一个参数先入栈(参数从后往前入栈)
结果为一个32位的整数时,通过寄存器R0返回
结果为一个64位整数时,通过R0和R1返回,依此类推.
结果为一个浮点数时,通过浮点运算部件的寄存器f0,d0或s0返回
结果为一个复合的浮点数时,通过寄存器f0-fN或者d0~dN返回
对于位数更多的结果,通过调用内存来传递
总的来说,栈的作用就是:保存现场/上下文,传递参数
保存现场/上下文
保存现场,也叫保存上下文
现场,相当于案发现场,总有一些现场的情况,要记录下来的,否则被别人破坏掉之后,你就无法恢复现场了。而此处说的现场,就是指CPU运行的时候,用到了一些寄存器,比如R0~R3,LR等等,对于这些寄存器的值,如果你不保存而直接跳转到函数中去执行,那么很可能会被破坏了,因为函数执行需要用到这些寄存器。
因此在函数调用之前,应该将这些寄存器等现场,暂时保持起来,等调用函数执行完毕返回后,再恢复现场,这样CPU就可以正确的继续执行了。
保存寄存器的值,一般用的是push指令,将对应的某些寄存器的值,一个个放到栈中,即所谓的入栈。
然后待被调用的子函数执行完毕的时候,再调用pop,把栈中的一个个的值,赋值给对应的入栈的寄存器,即所谓的出栈。
传递参数
当函数被调用并且参数大于4个时,(不包括第4个参数)第4个参数后面的参数就保存在栈中。