搜索
bottom↓
回复: 16

ARM 中R0-R15寄存器在函数调用中的作用

[复制链接]

出0入4汤圆

发表于 2022-11-6 21:23:14 | 显示全部楼层 |阅读模式
根据“ARM-thumb 过程调用标准”:

r0-r3    用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。

            被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。

r4-r11  被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。

r12        是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。
             在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。

13        是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。

r14        是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复

r15        是程序计数器 PC。它不能用于任何其它用途。
     

注意:在中断程序中,所有的寄存器都必须保护,编译器会自动保护R4~R11

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出5入14汤圆

发表于 2022-11-7 09:57:43 | 显示全部楼层
如果用 C 语言,这些都不用管吧?

出0入59汤圆

发表于 2022-11-7 10:07:57 | 显示全部楼层
函数嵌入汇编时,就要了解这些规则;

不过这些函数用得机会真不多,现在动辄多少核,多少GHZ

出0入0汤圆

发表于 2022-11-7 10:21:07 | 显示全部楼层
AAPCS和ATPCS能了解一下还是挺不错的

出0入0汤圆

发表于 2022-11-7 10:22:20 | 显示全部楼层
EMC菜鸟 发表于 2022-11-7 09:57
如果用 C 语言,这些都不用管吧?
(引用自2楼)

了解一下对调试有帮助

出0入0汤圆

发表于 2022-11-7 15:55:46 | 显示全部楼层
RTOS 在任务切换的时候,会用到这些

出0入0汤圆

发表于 2022-11-14 14:23:37 | 显示全部楼层
在C里面嵌入汇编代码时,有函数调用时,并不知道C语言函数里到底使用了哪些R4-R11里的哪些寄存器,只能把汇编代码里使用的寄存器先全部入栈,返回时再全部出栈

出0入42汤圆

发表于 2022-11-14 22:06:14 | 显示全部楼层
算法优化的时候有用
排查hardfault的时候有用

出5入4汤圆

发表于 2022-11-14 22:09:57 来自手机 | 显示全部楼层
看起来就几个寄存器啊,如果我们的函数参数比较多,临时变量也很多,看起来根本不够用,内核怎么处理的呢

出0入4汤圆

发表于 2022-11-14 22:12:38 | 显示全部楼层
tim4146 发表于 2022-11-14 22:09
看起来就几个寄存器啊,如果我们的函数参数比较多,临时变量也很多,看起来根本不够用,内核怎么处理的呢 ...
(引用自9楼)

现在芯片RAM好多都几十K

不用担心。其实临时变量一般放栈里。

出0入0汤圆

发表于 2022-11-15 07:12:01 来自手机 | 显示全部楼层
tim4146 发表于 2022-11-14 22:09
看起来就几个寄存器啊,如果我们的函数参数比较多,临时变量也很多,看起来根本不够用,内核怎么处理的呢 ...
(引用自9楼)

参数多尽量传指针  参数多了压栈传送
变量可太够用了 内存大着呢 你别在函数内开大数组就好

出300入477汤圆

发表于 2022-11-15 09:21:49 来自手机 | 显示全部楼层
bobde163 发表于 2022-11-14 14:23
在C里面嵌入汇编代码时,有函数调用时,并不知道C语言函数里到底使用了哪些R4-R11里的哪些寄存器,只能把汇 ...
(引用自7楼)

每个函数都需要有一些寄存器来完成自己的工作,因为所有的数据处理指令都只能操作寄存器。但是被你的代码调用的函数,以及调用你的代码的函数,非常可能在这个时候还不知道长啥样呢。
所以大家必须遵守相同的规则,到时候配合起来才能正常工作。
从别人调用方进到你的函数的时候,给你的R4-11是啥样,你返回的时候必须是原样。如果你内部想用它们就自己先压栈保存,返回前弹岀。同样的,你的代码去调用别的函数,你也不用保存你自己的这些寄存器,如果别人想用它就自己保存。
反过来,R0-3是不被保存的,谁都能随便用,也就是说进到你函数的时候,这几个寄存器或者是参数,或者没当参数你也能随便用,不必保存和恢复它们。同样的,如果你调用别人,你也得做好准备在调用完后别人会破坏掉这些寄存器。如果你还想使用它们的旧值要在之前自己保存。

出300入477汤圆

发表于 2022-11-15 09:31:31 来自手机 | 显示全部楼层
laujc 发表于 2022-11-14 22:12
现在芯片RAM好多都几十K

不用担心。其实临时变量一般放栈里。

(引用自10楼)

放栈里比寄存器慢。
别人设计cpu和调用规则的时候其实是算好了的,给你留了4个寄存器放参数,超过4个的才压栈。大部分函数是不会超过4个参数的。
当然如果你一进函数马上又要调用别人,你自己还得把这些参数寄存器压栈(调用别人会破坏参数寄存器),这是你的事。

出0入0汤圆

发表于 2022-11-17 10:43:30 | 显示全部楼层
redroof 发表于 2022-11-15 09:21
每个函数都需要有一些寄存器来完成自己的工作,因为所有的数据处理指令都只能操作寄存器。但是被你的代码 ...
(引用自12楼)

所以一般不建议在不熟悉arm函数调用参数传递规则的情况下在C代码中嵌入汇编代码,容易忽略寄存器的恢复导致汇编代码返回后出现程序异常,实在需要嵌入汇编代码需要严格检查,遵循规则

出0入89汤圆

发表于 2022-11-17 12:54:12 | 显示全部楼层
那么特斯拉把刹车识别成油门是不是某个寄存器越界而表面看起来又很难发现呢?

出0入309汤圆

发表于 2022-11-18 10:57:32 | 显示全部楼层
bobde163 发表于 2022-11-17 10:43
所以一般不建议在不熟悉arm函数调用参数传递规则的情况下在C代码中嵌入汇编代码,容易忽略寄存器的恢复导 ...
(引用自14楼)

如果使用inline assembly也未必需要了解这么多。把Clobber列好以后编译器会准备好参数恢复的问题的。
当然整个函数都用汇编写确实需要了解。

出40入42汤圆

发表于 2022-11-18 11:10:16 | 显示全部楼层
szjqt 发表于 2022-11-17 12:54
那么特斯拉把刹车识别成油门是不是某个寄存器越界而表面看起来又很难发现呢? ...
(引用自15楼)

我怀疑隔壁帖子是看了你这个回复而开的,哈哈
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 03:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表