一段简单的ARM汇编分析

假设代码段.text首地址为0x8054

错误的代码示例:

.text
.code 32
.global _start
_start:
    bl        main        @1. pc = 0x8054,lr = 0x0
    b         .
main:
    push      {lr}        @2. pc = 0x805c,lr = 0x8058
    bl        func1       @3. pc = 0x8060,lr = 0x8058    @栈1
    pop       {pc}        @
func1:
    bl        func2       @4. pc = 0x8068,lr = 0x8064
    mov       pc, lr      @6. pc = 0x806c,lr = 0x806c    @程序在此死循环,回不去主函数
func2:
    mov       pc, lr      @5. pc = 0x8070,lr = 0x806c

修正后:

.text
.code 32
.global _start
_start:
    bl        main        @1. pc = 0x8054,lr = 0x0
    b         .           @9. pc = 0x8058,lc = 0x8070    @栈空
main:
    push      {lr}        @2. pc = 0x805c,lr = 0x8058
    bl        func1       @3. pc = 0x8060,lr = 0x8058    @栈1
    pop       {pc}        @8. pc = 0x8064,lr = 0x8070    @栈3
func1:
    push      {lr}        @4. pc = 0x8068,lr = 0x8064
    bl        func2       @5. pc = 0x806c,lr = 0x8064    @栈2
    pop       {pc}        @7. pc = 0x8070,lr = 0x8070
func2:
    mov       pc, lr      @6. pc = 0x8074,lr = 0x8070

栈

两个程序的区别在于func1中有没有对lr寄存器进行压栈备份,由于前者没有备份,所以程序在连续跳转时丢失了回去的路。

因此在跳转指令bl被嵌套使用时,应该对lr寄存器进行压栈备份,在最后一层嵌套中使用mov pc, lr指令返回主调函数,然后逐层pop最终回到主函数.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值