本文通过分析一个简单函数的保护现场和恢复现场,来理解FP和SP指针。
DSP中有几个指针是有特殊用途的,AR0为FP指针,AR1为SP指针,AR2、AR3、AR4和AR5可以自由使用,也就是说,在函数执行过程中可以修改,也不必恢复。AR6和AR7用作寄存器变量。如果在函数中被修改,必须加以保护和恢复。
- int add(int a, int b, int c)
- {
- int nSum = 0;
- nSum = a + b + c;
- return nSum;
- }
- 汇编代码如下:
- add: ;进入函数ARP为1
- POPD *+ ;保存函数返回地址
- SAR AR0, *+ ;保存FP指针
- SAR AR1, * ;保存SP指针
- LAR AR0,#2h ;加载局部帧长度,即局部变量的个数+1
- LAR AR0,*0+,AR2 ;旧FP = 旧SP,新SP = 旧SP + 2,ARP = 2
- LACL #0h
- LAR AR2,#1h ;AR2 = 1
- MAR *0+ ;AR2 = AR2 + AR0
- SACL *,0 ;AR2内容置0
- SETC SXM
- SBRK #4h ;AR2 = AR2 - 4
- ;内存排列入下:
- ;参数C,返回地址,旧FP,旧SP,AR2.这时AR2指向参数C
- LACC *-,0 ;加载c,AR2 = AR2 - 1
- ADD *-,0 ;ACC += b, AR2 = AR2 - 1
- ADD *,0 ;ACC += a
- ADRK #6h ;内存排列入下:
- ;参数A(AR2),B,C,返回地址,旧FP,旧SP, (计算之前)。
- ;AR2 += 6,返回到AR2开始计算之前的地址
- SACL *,0 ;赋值给nSum
- LACC *,0 ;加载到ACC,做返回值
- MAR *,AR1 ;切换到AR1
- SBRK #3h ;撤消局部帧,AR1回到旧FP的位置
- LAR AR0,*- ;恢复FP
- PSHD * ;返回地址压栈
- RET