[转]arm中r12(IP)的用途

近来在维护一个年久失修的程序, 包括应用,库文件以及一个linux device driver.很久以前程序是用arm-linux-gcc 3.4.3编译的。而最近当换用arm-linux-gcc 4.1.1进行编译的时候发现程序神奇的无法运行了。经过尝试,发现当我们使用shared library形式编译程序后,它便无法正常运行。而如果将库和应用static linking在一起后就能得出正确结果。
苦思良久不得其法。几个人只好痛苦的开始研究arm的文档试图找到答案。也算功夫不负有心人。终于在一份arm公司的文档中找到了答案。原来曾经被视为general register的r12, 现在已不再仅仅是通用寄存器了。在新的规范中,它被称为Intra-Procedure-call scratch register。以下摘录一些文档的内容:

Register r12 (IP) may be used by a linker as a scratch register between a routine and any subroutine it calls (for details, see §5.3.1.1, Use of IP by the linker). It can also be used within a routine to hold intermediate values between subroutine calls

Both the ARM- and Thumb-state BL instructions are unable to address the full 32-bit address space, so it may be necessary for the linker to insert a veneer between the calling routine and the called subroutine. Veneers may also be needed to support ARM-Thumb inter-working or dynamic linking. Any veneer inserted must preserve the contents of all registers except IP (r12) and the condition code flags; a conforming program must assume that a veneer that alters IP may be inserted at any branch instruction that is exposed to a relocation that supports inter-working or long branches.

即是说。现在如果汇编代码中存在bl指令,而r12又被用来作为通用寄存器,那么r12的值就很有可能会被链接器插入的veneer程序修改掉了。当然如果源代码是纯粹的c代码,那arm-linux-gcc 4.1.1 本身并不会犯这样的错误。但由于我维护的程序中有部分汇编代码,而早年写的汇编代码又没有估计到这个因素。所以才引发了这个稀奇古怪的问题。

哦, 对了。还是发一下文档的引用。
[1] “Procedure Call Standard for the ARM Architecture”, 19th January, 2007, Richard Earnshaw.

参考文章:
https://blog.csdn.net/gooogleman/article/details/3529413

猜你喜欢

转载自blog.csdn.net/QWE123ZXCZ/article/details/84749943