Forum: Compiler & IDEs merkwürdige Übersetzung durch AVR-GCC


von Andreas G (Gast)


Angehängte Dateien:

Lesenswert?

Wenn ich das beigefügte Programm übersetze, werden merkwürdige Befehle 
generiert. Es wird ein Register mit 0 geladen, anschließend wird es 
einmal arithmetisch nach rechts geschoben, und anschließend vergessen.

Wie kann ich erreichen, daß diese unnötigen Befehle nicht eingebaut 
werden?

(Compileraufruf: avr-gcc -g -mmcu=attiny2313 -Wall -Wstrict-prototypes 
-Os -Wa,-a,-ad,-ah -Os -c bcd2bin.c > bcd2bin.lst)

Compilerversion: avr-gcc (GCC) 5.4.0

von Oliver S. (oliverso)


Lesenswert?

Wo ist das Problem?

Dein Hauptprogram macht nichts weiter, als 0 zurückzugeben. Der ganze 
Rest ist nur Dekoration und wird wegoptimiert.

gcc ist halt ein klassisches SiSo-System: Shit in - Shit out.

Oliver

von Schwarzseher (Gast)


Lesenswert?

So besser?
1
uint8_t bcd2int(uint8_t input){
2
        uint8_t tempa = input & 0xF0;
3
        uint8_t tempo = (tempa >> 1);
4
        return tempo + (uint8_t)(tempo >> 2) + (uint8_t)(tempa);
5
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas G schrieb:
> Wie kann ich erreichen, daß diese unnötigen Befehle nicht eingebaut
> werden?

Eine ältere Compilerversion benutzen. ;-)

Hier das Resultat für GCC 4.7.2:
1
bcd2int:
2
/* prologue: function */
3
/* frame size = 0 */
4
/* stack size = 0 */
5
.L__stack_usage = 0
6
        mov r25,r24
7
        andi r25,lo8(-16)
8
        lsr r25
9
        andi r24,lo8(15)
10
        add r24,r25
11
        lsr r25
12
        lsr r25
13
        add r24,r25
14
        ret

GCC 7.x habe ich gerade nicht zur Hand, vielleicht ist es dort ja
wieder besser geworden?  Mit bisschen Glück meldet sich Johann hier
zu Wort …

von Andreas G (Gast)


Lesenswert?

Das Hauptprogramm ist auch nicht das Problem. Das steht nur da, damit 
das ganze übersetzt wird, ohne Fehlermeldung.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas G schrieb:
> Das steht nur da, damit das ganze übersetzt wird, ohne Fehlermeldung.

Da du nur mit -c compiliert hast (und ich gleich mit -S), wird das
auch übersetzt, ohne dass du ein main() angibst.  Man muss ja nicht
versuchen, das zu linken.

von Andreas G (Gast)


Lesenswert?

@Schwarzseher: Danke, guter Tip, das Aufteilen in zwei Variablen hat 
genutzt. Hab noch das Ende angepaßt, da soll das Lownibble der Eingabe 
addiert werden.

@Jörg: ältere Version geht leider nicht, da gibt es Vorgaben. Ich bin 
eher ein Assembler-Programmierer der zu C gezwungen wurde ;-) ich wußte 
nicht, daß man ein Programm ohne "main" übersetzen kann.

@ Oliver S: Du solltest vor dem Posten erst einmal versuchen, das 
Problem zu erkennen, oder ging es nur darum, einen anderen zu 
beleidigen? Im Gegensatz zu den fundierten Antworten der anderen 
Beteiligten war Dein geistiger Erguß in keiner Weise hilfreich, da er 
das eigentliche Problem gar nicht angeschnitten hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andreas G schrieb:
> ältere Version geht leider nicht, da gibt es Vorgaben.

Und die paar Takte sind wirklich so wichtig, dass man sich darum
einen Kopf machen müsste?

Das Compilat von GCC 5.x ist ja nicht falsch, nur eben nicht optimal.

Wenn du ein völlig definiertes Zeitverhalten brauchst, solltest du
ohnehin die entsprechenden Codepassagen mit der Hand schreiben.
Andernfalls würde ich mir um einen solchen Artefakt keine zu großen
Gedanken machen.  Passiert halt immer wieder mal, dass ein Compiler
auch mal was Überflüssiges generiert.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ab v6 wird die Promotion zu int nicht mehr explizit ausgeführt.  Mit v5 
kann man zum Beispiel verwenden:
1
unsigned char bcd2int (unsigned char input)
2
{
3
  unsigned char tempu = input & 0xF0;
4
  unsigned char tempo = tempu >> 1;
5
  return tempo + (tempo >> 2) + (input & 0x0F);
6
}
1
bcd2int:
2
  mov r25,r24
3
  andi r25,lo8(-16)
4
  lsr r25
5
  andi r24,lo8(15)
6
  add r24,r25
7
  lsr r25
8
  lsr r25
9
  add r24,r25
10
  ret
Schwarzseher schrieb:
> So besser?

Fast, aber leider mit Zifferndreher.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

So sieht's mit GCC 7.3.0 aus:

1
bcd2int:
2
  mov r25,r24
3
  lsr r25
4
  andi r25,lo8(120)
5
  andi r24,lo8(15)
6
  add r24,r25
7
  lsr r25
8
  lsr r25
9
  add r24,r25
10
  ret

Gegenüber dem Kompilat des GCC 4.7.2 in Jörgs Beitrag sind lediglich ein
LSR und ein ANDI vertauscht und der ANDI-Operand entsprechend angepasst
worden.

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.