LDR pc,[pc,#reset]
我这天正在研究的书中向量表中使用的代码的这种和平。 我们知道"pc"是指令获取的地址(程序计数器),但是当用作LDR指令的第一个参数时,它违反了PC的地址性质。
不确定你所说的违反任何东西是什么意思。 您确实应该阅读 ARM 文档,而不是要求我们为您完成。
只看语法
ldr Rt,[Rn,#immed]
它将采用 Rn 中的值,将其用作地址,添加立即并从该位置读取一个单词,然后将该值读取放在 Rt 中。如果 Rt 是 R15(程序计数器),则它会分支。 您是否可以使用它在手臂和拇指模式之间切换取决于您使用的体系结构(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
如果你能到达那些有分支的人,否则稍微便宜一点
ldr pc,=ted
并将其替换为
ldr pc,=carol
如果您想进行可以到达任何地方的组装时间更改,并且没有任何 if armv4,那么如果 armv5 那么 etc 细微差别(除了切换到拇指或不切换到拇指)。