2015-05-29 58 views
-1

由於這個問題的延伸:GCC compile and link raw output異常輸出定製__start

我試圖編譯和定製__start鏈接的一段代碼。需要注意的是,我並不要求這種方法適用於任何已知的架構,因此遵守任何規範並不重要,始終如一地執行。

我有一個簡單的程序集(我從我現在找不到的URL中獲得)。

.set noreorder /* so we can use delay slots explicitly */ 

    .text 
    .globl main 
    .globl __start 
    .type __start,@function 
    .ent __start 

__start: 
    jal main; 
    nop; 
    li $0,1; 
    .end __start 

如果我理解這個正確的,這一切都不會是叫我的主要方法,做分支延遲槽無操作,然後寫數字1到寄存器0(我知道這違反了MIPS規範,這是故意的 - 它表示代碼的完成,並在實際發生之前被「捕獲」)。

然而,當我使用了MIPS ld使用此命令mips-linux-gnu-ld --section-start=.text=0 start.o main.o -o executable

我得到一些不尋常的輸出與objdump

00000000 <.pic.main>: 
0: 3c190000 lui t9,0x0 
4: 0800022b j 8ac <main> 
8: 273908ac addiu t9,t9,2220 
c: 00000000 nop 

00000010 <__start>: 
10: 0c000000 jal 0 <.pic.main> 
14: 00000000 nop 
18: 24000001 li zero,1 
1c: 00000000 nop 

......... 

000008ac <main> 
......... 

觀看時無論多麼微不足道用一個例子的代碼鏈接這是我的測試程序,我總是得到相同的.pic.main函數。但是,在某些情況下,它出現在__start之上,在某些情況下會低於__start

我想徹底刪除這個「功能」,但是如果失敗了,希望它總是在__start之後出現。作爲獎勵,如果有人知道這個功能是什麼或爲什麼發生,我會很感興趣。

回答

2

它看起來像一個位置無關的跳轉代碼。鏈接器不知道你的東西將放在哪裏,所以它爲所有情況創建一個PIC。相對跳轉或使用寄存器跳轉可以解決此問題,但它不會是跳轉和鏈接

我會嘗試使用

  • -mrelax-pic-calls把那些通過寄存器$t9正常調度到直接調用PIC調用。這隻有在鏈接器能夠在鏈接時解析目的地並且目的地在直接呼叫的範圍內時纔是可能的。
  • mbranch-cost=num將分支成本設置爲大致「簡單」指令。 「這個成本只是一種啓發式的方法,並不能保證在不同的版本中產生一致的結果。」
  • -mno-shared不生成代碼,並完全與位置無關,並且因此可以鏈接到共享庫
  • -mno-embedded-pic

我把我的錢一個的第2位。

+0

根據:https://dmz-portal.mips.com/wiki/GCC_MIPS_Options_Support_Status,GCC MIPS工具鏈不支持-mrelax-pic-calls –

+0

「上次修改於2013年4月14日」。那麼,如果是這樣,這是非常不幸的。另一方面,你仍然可以嘗試使用其他的。 – user35443