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

#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. ;-)
#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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren