s5pv210的学习之路(3)函数调用的堆栈

从前面(2)可知道可以把lr返回地址放到堆栈里,可是arm的sp指针一直在动(比如分配局部变量),那么如何找到一个稳定的相对地址可以找到保存的lr以便弹出呢,所以引入ip以保存sp
mov ip,sp
sub sp,sp,#8
str r14,[sp]
str ip,[sp,#4]
s5pv210的学习之路(3)函数调用的堆栈
sub sp ,sp ,#100 @分配局部变量
add sp ,sp ,#100 @回收局部变量 ,成对出现

ldr r0,=fmt
mov r14,r15
ldr r15,show

ldr lr,[sp]
ldr ip,[sp,#4]
@这里有个隐患,如果sp的局部变量没有成对回收,这里就会出错,这时引入fp栈帧寄存器见下面改进的例子

mov sp,ip
mov r15,r14

show:
.word 0xc3e1528c
fmt:
.asciz “hello!\n”

新版本,引入fp栈帧寄存器

mov ip,sp
sub sp,sp,#12
str r14,[sp]
str ip,[sp,#4]
str fp,[sp,#8]
sub fp,ip,#4 @fp=ip-4
s5pv210的学习之路(3)函数调用的堆栈
ldr r0,=fmt
mov r14,r15
ldr r15,show

ldr lr,[fp,#-8]
ldr ip,[fp,#-4]
ldr fp,[fp,#0]
mov sp,ip
mov r15,r14

show:
.word 0xc3e1528c
fmt:
.asciz “hello!\n”

ARM中有专门指令做这个事情:
mov ip,sp
stmfd sp! ,{fp,ip,lr,pc} @这里多放了PC,为了调试用

代替下面四句:
sub sp,sp,#12
str r14,[sp]
str ip,[sp,#4]
str fp,[sp,#8]

恢复时候:
sub sp, fp,#12
ldmfs sp,{fp,sp ,pc}
@即lr->pc,ip ->sp fp ->fp

所以我们反汇编时候总是看到:
mov ip,sp
stmfd sp! ,{fp,ip,lr,pc}
sub fp,ip,#4

sub sp, fp,#12
ldmfs sp,{fp,sp ,pc}