ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:18.31KB ,
资源ID:8330816      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8330816.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(arm堆栈的那些事.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

arm堆栈的那些事.docx

1、arm堆栈的那些事学习arm,对堆栈的了解不能不深入!下面带你进入arm堆栈操作的世界:arm堆栈操作arm堆栈的组织结构是 满栈降 的形式,满栈即sp是要停留在最后一个进栈元素,降:就是堆栈的增长方向是从高地址向低地址发展。arm对于堆栈的操作一般采用 LDMFD(pop)和STMFD (push) 两个命令。以前困惑的就是STMFD 命令 对于操作数 是按照什么顺序压栈的比如:STMFD sp!R0-R5,LR 进栈顺序是:高地址(1方式)LRR5R4R0 -sp低地址还是:高地址(2方式)R0R1R5LR -sp低地址现在通过下表,可以轻松的解决这个问题:寻址方式说明pop=LDMpus

2、h=STMFA递增满LDMFALDMDASTMFASTMIBFD递减满LDMFDLDMIASTMFDSTMDBEA递增空LDMEALDMDBSTMEASTMIAED递减空LDMEDLDMIBSTMEDSTMDA按照图表,可知 STMFD对应的是STMDB,根据arm指令手册,可知STMDB入栈顺序是(1方式)而LDMFD对应的是LDMIA,这样这两个操作就可以成功配对:以下是我在学习ARM指令中记录的关于堆栈方面的知识1、寄存器 R13 在 ARM 指令中常用作堆栈指针2、对于 R13 寄存器来说,它对应6个不同的物理寄存器,其中的一个是用户模式与系统模式共用,另外5个物理寄存器对应于其他5种

3、不同的运行模式。采用以下的记号来区分不同的物理寄存器: R13_ 其中,mode为以下几种模式之一:usr、fiq、irq、svc、abt、und。3、寄存器R13在ARM指令中常用作堆栈指针,但这只是一种习惯用法,用户也可使用其他的寄存器作为堆栈指针。而在Thumb指令集中,某些指令强制性的要求使用R13作为堆栈指针。由于处理器的每种运行模式均有自己独立的物理寄存器R13,在用户应用程序的初始化部分,一般都要初始化每种模式下的R13,使其指向该运行模式的栈空间,这样,当程序的运行进入异常模式时,可以将需要保护的寄存器放入R13所指向的堆栈,而当程序从异常模式返回时,则从对应的堆栈中恢复,采用

4、这种方式可以保证异常发生后程序的正常执行。4、有四种类型的堆栈:堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。同时,根据堆栈的生成方式,又可以分为递增堆栈(Ascending Stack)和递减堆栈(DecendingStack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就

5、有四种类型的堆栈工作方式,ARM 微处理器支持这四种类型的堆栈工作方式,即: Full descending 满递减堆栈堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。 ARM-Thumb过程调用标准和ARM、Thumb C/C+ 编译器总是使用Full descending 类型堆栈。 Full ascending 满递增堆栈堆栈首部是低地址,堆栈向高地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。 Empty descending 空递减堆栈堆栈首部是低(这里是不是错了,应该是高地址吧)地址,堆栈向高地址增长。栈

6、指针总是指向下一个将要放入数据的空位置。 Empty ascending 空递增堆栈堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向下一个将要放入数据的空位置。5、操作堆栈的汇编指令堆栈类型 入栈指令 出栈指令 Full descending STMFD (STMDB) LDMFD (LDMIA) Full ascending STMFA (STMIB) LDMFA (LDMDA) Empty descending STMED (STMDA) LDMED (LDMIB) Empty ascending STMEA (STMIA) LDMEA (LDMDB)例子: STMFD r13!, r0

7、-r5 ; Push onto a Full Descending Stack LDMFD r13!, r0-r5 ; Pop from a Full Descending Stack.例子1) 保护现场参数,不影响PC,嵌汇编的时候对之前的存参数的寄存器R0R12保存STMFD r13!, r0-r7,LRLDMFD r13!, r0-r7,PC2) ARM汇编中lr(r14)寄存器的作用lr(r14)的作用问题,这个lr一般来说有两个作用:1.当使用bl或者blx跳转到子过程的时候,r14保存了返回地址,可以在调用过程结尾恢复。2.异常中断发生时,这个异常模式特定的物理R14被设置成该异常

8、模式将要返回的地址。另外注意pc,在调试的时候显示的是当前指令地址,而用mov lr,pc的时候lr保存的是此指令向后数两条指令的地址,大家可以试一下用mov pc,pc,结果得到的是跳转两条指令,这个原因是由于arm的流水线造成的,预取两条指令的结果.3.我们看到的LR值是上一个子程序调用保存的子程序返回地址,这个LR是要赋给PC的。嵌入式汇编要手动保存返回地址,进行现场保护。PC记录当前运行的地址。下一条回自己+4进入子程序,LR才自动更新为返回地址值,PC为程序运行地址ARM汇编嵌套子程序几个星期前阅读了(加)Carl Hamacher、 Zvonko Vranesic、 Safwat

