关于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
在“{}”中括着的寄存器的入栈顺序是从后向前,出栈顺序是从前向后。
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
在“{}”中括着的寄存器的入栈顺序是从后向前,出栈顺序是从前向后。
相关文章推荐
- 关于ARM汇编中字符串表达式及运算符总结
- ARM汇编中关于“.word”伪指令的概念
- ARM汇编里面的关于cpsid.n中的.n解释
- 关于ARM汇编中使用宏定义的处理
- 学 Win32 汇编[18]: 关于压栈(PUSH)与出栈(POP) 之二
- ARM--汇编总结
- arm汇编总结---让汇编不再神秘
- 关于ARM汇编程序的理解
- ARM第一个项目中关于C的总结
- 关于IAR的一些总结 -- ARM调试和Flash调试的区别
- GNU ARM汇编--(二十)总结
- ARM汇编程序中的伪指令同义词总结
- 《基于Linux嵌入式原理与应用开发》总结_ARM裸机程序_汇编程序
- 关于汇编ARM指令DCD
- 关于c与汇编混合编程的一点总结
- arm编程,关于C函数中嵌入汇编和寄存器变量的混合使用方法。用汇编透视c语法操作
- 【摘录】ARM汇编程序中的伪指令同义词总结
- ARM汇编中的LDR指令总结
- 影响CPSR状态寄存器的ARM汇编指令--总结
- 国嵌ARM 上学期专题3之汇编语言玩得转 常见问题解决方案和知识点总结