之后几天一直在于GCC做斗争,以后可能要长期使用这种编译器了,所以即使我再不喜欢它,也要开始了解了。
GCC对MIPS的编译做了一些特殊的处理,有一些专门为MIPS的编译选项,这在GNU的官方网站上都可以查得到,我在这里简单说明一下,虽然不是ARM,但是日后会和ARM做比较。
在对MIPS的编译中,不能简单地使用-fpic来达到位置无关的目的,最重要的一个开关是-mabicalls(使能System V r4调用格式),使用了这个开关,并且再搭配上-mshare或者-fpic才能达到位置无关的目的,而在链接时是否使用位置无关选项并不重要,即使选择了静态链接,依然能够给出位置无关代码。
还有一点需要注意的是如果你的工程是类似于bootloader这样的汇编代码和c代码混编的工程,就一定要注意处理好汇编与c代码间调用的接口,在SVr4针对MIPS的寄存器调用规则中,t9寄存器保存当前函数的地址,这一点要切记切记。所以在汇编代码跳往c代码之前,要把t9设置好,最好用如下格式的跳转:
la t9, start
jalr t9
也一定要注意在这两句之前,要把gp寄存器的值设为你动态加载时image的首地址,la t9,start这句话会分解为几句汇编代码,利用gp寄存器的值查找GOT的位置。同时也要注意更新GOT的值,因为编译完的结果都只是相对于0地址的值,你要把这个值更新为你动态加载后的地址。这些内容不只是MIPS相关,所有系统的动态加载都会使用差不多的方法,而ARM的编译器在处理这些问题的时候还是稍微聪明点,小范围内跳转都是直接使用相对偏移跳转,不会借助于GOT,MIPS的专业编译器没有使用过。 |