天天看點

arm中r12(IP)的用途

  1. arm中r12的用途
    第一篇部落格。就寫一個最近遇到的bug吧。算是為光秃秃的部落格填點東西吧。 近來在維護一個年久失修的程式, 包括應用,庫檔案以及一個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.  

繼續閱讀