您的位置:首页 > 其它

关于arm汇编入栈和出栈的总结

2010-06-22 21:48 302 查看
用汇编进行函数内压栈和出栈往往使用如下的语句:

stmfd sp!, {r0-r9, lr} ; (1)给寄存器r0-r9, lr压栈

ldmfd sp!, {r0-r9, pc}; (2)给寄存器r0-r9出栈, 并使程序跳转回函数的调用点

stmfd 代表满递减入栈,即sp指向栈顶元素,每入栈一个元素,sp的值减4;

ldmfd 代表的是满递减出栈,正确的含义是sp指向栈顶元素,每出栈一个元素,sp值加4。

用TRACE32做实验可得下面的结果。

执行(1)之前的寄存器情况如下图:



图1

R13的值为0x5801FFE8, 保存11个寄存器,则入栈后地址应该是0x5801FFE8-11*4=0x

5801FFBC。

单步执行过(1)指令后,寄存器的情况如下图:



图2

注意R13 已经变成了0x5801FFBC.

再来看出栈后寄存器的情况,如下图:



图3

出栈以后R13值变回0x5801FFE8。

所以我们可以知道ldmfd 事实上是递增的。 用TRACE32可以看到stmfd和ldmfd这两个助记符对应的汇编指令,如下图:



图4

stmfd 对应的汇编指令,实际上是stmdb。



ldmfd对应的汇编指令,实际上是ldmia。

另外如果您认为入栈的顺序是从r0开始到r9再到lr您就错了。真正的顺序是正好相反的。这一点您可以观察图2看到寄存器入栈的真实顺序,r0的值0x08005000是位于栈顶的。

总结一下:

stmfd和ldmfd是配对使用的,stmfd=stmdb, ldmfd=ldmia

在“{}”中括着的寄存器的入栈顺序是从后向前,出栈顺序是从前向后。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: