加载中…
正文 字体大小:

MIPS BOOT中的地址重定位RELOC

(2009-08-06 23:46:34)
标签:

杂谈

分类: MSN搬家

1.       首先明确几个概念物理地址、虚拟地址、链接地址、指令所在地址(程序地址)
2.       凡是标号的值都是标号所在指令的链接地址(即RAM地址)。在分支指令中的标号所表示的值是一个相对于本分支指令地址的16bit的偏移量。汇编器会将标号所表示的有效地址(目标地址)转换成合适的偏移值放入指令中。在跳转指令中的标号所表示的值也是由汇编器将标号所在的有效地址(目标地址)转换成合适的偏移值,转换规则详见指令说明。

3.       把当前的执行地址保存在了ra中,再通过做差找到偏移量,最后再把计算结果返回给一个寄存器,再jal过去。

4.       bal跳转的地址是当前指令地址加标号相对于当前指令地址的偏移。

  

     la  gp, _gp             

     la  sp, STACK_ADRS-(4*_RTypeSize)  

     move   a0, s0           

     sync                    

     RELOC(t0, romStart)

     jal t0           

     nop

    bal sysLedErr        

 

   RELOC(t0, romStart)

   jal t0           

   nop

  #ifndef RELOC

  #define   RELOC(toreg,address) \

   bal 9f; \

9:; \

   la  toreg,address; \

   addu   toreg,ra; \

   la  ra,9b; \

   subu   toreg,ra

#endif

这个是vxworks bootloader 位置无关代码的处理手法。 romStart的连接地址是在ram所在的地址,而实际运行是在flash上,我们需要将romStart的地址换成在flash中的位置,所以该段代码先加上当前运行位置的地址,然后减去链接时生成的当前位置的地址,这样就得到实际运行时romStart的相对地址,这样就可以直接跳转过去了。

RELOC(t0,romStart)  \

0Xbfc01004: bal  9f; \           

9:  ;\

0Xbfc01008:la   t0, romStart; \

0Xbfc01010:addu t0, ra;       \

0Xbfc01014:la ra, 9b; \

0Xbfc0101c:subu t0, ra   \

 

 jal      t0 

 nop

 

1.    执行bal之后,ra寄存器的值为0Xbfc0100c;

2.    执行la之后,t0寄存器存放的是romStart的链接地址。

3.    执行addu之后,t0寄存器存放的是0Xbfc0100c+romStart的链接地址。

4.    执行la之后,ra寄存器存放的是0xbfc01008的地址对应的链接地址。

5.    执行subu之后,t0寄存器存放的是0xbfc01008的地址对应的链接地址-(0Xbfc0100c+romStart),此时t0寄存器存放的即是romStart对应的ROM地址。

6.    

MIPS的函数调用使用jal指令,返回地址位于$ra($31)中,返回地址是下下一条指令。紧跟分支指令后的下一条指令是分支延时槽,这条指令总是在函数调用前之前。因此所有jal指令后的下一条指令都是nop指令。MIPS函数返回时使用jr       ra

 

与ppc的地址重定位的比较
lis     r4, HIADJ(start)               

addi    r4, r4, LO(start)              

lis     r5, HIADJ(romInit)             

addi    r5, r5, LO(romInit)            

lis     r6, HIADJ(ROM_TEXT_ADRS)       

addi    r6, r6, LO(ROM_TEXT_ADRS)      

sub     r4, r4, r5                     

add     r4, r4, r6

mtspr   LR, r4                                                                

blr                                    

PPC中函数调用通常使用bl指令,函数返回通常用blr指令。bl指令可以自动将本指令的下一条指令的地址装载到LR寄存器,但在调用romStart时,lr寄存器是手工设置的。PPC只有分支指令即b指令,没有跳转指令(j指令),通过指令中的AA标记区分长跳转和短跳转。

0

阅读 评论 收藏 转载 喜欢 打印举报
  • 评论加载中,请稍候...
发评论

       

    验证码: 请点击后输入验证码 收听验证码

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有