SCREA 发表于 2022-11-6 21:23:14

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

根据“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

EMC菜鸟 发表于 2022-11-7 09:57:43

如果用 C 语言,这些都不用管吧?

polarbear 发表于 2022-11-7 10:07:57

函数嵌入汇编时,就要了解这些规则;

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

azeng 发表于 2022-11-7 10:21:07

AAPCS和ATPCS能了解一下还是挺不错的

vuo50z 发表于 2022-11-7 10:22:20

EMC菜鸟 发表于 2022-11-7 09:57
如果用 C 语言,这些都不用管吧?
(引用自2楼)

了解一下对调试有帮助

52HLX 发表于 2022-11-7 15:55:46

RTOS 在任务切换的时候,会用到这些

bobde163 发表于 2022-11-14 14:23:37

在C里面嵌入汇编代码时,有函数调用时,并不知道C语言函数里到底使用了哪些R4-R11里的哪些寄存器,只能把汇编代码里使用的寄存器先全部入栈,返回时再全部出栈

wshtyr 发表于 2022-11-14 22:06:14

算法优化的时候有用
排查hardfault的时候有用

tim4146 发表于 2022-11-14 22:09:57

看起来就几个寄存器啊,如果我们的函数参数比较多,临时变量也很多,看起来根本不够用,内核怎么处理的呢

laujc 发表于 2022-11-14 22:12:38

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

现在芯片RAM好多都几十K

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

huangqi412 发表于 2022-11-15 07:12:01

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

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

redroof 发表于 2022-11-15 09:21:49

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

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

redroof 发表于 2022-11-15 09:31:31

laujc 发表于 2022-11-14 22:12
现在芯片RAM好多都几十K

不用担心。其实临时变量一般放栈里。
(引用自10楼)

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

bobde163 发表于 2022-11-17 10:43:30

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

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

szjqt 发表于 2022-11-17 12:54:12

那么特斯拉把刹车识别成油门是不是某个寄存器越界而表面看起来又很难发现呢?

iamseer 发表于 2022-11-18 10:57:32

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

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

落叶知秋 发表于 2022-11-18 11:10:16

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

我怀疑隔壁帖子是看了你这个回复而开的,哈哈{:titter:}
页: [1]
查看完整版本: ARM 中R0-R15寄存器在函数调用中的作用