LDR pc,[pc,#reset]
我正在研究的这本书中的向量表中使用了这种代码的和平。我们知道“pc”是获取指令的地址(程序计数器),但是当用作LDR指令的第一个参数时,它违反了 pc 的地址性质。
答案 0 :(得分:0)
不确定违反任何内容是什么意思。你真的应该阅读ARM文档,而不是要求我们为你做。
只看语法
ldr Rt,[Rn,#immed]
它将把Rn中的值用作地址,添加立即数并从该位置读取一个单词,然后将该值读入Rt。如果Rt是R15(程序计数器),那么它就会分支。是否可以使用它在arm和thumb模式之间进行更改特定于您正在使用的体系结构(ARMv4,ARMv5,ARMv6等)。还有其他例外。
如果你做了回写
ldr Rt,[Rn,#immed]!
然后我认为你得到了你应得的不可预测的结果。
在手臂模式下,R15是前面两条指令(前面总是两条指令)。所以如果这个ldr在地址0x100那么当它执行时Rn将是0x108它将立即添加立即跳转到结果,所以这可以用作一个非常懒的方式来编译(汇编)时间跳转表
.equ BOB , 0x0
.equ CAROL, 0x4
.equ TED , 0x8
.equ ALICE, 0xC
nop
.align 8
ldr pc,[pc,#TED]
.word 0
.word bob
.word carol
.word ted
.word alice
.align 8
bob:
nop
nop
b .
ted:
nop
b .
carol:
nop
nop
nop
nop
b .
alice:
b .
创建此表
100: e59ff008 ldr pc, [pc, #8] ; 10 <bob-0x1f0>
104: 00000000 andeq r0, r0, r0
108: 00000200 andeq r0, r0, r0, lsl #4
10c: 00000214 andeq r0, r0, r4, lsl r2
110: 0000020c andeq r0, r0, r12, lsl #4
114: 00000228 andeq r0, r0, r8, lsr #4
0x108 + 8 = 0x110,它给出地址0x20C,它将加载到R15并导致跳转到该地址
00000200 <bob>:
200: e1a00000 nop ; (mov r0, r0)
204: e1a00000 nop ; (mov r0, r0)
208: eafffffe b 208 <bob+0x8>
0000020c <ted>:
20c: e1a00000 nop ; (mov r0, r0)
210: eafffffe b 210 <ted+0x4>
00000214 <carol>:
214: e1a00000 nop ; (mov r0, r0)
218: e1a00000 nop ; (mov r0, r0)
21c: e1a00000 nop ; (mov r0, r0)
220: e1a00000 nop ; (mov r0, r0)
224: eafffffe b 224 <carol+0x10>
00000228 <alice>:
228: eafffffe b 228 <alice>
现在,如果我将此行更改为
ldr pc,[pc,#CAROL]
并将其分支重新组合到不同的地址。
会更容易b ted
然后将其更改为
b alice
IF 你可以到达那些有分支的人,稍微便宜一点
ldr pc,=ted
并将其替换为
ldr pc,=carol
如果你想进行一个可以到达任何地方的汇编时间变化,并且没有任何if armv4那么如果armv5然后等细微差别(除了切换到拇指或非拇指)。