merkwürdige Übersetzung durch AVR-GCC

Gast #5331742
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
Angehängte Dateien:
Moderator Persönliche Seite #5331895
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 …
Gast #5331955
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.
Moderator Persönliche Seite #5331971
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.
Persönliche Seite #5332196
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.
Moderator #5332325
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.

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