[avr-gcc Compiler-/Linkerbug] --relax sprengt Interruptvektortabelle

OP #1661850
Lesenswert?
• ▲
▼
Hallo zusammen,

beim Test der verschiedenen Optimierungsmöglichkeiten bin ich auf ein 
Problem gestoßen, das ich für mit an Sicherheit grenzende 
Wahrscheinlichkeit für einen Compiler-/Linkerfehler halte.
Um das ganze zu bestätigen (und weil ich auf die Schnelle nicht wirklich 
rausgekriegt habe, wohin der Bugreport gehen sollte), lade ich das ganze 
hier ab.

Problembeschreibung:
Wird die Linker-Option "--relax" verwendet, bläht avr-gcc jede 
Sprunganweisung der Interruptvektortabelle um ein "nop" auf.
Das Problem tritt wohl bei allen AVRs mit mehr als 8KB Flash auf, 
konkret getestet habe ich Mega(8)8 (tritt nicht auf), Mega168, Mega328, 
Mega644, Mega128 und Mega 2560 (tritt bei allen auf)
Verwendeter Compiler: gcc version 4.3.3 (WinAVR 20100110)

Verwendetes C-File:
1
void main(void) { }

Compileraufruf:
1
avr-gcc -Wall -g2 -gdwarf-2 -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -ffreestanding -std=gnu99 -funsigned-char -funsigned-bitfields -W -Wundef -Wunreachable-code -Wstrict-prototypes -msize -mmcu=atmega168 -Wl,--gc-sections,--relax -o"main.out" "main.c"
1
avr-objdump -h -S -j .text -j .data main.out > "main.lss"

Gibt mit dem ATMega168 folgendes:
1
Disassembly of section .text:
2

3
00000000 <__vectors>:
4
   0:  33 c0         rjmp  .+102      ; 0x68 <__ctors_end>
5
   2:  00 00         nop
6
   4:  39 c0         rjmp  .+114      ; 0x78 <__bad_interrupt>
7
   6:  00 00         nop
8
   8:  37 c0         rjmp  .+110      ; 0x78 <__bad_interrupt>
9
   a:  00 00         nop
 Den Rest habe ich weggelassen ...

Könnt ihr das Problem bestätigen?

mfG
Markus
#1661937
Lesenswert?
• ▲
▼
Markus J. schrieb:
> Könnt ihr das Problem bestätigen?

Nein, denn ...

> Das Problem tritt wohl bei allen AVRs mit mehr als 8KB Flash auf,

... bei diesen AVRs sind die Interruptvektoren doppelt so groß, die NOPs 
sind dort also völlig zu Recht.

Vielleicht kommst du ja von alleine drauf, warum die Vektoren dort 
doppelt so groß sein müssen. ;-)
OP #1662068
Lesenswert?
• ▲
▼
argh
Und voll reingefallen ...
Natürlich, du hast voll und ganz recht - tückischerweise gibt das von 
avr-objdump erzeugte Listing die normalerweise erzeugte 
"jmp"-Instruktion in einer Zeile aus, den "rjmp"-Befehl dagegen wie oben 
in zwei Zeilen.
Solange man nicht peinlich genau auf die Instruktionsadresse achtet (und 
das Datasheet nicht gerade Zeile für Zeile im Kopf hat), wird der 
Eindruck einer aufgeblähten Interruptvektortabelle erzeugt.

Vielen Dank, das Thema hat sich damit erledigt!

mfG
Markus
#1662099
Lesenswert?
• ▲
▼
Markus J. schrieb:
> tückischerweise gibt das von
> avr-objdump erzeugte Listing die normalerweise erzeugte
> "jmp"-Instruktion in einer Zeile aus, den "rjmp"-Befehl dagegen wie oben
> in zwei Zeilen.

Ich kann da ehrlich gesagt nichts Tückisches sehen, schon gar nicht 
einen "rjmp in zwei Zeilen". Das NOP ist ein separater Assemblerbefehl, 
der direkt nichts mit dem rjmp zu tun hat. Warum sollte sich objdump 
dazu bemüßigt fühlen, zwei Assemblerbefehle in eine Zeile zu packen?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.