AAPCS_C函数与汇编函数之间参数及返回值传递方法.docx

AAPCS_C函数与汇编函数之间参数及返回值传递方法.docx

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
AAPCS_C函数与汇编函数之间参数及返回值传递方法

PAGE4 / NUMPAGES4 C函数与汇编函数之间参数及返回值传递方法 AAPCS(ARM Application Procedure Call Standard)对ARM结构的一些标准做了定义,在这里我们只重点介绍函数调用部分,如图1所示,AAPCS为ARM的R0~R15寄存器做了定义,明确了它们在函数中的职责: 图 1 AAPCS关于ARM寄存器的定义 函数调用时的规则如下: 1. 父函数与子函数间的入口参数依次通过R0~R3这4个寄存器传递。父函数在调用子函数前先将参数存入到R0~R3中,若只有一个参数则使用R0传递,2个则使用R0和R1传递,依次类推,当超过4个参数时,其它参数通过栈传递。当子函数运行时,根据自身参数个数自动从R0~R3或者栈中读取参数。 2. 子函数通过R0寄存器将返回值传递给父函数。子函数返回时,将返回值存入R0,当返回到父函数时,父函数读取R0获得返回值。 3. 发生函数调用时,R0~R3是传递参数的寄存器,即使是父函数没有参数需要传递,子函数也可以任意更改R0~R3寄存器,无需考虑会破坏它们在父函数中保存的数值,返回父函数前无需恢复其值。AAPCS规定,发生函数调用前,由父函数将R0~R3中有用的数据压栈,然后才能调用子函数,以防止父函数R0~R3中的有用数据被子函数破坏。 4. R4~R11为普通的通用寄存器,若子函数需要使用这些寄存器,则需要将这些寄存器先压栈然后再使用,以免破坏了这些寄存器中保存的父函数的数值,子函数返回父函数前需要先出栈恢复其数值,然后再返回父函数。AAPCS规定,发生函数调用时,父函数无需对这些寄存器进行压栈处理,若子函数需要使用这些寄存器,则由子函数负责压栈,以防止父函数R4~R11中的数据被破坏。 5. 编译器在编译时就确定了函数间的调用关系,它会使函数间的调用遵守3、4条规定。但编译器无法预知中断函数的调用,被中断的函数无法提前对R0~R3进行压栈处理,因此需要在中断函数里对它所使用的R0~R11压栈。对于中断函数,不遵守第3条规定,遵守第5条规定。 6. R12寄存器在某些版本的编译器下另有它用,用户程序不能使用,因此我们在编写汇编函数时也必须对它进行压栈处理,确保它的数值不能被破坏。 7. R13寄存器是堆栈寄存器(SP),用来保存堆栈的当前指针。 8. R14寄存器是链接寄存器(LR),用来保存函数的返回地址。 9. R15寄存器是程序寄存器(PC),指向程序当前的地址。 上述只介绍了本手册中使用到的情形,具体的情况在编写操作系统代码时会涉及到,其它规则请请读者自行查找资料。 接下来我们再通过几个小例子熟悉一下C函数与汇编函数的调用过程。下面的C函数TestFunc1与汇编函数TestFunc2的功能是一样的。 U8 TestFunc1(void) { U8 ucPara1; U8 ucPara2; U8 ucPara3; U8 ucPara4; U8 ucPara5; U8 ucPara6; ucPara1 = 1; ucPara2 = 2; ucPara3 = 3; ucPara4 = 4; ucPara5 = 5; ucPara6 = 6; return ucPara1 + ucPara2 + ucPara3 + ucPara4 + ucPara5 + ucPara6; } .func TestFunc2 TestFunc2: STMDB R13!, {R5 - R6, R10} @R5,R6,R10寄存器压栈 LDR R1, =1 LDR R3, =2 LDR R4, =3 LDR R5, =4 LDR R6, =5 LDR R10, =6 ADD R0, R1, R3 ADD R0, R0, R4 ADD R0, R0, R5 ADD R0, R0, R6 ADD R0, R0, R10 LDMIA R13!, {R5 - R6, R10} @R5,R6,R10寄存器出栈 .endfunc TestFunc2函数使用了R0、R1、R3、R4、R5、R6、R10共7个寄存器,遵循AAPCS规则,在使用R0、R1和R3之前并没有对它们压栈,但对R5、R6和R10寄存器进行了压栈保存,在函数返回前又出栈还原了这3个寄存器,这样TestFunc2函数返回到它的父函数之后,R5、R6和R

文档评论(0)

haihang2017 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档