ARM的栈帧
2016-07-19 14:09
253 查看
1. ARM的栈帧
先来看看ARM的栈帧布局图:
上图描述的是ARM的栈帧布局方式,main stack frame为调用函数的栈帧,func1 stack frame为当前函数(被调用者)的栈帧,栈底在高地址,栈向下增长。图中FP就是栈基址,它指向函数的栈帧起始地址;SP则是函数的栈指针,它指向栈顶的位置。ARM压栈的顺序很是规矩(也比较容易被黑客攻破么),依次为当前函数指针PC、返回指针LR、栈指针SP、栈基址FP、传入参数个数及指针、本地变量和临时变量。如果函数准备调用另一个函数,跳转之前临时变量区先要保存另一个函数的参数。
ARM也可以用栈基址和栈指针明确标示栈帧的位置,栈指针SP一直移动,相比于x86,ARM更为鲜明的特点是,两个栈空间内的地址(SP+FP)前面,必然有两个代码地址(PC+LR)明确标示着调用函数位置内的某个地址。
2. ARM的汇编指令和栈操作
ARM微处理器共有37个寄存器,其中31个为通用寄存器,6个为状态寄存器。但是这些寄存器不能被同时访问,具体哪些寄存器是可编程访问的,取决于微处理器的工作状态及具体的运行模式。但在任何时候,通用寄存器R0~R15、一个或两个状态寄存器都是可访问的。有三个特殊的通用寄存器:
寄存器R13:在ARM指令中常用作堆栈指针SP
寄存器R14:也称作子程序连接寄存器(Subroutine Link Register)即连接寄存器LR
寄存器R15:也称作程序计数器PC
ARM进行函数内压栈和出栈往往使用如下的语句:
stmfd sp!, {r0-r9, lr} ; 满递减入栈,给寄存器r0-r9,lr压栈,sp不断减4
ldmfd sp!, {r0-r9, pc} ; 满递减出栈,给寄存器r0-r9出栈,并使程序跳转回函数的调用点,sp不断增4
常用的函数内外跳转指令有mov和BL,ARM有两种跳转方式:
(1)mov pc, <跳转地址〉
这种向程序计数器PC直接写跳转地址,能在4GB连续空间内任意跳转。
(2)通过 B BL BLX BX 可以完成在当前指令向前或者向后32MB的地址空间的跳转(为什么是32MB呢?寄存器是32位的,此时的值是24位有符号数,所以32MB?后面再查查看)。B是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——是相对当前PC值的一个偏移量,它的值由汇编器计算得出。BL很常用,它在跳转之前会在寄存器LR(R14)中保存PC的当前内容。BL的经典用法如下:
bl NEXT ; 跳转到NEXT
……
NEXT
……
mov pc, lr ; 从子程序返回。
原文:http://blog.chinaunix.net/uid-16459552-id-3364761.html
先来看看ARM的栈帧布局图:
上图描述的是ARM的栈帧布局方式,main stack frame为调用函数的栈帧,func1 stack frame为当前函数(被调用者)的栈帧,栈底在高地址,栈向下增长。图中FP就是栈基址,它指向函数的栈帧起始地址;SP则是函数的栈指针,它指向栈顶的位置。ARM压栈的顺序很是规矩(也比较容易被黑客攻破么),依次为当前函数指针PC、返回指针LR、栈指针SP、栈基址FP、传入参数个数及指针、本地变量和临时变量。如果函数准备调用另一个函数,跳转之前临时变量区先要保存另一个函数的参数。
ARM也可以用栈基址和栈指针明确标示栈帧的位置,栈指针SP一直移动,相比于x86,ARM更为鲜明的特点是,两个栈空间内的地址(SP+FP)前面,必然有两个代码地址(PC+LR)明确标示着调用函数位置内的某个地址。
2. ARM的汇编指令和栈操作
ARM微处理器共有37个寄存器,其中31个为通用寄存器,6个为状态寄存器。但是这些寄存器不能被同时访问,具体哪些寄存器是可编程访问的,取决于微处理器的工作状态及具体的运行模式。但在任何时候,通用寄存器R0~R15、一个或两个状态寄存器都是可访问的。有三个特殊的通用寄存器:
寄存器R13:在ARM指令中常用作堆栈指针SP
寄存器R14:也称作子程序连接寄存器(Subroutine Link Register)即连接寄存器LR
寄存器R15:也称作程序计数器PC
ARM进行函数内压栈和出栈往往使用如下的语句:
stmfd sp!, {r0-r9, lr} ; 满递减入栈,给寄存器r0-r9,lr压栈,sp不断减4
ldmfd sp!, {r0-r9, pc} ; 满递减出栈,给寄存器r0-r9出栈,并使程序跳转回函数的调用点,sp不断增4
常用的函数内外跳转指令有mov和BL,ARM有两种跳转方式:
(1)mov pc, <跳转地址〉
这种向程序计数器PC直接写跳转地址,能在4GB连续空间内任意跳转。
(2)通过 B BL BLX BX 可以完成在当前指令向前或者向后32MB的地址空间的跳转(为什么是32MB呢?寄存器是32位的,此时的值是24位有符号数,所以32MB?后面再查查看)。B是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——是相对当前PC值的一个偏移量,它的值由汇编器计算得出。BL很常用,它在跳转之前会在寄存器LR(R14)中保存PC的当前内容。BL的经典用法如下:
bl NEXT ; 跳转到NEXT
……
NEXT
……
mov pc, lr ; 从子程序返回。
原文:http://blog.chinaunix.net/uid-16459552-id-3364761.html
相关文章推荐
- 找出一个数组中重复次数最多的数
- Java hashCode() 方法深入理解
- Jenkins + Saucelabs+ Curl上传被测app 到saucelabs storage
- JNI接口函数
- Unity3D中常用的数据结构总结与分
- oc中常用的占位符
- TDK 磁环
- ADB常用命令汇总
- 用java打开文件夹
- Linux 下复制(cp)目录时排除一个或者多个目录的方法
- fiddler 使用方法汇总
- 关于unicorn 的 worker_processes
- centos之lnmp
- centos7配置ip地址
- Android应用被强制停止后无法接受广播解决方案
- h5新标签和css3动画制作一个鼠标悬停的动画效果
- Redis cluster搭建
- Maven 的安装配置 (eclipse)
- 「添加购物」功能交互演示
- 【知乎网】Linux IO 多路复用 是什么意思?