什么是ATPCS规则?

举报
樊心昊 发表于 2020/06/26 18:03:02 2020/06/26
【摘要】 摘要:当我们想通过arm汇编调用一个c语言的函数时,并且该函数需要参数,这时就要根据ATPCS规则来进行传参了。什么是ATPCS规则? ATPCS规则全程“ARM-THUMB procedure call standard”,ARM汇编过程调用标准。我们在通过ARM汇编编写代码时,比如STM32的Startup.S文件、单片机的操作系统任务调度相关汇编文件、UBOOT等,有时无法...

摘要:当我们想通过arm汇编调用一个c语言的函数时,并且该函数需要参数,这时就要根据ATPCS规则来进行传参了。

什么是ATPCS规则?

       ATPCS规则全程“ARM-THUMB procedure call standard”,ARM汇编过程调用标准。

我们在通过ARM汇编编写代码时,比如STM32的Startup.S文件、单片机的操作系统任务调度相关汇编文件、UBOOT等,有时无法避免或者说是为了方便,我们会通过ARM汇编调用一个C语言的函数,例如bl printf,这是该函数需要一个或者多个参数,我们该如何把参数传给该函数呢?

       ATPCS中规定了,只需要将函数需要的参数写到特定寄存器中,即可完成传参操作。

image.png

该表格摘自--《The ARM-THUMB Procedure Call Standard》在附件中为大家上传。

注意这里的r0-r3寄存器,这4个寄存器可以用于传入函数的参数或者接收函数的返回值,在调用函数之前将要传给函数的参数通过mov指令或者ldr指令存入r0-r3寄存器中即可完成传参。

细心的同学到这里应该会问我:“如果参数超过了4个怎么办呢?”,这里假设有6个参数,首先将前四个按照顺序存入r0-r3寄存器中,第6个和第5个参数,按照从后向前的顺序压入数据栈中,因为出栈和入栈的顺序相反,为了让函数使用参数方便,所以压栈是从最后以一个参数开始压,在出栈时,就可以依次取到第4个、第5个参数来使用了。

这里又可以引入一个知识点,这就是前辈们告诉我们编写函数时,参数不要超过4个的原因,因为会降低程序的效率。

函数的返回值也是通过r0-r3寄存器来返回的,例如:

返回一个大小为32位的数据,通过r0返回。

返回一个大小为64位的数据,通过r0+r1返回。

返回一个大小为96位的数据,通过r0+r1+r2返回。

返回一个大小为128位的数据,通过r0+r1+r2返回。

超过128以后的数据就要采用内存的方式传递了,一般不会这样做,比如我们要返回一个结构体的数据,那么就在堆中为这个结构体分配内存并写入数据,然后放回指向该结构体的指针即可。

现在来讲解r4-r11寄存器,假设要使用int add(int a, int b)函数,作用是传入2个参数,返回这两个参数的和,其中使用了局部变量,比如我们通过r0和r1寄存器给该函数传参,在函数中我们需要通过mov r4, r0和mov r5, r1,将两个参数读到“局部变量寄存器”中存储和使用,然后我们可以使用add语句来相加r4和r5的值,如果大小没有超过32位,则最终存储到r0寄存器中,函数返回,在汇编中调用bl add语句后,读取r0的值,即可获得该函数的执行返回值。

r13寄存器为数据栈指针也就是我们常说的SP,指向栈顶地址,并且寄存器SP在进入子程序时的值和退出子程序时的值必须相等,也就是说bl add函数执行之前的sp地址必须等于bl add函数之后之后的sp地址。

r14寄存器为返回地址寄存器也就是我们常说的LR,用于在函数执行之前保存该函数的下一条指令的地址,也就是说执行bl add函数之前,将bl add这条指令的下一条指令的地址保存的lr寄存器中,当add函数执行完毕后,根据lr寄存其中的值返回到下一条指令的位置继续执行程序(将lr寄存器中的值读到pc中就可以完成返回)。

r15寄存器为程序计数器也就是我们常说的PC,这个程序“计数器”可以翻译的有点不恰当,它保存了当前指令地址+4(Thumb)或者+8(ARM)的值,为何要+4或者+8这个涉及到“流水线”的概念,以后再说,大家目前只要知道我们可以将某个指令的地址写到PC中,程序就会跳转到该指令开始执行,在执行bl add指令之前,可以将当前pc的值保存到lr寄存器中,这样函数执行完毕后才能找到返回地址。

 

总结:ATPCS规则就是定义了函数传参以及返回数据的标准,定义了寄存器在函数调用时的作用,详细的内容大家可以自行查阅我在附件中上传的官方文档,你也可以试试能不能自己找到这个官方文档,这里给个提示“这是ARM公司提出的”。


    附件下载

  • ATPCS.pdf 165.42KB 下载次数:8
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。