为什么'LDR'不能代替'B'?

时间:2013-07-02 14:17:41

标签: assembly arm

我有一个程序(手臂)和一些说明(IDA的disas):

.plt:000083F0   ADRL   R12, 0x83F8
.plt:000083F8   LDR    PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0

addr 0x90D8存储0x83D0:

000090D8  D0 83 00 00

那么,在ldr之后,pc是0x83D0并将执行0x83D0中的inst,不是吗?

这里我想直接jmp到0x83D0并且不使用09D8,我修改二进制机器代码并由IDA重新加载:

.plt:000083F0   B   sub_83D0

IDA显示它将jmp到0x83D0,所以我认为修改是有效的 但是,修改后程序无法运行 我的修改和如何实现目标有什么问题吗?请帮帮我......

我在这里添加了一些disas:
SRC

.plt:000083E4
.plt:000083E4 ; =============== S U B R O U T I N E =======================================
.plt:000083E4
.plt:000083E4 ; Attributes: thunk
.plt:000083E4
.plt:000083E4 sub_83E4                                ; CODE XREF: .text:00008410j
.plt:000083E4                 ADRL            R12, 0x83EC
.plt:000083EC                 LDR             PC, [R12,#(off_90D4 - 0x83EC)]! ; sub_83D0
.plt:000083EC ; End of function sub_83E4
.plt:000083EC
.plt:000083F0
.plt:000083F0 ; =============== S U B R O U T I N E =======================================
.plt:000083F0
.plt:000083F0 ; Attributes: thunk
.plt:000083F0
.plt:000083F0 sub_83F0                                ; CODE XREF: sub_8430+6p
.plt:000083F0                                         ; sub_8430+Ep ...
.plt:000083F0                 ADRL            R12, 0x83F8
.plt:000083F8                 LDR             PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0
.plt:000083F8 ; End of function sub_83F0
.plt:000083F8
.plt:000083F8 ; .plt          ends
.plt:000083F8

已修改

.plt:000083E4
.plt:000083E4 ; =============== S U B R O U T I N E =======================================
.plt:000083E4
.plt:000083E4 ; Attributes: thunk
.plt:000083E4
.plt:000083E4 sub_83E4                                ; CODE XREF: .text:00008410j
.plt:000083E4                 ADRL            R12, 0x83EC
.plt:000083EC                 LDR             PC, [R12,#(off_90D4 - 0x83EC)]! ; sub_83D0
.plt:000083EC ; End of function sub_83E4
.plt:000083EC
.plt:000083F0
.plt:000083F0 ; =============== S U B R O U T I N E =======================================
.plt:000083F0
.plt:000083F0
.plt:000083F0 sub_83F0                                ; CODE XREF: sub_8430+6p
.plt:000083F0                                         ; sub_8430+Ep ...
.plt:000083F0                 ADRL            R12, loc_83F8
.plt:000083F8
.plt:000083F8 loc_83F8                                ; DATA XREF: sub_83F0o
.plt:000083F8                 B               sub_83D0
.plt:000083F8 ; End of function sub_83F0
.plt:000083F8
.plt:000083F8 ; .plt          ends
.plt:000083F8

在0x90D4中:

000090D4  D0 83 00 00 D0 83 00 00

1 个答案:

答案 0 :(得分:2)

指令B sub_83D0 PC 相对。指令序列

.plt:000083F0   ADRL   R12, 0x83F8
.plt:000083F8   LDR    PC, [R12,#(off_90D8 - 0x83F8)]! ; sub_83D0

000090D8:  D0 83 00 00

PC是否相对,但它跳转到绝对地址。您的假设是链接地址是运行时地址。这并非总是如此,特别是在 bootstrap 代码中,可能重新定位或启用 MMU

上面的序列可以从任何地址运行,并将控制转移到绝对 0x83d0 分支变体只会通过添加偏移来更改PC。即,

PC = PC + (SignExtend) (immediate << 2);

等效值为mov pc, #0x83D0,但这不符合 8bit 旋转2倍的mov immediates限制。您可以尝试,

mov r12, #0x8300
orr pc, r12, #0xd0

但转移到的代码可能还需要将r12值设置为较旧的运行时地址。