Forum: Compiler & IDEs [avr-gcc Compiler-/Linkerbug] --relax sprengt Interruptvektortabelle


von Markus J. (markusj)


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

von Stefan E. (sternst)


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

von Markus J. (markusj)


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

von Stefan E. (sternst)


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?

von Markus J. (markusj)


Lesenswert?

Auch wieder wahr, das war wohl ein Anflug selektiver Wahrnehmung ;)

mfG
Markus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.