在调用C函数时,C函数也会用到一些寄存器,如果不保存的话在退出时,之前调用这个C函数的函数或汇编代码就不能正常运行了。所以一定是需要保存那些被动过的寄存器。
那保存寄存器是在调用函数前保存呢还是在进入函数后保存呢?哪些寄存器需要保存呢。
我用的环境是ARM7,ARMv4的汇编指令集。编译器是ADS1.2
------解决方案--------------------
标准arm系列中,除cortex-M系列,其他的寄存器保存都是软件来做的,原则就是你需要用到哪些寄存器就保存哪些寄存器,每种编译器和arm自己都会有规范(arm的是EABI),传递参数用哪几个,返回值用谁,栈用谁,这些都是规范已经定义好的,编译器清楚地知道在当前函数体中有哪几个寄存器会被改变,于是就会在函数开始时将这些寄存器统统压栈,另外在多数情况下,lr也是必须要压栈的(记录着函数返回地址相关信息)。
如果你自己写纯汇编代码(注意,是纯汇编,不能和其他语言函数互相调用)就可以不遵守这些规范,随意用自己的寄存器组合来操作,只需要记住一个准则,将可能被修改的寄存器压栈。切记有两个寄存器不能随便用,就是pc和lr。
------解决方案--------------------
如果你跟踪汇编代码,确实在函数调用中没有使用到r0或者r1,但是又真的被改变了,那么你需要考虑是不是因为中断或者某种类型的exception中有函数调用用到了这几个寄存器,当然arm的模式切换会导致寄存器组切换,不过在某些情况下还是会改变当前模式的寄存器。
另外你提到了SWI,SWI指令就会影响寄存器,它是保护式操作系统的系统调用的基本实现方式。