9、Zaky编写的计算机组成第五版中的ARM子程序调用的一些知识,启发很大,顺便将它整理了一下并加入了自己的理解。子程序1 通过寄存器传递参数BL指令通常用于调用一个子程序。它和B指令的区别在于它将返回地址装载到R14中。由于子程序可能是嵌套的,因此LR的内容必须保存在子程序所使用的堆栈中。下面的例子使用寄存器传递参数。调用者通过寄存器R1和R2分别将数组的大小和数组的首地址传递给子程序;子程序利用寄存器R0将和传递给调用者。该子程序使用了寄存器R3,必须将它和LR推入堆栈。调用程序LDR R1, NLDR R2, POINTERBL LISTADDSTR R0, SUM子程序LISTADD ST

10、MFD R13!, R3, R14MOV R0, #0LOOP LDR R3, R2, #4ADD R0, R0, R3SUBS R1, R1, #1BGT LOOPLDMFD R13!, R3, R15注:这里并没有遵守APCS(ARM过程调用标准),一般由调用者负责保存R0R3,被调用者负责保存其他的寄存器以使调用返回后程序的状态不被破坏。2 通过堆栈传递参数调用程序LDR R0, POINTER STR R0, R13, #-4! ;将数组首地址推入堆栈LDR R0, NSTR R0, R13, #-4! ;将元素个数N推入堆栈BL LISTADDLDR R0, R13, #4 ;将元素

11、和装载到寄存器R0中STR R0, SUMADD R13, R13, #8 ;恢复堆栈子程序LISTADD STMFD R13!, R0-R3, R14LDR R1, R13, #20LDR R2, R13, #24MOV R0, #0LOOP LDR R3, R2, #4ADD R0, R0, R3SUBS R1, R1, #1BGT LOOPSTR R0, R13,#24 ;把和推入堆栈的最深处LDMFD R13!, R0-R3, R15R0R1R2R3返回地址NPOINTER/SUM3 嵌套子程序当子程序嵌套时,堆栈是用于处理返回地址的最合适的数据结构。当调用子程序时在堆栈上建立了完整的

12、堆栈结构。应当注意当前子程序的堆栈帧指针所指向的空间中存储的是调用当前子程序的子程序的堆栈帧指针。调用者将子程序所需要的参数按照顺序推入堆栈。子程序首先保存工作寄存器、调用者的堆栈帧指针以及返回地址,然后它计算自己的堆栈帧指针的值(ADD FP, SP, #16),并利用这个堆栈帧指针从堆栈帧中获取调用者传递给它的参数。在子程序完成它的任务之后,它也将返回值保存在堆栈中,此例保存在参数所在的内存单元。调用者和被调用者必须约定好参数的传递顺序和返回值保存位置。如果返回值比较多的话,调用者要为返回值预先在堆栈中保留合适的空间。调用程序2000 LDR R0, PARAM2 STR R0, SP,

13、#-4! ;将参数推入堆栈LDR R0, PARAM1STR R0, SP, #-4! BL SUB12020 LDR R0, SP ;保存SUB1的结果STR R0, RESULTADD SP, SP, #8 ;恢复堆栈子程序2100 SUB1 STMFD SP!, R0-R3, FP,LRADD FP, SP, #16 ;计算帧指针LDR R0, FP, #8 ;载入参数1LDR R1, FP, #12 ;载入参数2LDR R2, PARAM3 ;载入参数3STR R2, SP, #-4! ;将参数3推入堆栈BL SUB22164 LDR R2, SP, #4 ;将SUB2的结果弹出并存储

14、在R2中,并递增SPSTR R3, FP, #8 ;将结果推入堆栈LDMFD SP!, R0-R3, FP, PC ;恢复寄存器并返回3000 SUB2 STMFD SP!, R0, R1, FP, LRADD FP, SP, #8 ;载入结构指针LDR R0, FP, #8 ;载入参数STR R1, FP, #8 ;将结果推入堆栈LDMFD SP!, R0, R1, FP, PCR0 from SUB1R1 from SUB1FP from SUB12164/返回地址param3/SUB2的结果最后保存在这里R0 from mainR1 from mainR2 from mainR3 from mainFP from main2020/返回地址param1/SUB1的结果最后保存在这里param2原栈顶3 子程序编译后都放在哪嵌汇编子程序:会在编译后统一放到一个地方 系统调用_main()库函数,后再进入main.c前的初始化C下面的堆栈命令前(这个堆栈是用来放置C里参数的)嵌汇编子程序:按定义顺序放在堆栈前,而C语言子程序,放在初始化堆栈堆栈命令后。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1