2009-11-19 81 views
2

我有一個使用avr-objcopy反彙編的二進制文件。中斷向量表看起來像:如何使用gnu彙編器爲AVR跳轉相對於PC?

 
00000000 : 
    ; VECTOR TABLE 
    0: 13 c0   rjmp .+38  ; 0x28, RESET 
    2: b8 c1   rjmp .+880  ; 0x374, INT0 
    4: fd cf   rjmp .-6   ; 0x0 
    6: fc cf   rjmp .-8   ; 0x0 
    8: fb cf   rjmp .-10  ; 0x0 
    a: fa cf   rjmp .-12  ; 0x0 
    c: f9 cf   rjmp .-14  ; 0x0 
    e: f8 cf   rjmp .-16  ; 0x0 
    10: f7 cf   rjmp .-18  ; 0x0 
    12: c7 c1   rjmp .+910  ; 0x3a2, TIMER1 OVF 
    14: f5 cf   rjmp .-22  ; 0x0 
    16: f4 cf   rjmp .-24  ; 0x0 
    18: f3 cf   rjmp .-26  ; 0x0 
    1a: f2 cf   rjmp .-28  ; 0x0 
    1c: 2b c2   rjmp .+1110  ; 0x474, ADC conversion complete 
    1e: f0 cf   rjmp .-32  ; 0x0 
    20: ef cf   rjmp .-34  ; 0x0 
    22: ee cf   rjmp .-36  ; 0x0 
    24: ed cf   rjmp .-38  ; 0x0 
    26: 00 00   nop 
    ; START 
    28: f8 94   cli 
(snip)

我想通過一些修改重新組合此文件。我通過刪除前2列來重新格式化它,以便它是常規裝配文件。即:

 
.org 0 
    rjmp .+38   ; 0x28, RESET 
    rjmp .+880   ; 0x374, INT0 
(snip)

然而,當我運行

$ avr-as -mmcu=atmega8 test.asm

,然後拆卸生成的文件。 (使用objcopy -S a.out)輸出如下所示:

00000000 : 
    0: 00 c0   rjmp .+0    ; 0x2 
    2: 00 c0   rjmp .+0    ; 0x4 
    4: 00 c0   rjmp .+0    ; 0x6 
    6: 00 c0   rjmp .+0    ; 0x8 
    8: 00 c0   rjmp .+0    ; 0xa 
    a: 00 c0   rjmp .+0    ; 0xc 
    c: 00 c0   rjmp .+0    ; 0xe 
    e: 00 c0   rjmp .+0    ; 0x10 
    10: 00 c0   rjmp .+0    ; 0x12 
    12: 00 c0   rjmp .+0    ; 0x14 
    14: 00 c0   rjmp .+0    ; 0x16 
    16: 00 c0   rjmp .+0    ; 0x18 
    18: 00 c0   rjmp .+0    ; 0x1a 
    1a: 00 c0   rjmp .+0    ; 0x1c 
    1c: 00 c0   rjmp .+0    ; 0x1e 
    1e: 00 c0   rjmp .+0    ; 0x20 
    20: 00 c0   rjmp .+0    ; 0x22 
    22: 00 c0   rjmp .+0    ; 0x24 
    24: 00 c0   rjmp .+0    ; 0x26 
    26: 00 00   nop 
    28: f8 94   cli 
(snip) 

那麼我怎樣才能得到avr--至於尊重PC相對跳轉呢?

回答

6

我找到了答案!

我在裝配但沒有連接。所以彙編程序用+ 0填充所有相關的跳轉/調用/分支。

爲了解決這個問題,我需要創建一個自定義鏈接腳本我叫linker.x其中包含以下內容:

 
SECTIONS 
{ 
    . = 0x0; 
    .text : { *(.text) } 
} 

這告訴鏈接地址開始.text段0

然後,我可以用鏈接代碼:

$ avr-ld -mavr4 -Tlinker.x a.out -o output.o 

使用上述命令鏈接之後所有的+ 0的填充與他們正確的價值觀!

之所以這樣做,是因爲直到鏈接階段,因爲/ gcc不知道二進制文件中會包含哪些內容。它是鏈接器將所有單個對象文件合併成一個。因此,如果連接器階段從未運行,則無法通過絕對跳轉填充相對跳轉。

AVR的彙編程序既能進行組裝和鏈接。但gnu彙編程序更通用,因此需要單獨鏈接。

0

我假設rjmp PC+2在avr-as中不起作用?這就是我在AVR工作室做的...

+0

感謝您的提示。我嘗試過,但不起作用。 :( 事實上,我已經能夠將它拆解爲「rjmp。+ 0」以外的其他東西的時候,我使用的是文字,但它不再是相對的,而是絕對的。 – kroylar 2009-11-20 06:10:06