本帖最后由 crifan 于 2011-04-18 00:15 编辑
关于为何不直接用mov指令,而非要用adr伪指令
在分析uboot的start.S中,看到一些指令,比如: 觉得好像可以直接用mov指令实现即可,为啥还要这么麻烦地,去用ldr去实现?
关于此处的代码,为何要用adr指令: ( 注:其被编译器编译后,会被翻译成: ) 而不直接用mov指令直接将_start的值赋值给r0,类似于这样:
呢? 其原因主要是, 这样的代码,所处理的值,都是相对于PC的偏移量来说的,这样的代码中,没有绝对的物理地址值,都是相对的值,利用产生位置无关代码。因为如果用mov指令: 那么就会被编译成这样的代码: 如果用了上面这样的代码: 那么,如果整个代码,即要执行的程序的指令,被移动到其他位置,那么 这行指令,执行的功能,就是跳转到绝对的物理地址,而不是跳转到相对的_start的位置了, 就不能实现我们想要的功能了,这样包含了绝对物理地址的代码,也就不是位置无关的代码了。 于此相对,这行指令: 即使程序被移动到其他位置,那么该行指令还是可以跳转到相对PC往前172字节的地方,也还是我们想要的_start的位置,这样包含的都是相对的偏移位置的代码,就叫做位置无关代码。其优点就是不用担心你的代码被移动,即使程序的基地址变了,所有的代码的相对位置还是固定的,程序还是可以正常运行的。
关于,之所以不用上面的: 类似的代码,除了上面说的,不是位置无关的代码之外,其还有个潜在的问题,那就是,关于mov指令的源操作数,此处即为0x33d00000,不一定是合法的mov 指令所允许的值,这也正是下面要详细解释的内容“mov指令的操作数的取值范围到底是多少”。
【总结】 之所以用adr而不用mov,主要是为了生成地址无关代码,以及由于不方便判断一个数,是否是有效的mov的操作数 |