www.mikrocontroller.net

Forum: Compiler & IDEs seltsamer Assemblercode


Autor: Jogibär (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe da ein Problem, wo ich nicht weiter komme.

Folgender Programmauszug:

case 0:
          {
          sbi (PORTC,1);
          sbi (PORTC,2);
          cbi (PORTC,0);
          PORTD = a |= ( PIND &= 0x80);
          zaehler = 1;
          break;
          }

PortD als Ausgänge definiert.
Ich will den aktuellen Zustand der Ausgänge einlesen, ein Bit, das ich
nicht
verändern möchte , herausfiltern ( PORTD.7) und mit den Bits der
Variable a
logisch ODER verknüpfen.
Dabei soll das 7.Bit des Ausgangs seinen Zustand behalten.

Nur irgendwie habe ich einen Denkfehler.Somit habe ich mir den
Assemblercode
angeschaut, und etwas seltsames entdeckt.

Assembler Code ( Auschnitt);

27e:   02 97           sbiw    r24, 0x02       ; 2
 280:   c9 f0           breq    .+50            ; 0x2b4
 282:   08 95           ret
 284:   a9 9a           sbi     0x15, 1 ; 21
 286:   aa 9a           sbi     0x15, 2 ; 21
 288:   a8 98           cbi     0x15, 0 ; 21
 28a:   80 b3           in      r24, 0x10       ; 16
 28c:   80 78           andi    r24, 0x80       ; 128
 28e:   80 bb           out     0x10, r24       ; 16
 290:   80 b3           in      r24, 0x10       ; 16
 292:   82 2b           or      r24, r18
 294:   82 bb           out     0x12, r24       ; 18
 296:   81 e0           ldi     r24, 0x01       ; 1
 298:   0a c0           rjmp    .+20            ; 0x2ae

In Zeile 28a ließt er den Port ein,in 28c wird mit 0x80 UND verknüpft
und in
Zeile 28e auf PIND !!! ausgegeben, sowie in Zeile 290 von PIND wieder
eingelesen.

Doch laut Datenblatt ist PIND nur lesbar !?!
Darum müßte er in Zeile 290 den alten PIND Wert wieder einlesen.

Ehrlich gesagt, ich verstehe das nicht ganz.
Kann mir jemand mal das erklären ?

mit freundlichen Grüßen

Jogibär

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas kommt davon, wenn man 3 Zuweisungen zugleich macht.
Schreibs besser hintereinander.

Den Compiler interessiert nicht, welche Bedeutung eine IO-Adresse hat.

Er führt brav alles aus, was Du hinschreibst, auch wenn es unsinnig
ist.


Peter

Autor: Jogibär (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für deinen Hinweis.

Der Fehler lag in   < PIND &= 0x80 >

Der Compiler verknüpft beide Bytes logisch UND , und
speichert dann das Ergebnis in dem ersten Parameter ( in diesem Fall
PIND).
Deshalb der Schreibzugriff auf PIND.

Bin noch nicht solange dabei, ein paar Fehler seien mir gestattet.

Jogibär

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Bin noch nicht solange dabei, ein paar Fehler seien mir gestattet."

Deshalb ja mein Tip "immer nur eine Zuweisung je Zeile".

Mehrfachzuweisungen ergeben selten kürzeren Code, höchstens den Sieg im
Unleserlichkeitswettbewerb.


Peter

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dazu kommt noch, dass = und |= die gleiche Priorität haben; da kommt je
nach Commpiler etwas anderes heraus, aus der Zeile.

Autor: Fritz Ganter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wegen Mehrfachzuweisungen:

Auch wenn man es gerne macht, tut es nicht, da dabei schlechterer Code
rauskommt.

also statt:

a=b=c;

besser

a=c;
b=a;

schreiben, im ersten Fall liest er den Inhalt von c 2 mal, im zweiten
Fall verwendet er das Register wieder.

Ist im normalen Code vielleicht egal, aber in Interruptroutinen bringts
schon was.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.