2009-11-19 2 views
2

J'ai un fichier binaire que j'ai démonté en utilisant avr-objcopy. La table de vecteurs d'interruption ressemble à:Comment puis-je sauter par rapport au PC en utilisant l'assembleur GNU pour AVR?

 
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)

Je veux réassembler ce fichier avec quelques modifications. Je l'ai reformaté en supprimant les 2 premières colonnes de sorte qu'il s'agit d'un fichier d'assemblage régulier. à savoir:

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

Cependant, quand je lance

$ avr-as -mmcu=atmega8 test.asm

puis désassembler le fichier généré. (En utilisant objcopy -S a.out) La sortie ressemble à:

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) 

Alors, comment puis-je obtenir à AVR-respecter les sauts de PC par rapport?

Répondre

6

J'ai trouvé la réponse!

J'étais en train d'assembler mais pas de lier. Donc l'assembleur remplissait tous les sauts/appels/branches relatifs avec. + 0.

Pour résoudre ce problème, je devais créer un script de liaison personnalisé J'ai appelé linker.x qui contient les éléments suivants:

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

Ceci indique l'éditeur de liens pour démarrer la section .text à l'adresse 0.

ensuite, je pourrais lier le code à l'aide:

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

Après la liaison en utilisant la commande ci-dessus tous les + 0. ont été remplies avec leurs valeurs correctes.!

La raison en est que, jusqu'à l'étape de liaison, comme/gcc ne sait pas quoi d'autre va être inclus dans le fichier binaire. C'est l'éditeur de liens qui prend tous les fichiers objets individuels et les combine en un seul. Donc, si l'étape du linker n'est jamais exécutée, il n'y a aucun moyen de remplir les sauts relatifs avec des sauts absolus.

L'assembleur d'AVR effectue à la fois l'assemblage et la liaison. Mais l'assembleur gnu est plus générique et vous devez donc lier séparément.

0

Je suppose que rjmp PC+2 ne fonctionne pas dans avr-as? Voilà comment je le ferais dans AVR Studio ...

+0

Merci pour le conseil. J'ai essayé mais ça ne marche pas. :( En fait, la seule fois où j'ai pu le faire démonter à autre chose que "rjmp. + 0" c'est quand j'utilise un littéral, mais ce n'est plus relatif, mais absolu. – kroylar

Questions connexes