seltsamer Assemblercode

Gast #99962
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
#99963
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
Gast #99964
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
#99965
"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
Gast #99967
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

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.