[英]ARM LDR instruction on PC register
我在这里理解这个故事:
LDR r0,[pc,0x5678]相当于这个“C代码”
\n r0 = *(pc + 0x5678)\n它是使用基本偏移量解引用的指针。
我的问题是:
我找到了这段代码
LDR PC, [PC,-4]
它被评论为猴子修补等。
我如何理解这段代码
pc = *(pc - 4)
在这种情况下,“pc”寄存器将取消引用前一条指令的地址,并将包含指令的“机器代码”(不是指令的地址),程序将跳转到该无效地址继续执行,可能我们将“分段故障”。 那么我缺少或不理解?
让我思考的是LDR指令中第二个操作数的括号。 据我所知,x86架构上的括号已经取消引用指针,但我无法理解ARM架构中的含义。
mov r1, 0x5678 add r1, pc mov r0, [r1]
这段代码相当于?
LDR r0, [pc, 0x5678]
引自ARM指令集文档(ARM DDI 0029E)的4.9.4节:
使用
R15
作为基址寄存器时,必须记住它包含当前指令地址8字节的地址。
因此该指令将加载位于当前指令之后 4个字节的字,该字有望包含有效地址。
由于ARM体系结构的一个怪癖 , LDR PC, [PC,-4]
是
以下指令的分支(假设我们在谈论ARM,而不是Thumb),因此在正常情况下它没有效果(性能除外) )。
关键是,通过将该指令放在函数的开头,然后代码在运行时通过重写
分支到紧跟在指令之后的字中存储在存储器中的地址。 Herp derp,我让LDR
指令的底部12位来改变偏移,从而非常简单,从而将该函数重定向到其他地方。
ADR
和LDR
混淆了 - 如果它是ADR
,上面的情况就是如此,但这种情况更为直白。
现在我已经失去了自己,这只是一个简单的函数调用蹦床。 函数地址将紧跟在LDR
指令之后存储为数据字(可能由链接器设置为某个初始值),并且可以在运行时简单地重写为数据以重定向分支,而无需求助于自修改代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.