【问题标题】:LDR instruction as memory jumpLDR 指令作为内存跳转
【发布时间】:2021-08-03 22:27:20
【问题描述】:

我正在查看汇编代码,发现一条我不明白其用途的指令 - ldr PC, r1。据我了解,这会执行内存跳转到 r1 指向的地址中包含的值。为什么不使用 B 或 BL 指令? LDR 指令会停止流水线吗?出于纯粹的好奇,如果管道没有停止会发生什么?

【问题讨论】:

  • 我假设那是ldr pc, [r1]。因此,它是通过内存中的指针进行的间接跳转。 bbl 都做不到。
  • 可能是 mov pc, r1, one or other ldr pc, [r1]
  • @Jester 抱歉,如果这有什么改变,我错过了最后的零 - ldr PC, r1, 0
  • 我在switch case编译中经常看到,与offset和shift一起使用。
  • @KRol 你的意思是ldr pc, [r1, #0]?同ldr pc, [r1]

标签: assembly arm cortex-m


【解决方案1】:

一个原因是 ARM 的分支命令不能分支到距离当前程序计数器超过 4 KB 的地址。 (我对较新的基于 ARM 的机器不熟悉,只有 Game Boy Advance,它有这个限制,但我不确定 m-Cortex)

【讨论】:

    【解决方案2】:

    全局函数的地址在内存中的一个表中。或者可能只是一个跳转地址表。

        adr     r1, jumptable
        ldr     r2, [r1, r12, lsl #2]!
        blx     r2
    
        ldr     pc, [r1, #4]
    
    
    
    jumptable:
        .word   0x80000000
        .word   0x800000c0
        .word   0x800000e0
    

    上面的例程将首先分支(带链接)到r12th 子例程,然后在返回时分支(不带链接)到表中的下一个。


    大多数函数一开始就在被调用时保留寄存器:

    push    {r4-r10, lr}
    

    然后在返回时恢复寄存器:

    pop     {r4-r10, lr}
    

    最后通过以下方式返回给调用者:

    bx      lr
    

    但更有可能将恢复和实际回报结合起来,例如:

    pop     {r4-r10, pc}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 2014-07-29
      • 1970-01-01
      • 2019-10-28
      • 2014-05-19
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多