Comment puis-je sauter par rapport au PC en utilisant l'assembleur gnu pour AVR?
-
21-09-2019 - |
Question
J'ai un fichier binaire que je l'ai démonté à l'aide-objcopy AVR. Le tableau de vecteur d'interruption ressemble à:
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 remonter ce fichier avec quelques modifications. Je l'ai reformaté en supprimant les 2 premières colonnes afin qu'il soit un fichier de montage régulier. à-dire:
.org 0 rjmp .+38 ; 0x28, RESET rjmp .+880 ; 0x374, INT0 (snip)
Cependant, quand je lance
$ avr-as -mmcu=atmega8 test.asm
puis démonter 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-respect des sauts de PC par rapport?
La solution
J'ai trouvé la réponse!
J'assemblait mais pas la liaison. Ainsi, l'assembleur emplissait dans tous les sauts relatifs / appels / branches 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.
Alors je pourrais lier le code en utilisant:
$ avr-ld -mavr4 -Tlinker.x a.out -o output.o
Après la liaison en utilisant la commande ci-dessus tous les. + 0. étaient remplis avec leurs valeurs correctes!
La raison pour cela, parce que jusqu'à l'étape de liaison, comme / gcc ne sais pas quoi d'autre va être inclus dans le fichier binaire. Il est l'éditeur de liens qui prend tous les fichiers objets individuels et les combine en un seul. Donc, si l'étape de liaison est jamais exécuté, il n'y a aucun moyen de remplir les sauts relatifs avec des sauts absolus.
assembleur deAVR fait la fois l'assemblage et la liaison. Mais l'assembleur gnu est plus générique et donc vous devez relier séparément.
Autres conseils
Je suppose que le travail ne marche pas rjmp PC+2
en avr-as? Voilà comment je le ferais dans AVR Studio ...