www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Was passiert bei einem Überlauf


Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich will einen Überlauf in C bewusst einsetzen, und habe mich gefragt, 
was passiert, wenn ich ein uint8_t i = 0xff inkrementiere. Die geht doch 
dann auf 0 und sonst nichts, oder?

Hintergrund:

Habe einen Moving-Average-Filter und schalte zwischen mehreren AD-Ports 
um. Da dies in der Interrupt-Schleife geschieht ist der erste AD-Wert 
noch vom "alten" Port und daher für den neuen MA uninteressant und soll 
verworfen werden. Um dies festzustellen, nehme ich die Zählervariable, 
d.h. i. Dies ist die Anzahl der bisherigen Samples des Filters, die nach 
dem initialisieren hochzählt bis die Filterlänge erreicht ist. 
Anschließend arbeitet der Filter rekursiv.

Dient primär dem Einsparen unnötiger Variablen.

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Hallo,
>
> ich will einen Überlauf in C bewusst einsetzen, und habe mich gefragt,
> was passiert, wenn ich ein uint8_t i = 0xff inkrementiere. Die geht doch
> dann auf 0 und sonst nichts, oder?
Ja, und es wird das Überlauf Flag gesetzt.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Antwort schrieb:
> und es wird das Überlauf Flag gesetzt.

Okay?! Das könnte ich abfragen. Wo eigentlich?

Wenn ich's lasse, passiert nichts weiter, oder? Oder gibts noch weitere 
Konsequenzen, wie etwa das Beschreiben einer anderen, genauer der 
nächsten Speicherstelle.

Wie gesagt: Mir ist zu diesem Zeitpunkt völlig bewusst, dass ein 
Überlauf passiert.

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau im Datenblatt deines Controllers nach dem Carry-Flag (ich weiß 
nicht welchen du verwendest)

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Antwort schrieb:
>> und es wird das Überlauf Flag gesetzt.

>Okay?! Das könnte ich abfragen. Wo eigentlich?

Die Antwort von "Antwort" ist so nicht richtig. Wenn wir von C 
Programmen reden, dann gibt es dort ein Überlauf Flag nicht. Nirgendwo 
ist sowas definiert. Also kann man das auch nicht abfragen.

Ein anderer Punkt ist natürlich, das das C Programm ja in ein 
Assembler-Programm umgesetzt wird und auf einer konkreten CPU läuft. 
Deswegen und weil die viele CPUs bei einem Inkrement auch ein 
Überlauf-Flag setzen, ist es, insbesondere wenn man in ein C Programm 
Assemblerbefehle inkorporieren kann, zwar möglich, diese Flag 
abzufragen,
aber es ist nirgendwo in der C-Sprachbeschreibung definiert, das und auf 
welche Weise ein Inkrement in Assembler umgesetzt wird, welcher Befehl, 
welches Register etc. dafür verwendet wird und das mischen von C mit 
Assemblercode ist auch nicht Standard sondern z.B. eine Besonderheit von 
GCC und anderen.

Da aber die Hauptfrage ja war: "Die geht doch dann auf 0 und sonst 
nichts, oder?" und man diese mit Ja beantworten muss, spielt das alles 
garkeine Rolle.

Autor: C-Experte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich will einen Überlauf in C bewusst einsetzen

Laut C-Standart ist das Ergebnis undefiniert.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einen AVR (Genauer einen ATtiny26).
Programmiere in C und bin mir nicht ganz bewusst, ob der Missbrauch 
eines Überlaufs Konsequenzen hat. Was passiert mit dem Carry-Flag wenn 
es nicht für eine bestimmte Operation (z.B. eine 16-Bit Op) verwendet 
wird. Muss ich das selbst händisch zurücksetzen (da der Compiler das 
wahrscheinlich nicht automatisch macht!?) oder passiert das 
vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt 
wird?

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-Experte schrieb:
>> ich will einen Überlauf in C bewusst einsetzen
>
> Laut C-Standart ist das Ergebnis undefiniert.

Das ist Unsinn. Der C Standar>>>D<<< definiert den Überlauf einer 
unsigned Variable ziemlich exakt.

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Einen AVR (Genauer einen ATtiny26).
> Programmiere in C und bin mir nicht ganz bewusst, ob der Missbrauch
> eines Überlaufs Konsequenzen hat. Was passiert mit dem Carry-Flag wenn
> es nicht für eine bestimmte Operation (z.B. eine 16-Bit Op) verwendet
> wird. Muss ich das selbst händisch zurücksetzen (da der Compiler das
> wahrscheinlich nicht automatisch macht!?) oder passiert das
> vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt
> wird?

Der Compiler kümmert sich um das carry flag wo nötig.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C-Experte schrieb:
> Laut C-Standart ist das Ergebnis undefiniert.

Und aus der Sicht von AVR-GCC?

Huch schrieb:
> Da aber die Hauptfrage ja war: "Die geht doch dann auf 0 und sonst
> nichts, oder?" und man diese mit Ja beantworten muss, spielt das alles
> garkeine Rolle.

Alles klar, d.h. ich brauch keine bösen Bugs durch diesen "Missbrauch" 
befürchten (z.B einen Fehler in der nächsten 16-Bit Op.)?

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huch schrieb:
> Die Antwort von "Antwort" ist so nicht richtig. Wenn wir von C
> Programmen reden, dann gibt es dort ein Überlauf Flag nicht. Nirgendwo
> ist sowas definiert. Also kann man das auch nicht abfragen.
>
> Ein anderer Punkt ist natürlich, das das C Programm ja in ein
> Assembler-Programm umgesetzt wird und auf einer konkreten CPU läuft.
> Deswegen und weil die viele CPUs bei einem Inkrement auch ein
> Überlauf-Flag setzen, ist es, insbesondere wenn man in ein C Programm
> Assemblerbefehle inkorporieren kann, zwar möglich, diese Flag
> abzufragen,

Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne 
Assembler-Befehle.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein

äh ja, du brauchst nichts zu befürchten.

Autor: mar IO (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Buesch schrieb:
> C-Experte schrieb:
>>> ich will einen Überlauf in C bewusst einsetzen
>>
>> Laut C-Standart ist das Ergebnis undefiniert.
>
> Das ist Unsinn. Der C Standar>>>D<<< definiert den Überlauf einer
> unsigned Variable ziemlich exakt.

An sowas kann ich mich auch erinnern irgendwann irgendwo gelesen zu 
haben. Man beachte, vorzeichenlos!

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Buesch schrieb:
> Der Compiler kümmert sich um das carry flag wo nötig.

Und da es eine 8-bit Variable ist, die inkrementiert wird, macht er das 
in dem Fall nicht, oder? Daher:

> Muss ich das selbst händisch zurücksetzen (da der Compiler das
> wahrscheinlich nicht automatisch macht!?) oder passiert das
> vollautomatisch, wenn es nicht abgefragt und eine neue Op ausgeführt
> wird?

und:

Muss ich einen bösen Bug im Programmablauf befürchten?

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne
> Assembler-Befehle.

Ist mir völlig klar. Aber: was soll das bringen?
Ich weiß ja dass das Carry-Flag gesetzt sein wird.

Muss ich es händisch zurücksetzen ist die goldene Frage! Oder anders: 
Will nur wissen, was mit dem Carry-Flag passiert, wenn es NICHT 
abgefragt wird.

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Speziell beim AVR kann man doch SREG abfragen. Das geht auch in C ohne
> Assembler-Befehle.

Das wird nur durch Zufall funktionieren, wenn überhaupt.

Beispiel:

a += 1
b = SREG

Niemand garantiert dir, dass zur zweiten Zeile das carry flag noch den 
Zustand von der "add" instruktion hat. Nein, auch nicht wenn interrupts 
abgeschaltet sind. Genauer gesagt garantiert auch niemand, dass 
überhaupt eine add instruktion verwendet wird. Der compiler könnte 
möglicherweise auch das ganze Konstrukt auflösen, weil vielleicht alles 
zur Compilezeit bekannt ist oder sonst eine andere beliebige 
Optimierung. Und dann kommt bei dem SREG nur nur zufälliges Gemüse raus.

Die einzige Möglichkeit ist es sowohl das add als auch das lesen des 
carry bits im inline-assembly auszuführen.

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Muss ich es händisch zurücksetzen ist die goldene Frage! Oder anders:
> Will nur wissen, was mit dem Carry-Flag passiert, wenn es NICHT
> abgefragt wird.

Nichts. Du musst gar nichts machen. Der Überlauf einer unsigned Variable 
ist vollständig in C definiert und es passiert garantiert nichts 
Unvorhergesehenes.
Da es in C kein carry flag gibt, muss man es natürlich auch nicht 
zurücksetzen.

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs gerade gefunden, hier:
http://www.mikrocontroller.net/articles/AVR-Tutori...

Zitat:
Überläufe, die durch Inkrementieren oder Dekrementieren (INC/DEC) 
erzeugt werden, beeinflussen das Carry-Flag jedoch nicht.

Damit hat sich die Antwort gefunden, da ich jetzt einfach mal davon 
ausgehe, dass der Compiler den ++-Operator nach INC übersetzt!

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Damit hat sich die Antwort gefunden, da ich jetzt einfach mal davon
> ausgehe, dass der Compiler den ++-Operator nach INC übersetzt!

Da würde ich nicht von ausgehen.
Es spielt aber auch keine Rolle wie er es übersetzt. Die CPU Flags 
spielen in C keine Rolle und werden vom Compiler verwaltet (außer 
Spezialflags wie I, die der Compiler nicht antastet).

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Buesch schrieb:
> Da würde ich nicht von ausgehen.

So abwegig?

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke an alle für die Hilfe! Wieder was gelernt!

Autor: Michael Buesch (mb_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Regler schrieb:
> Michael Buesch schrieb:
>> Da würde ich nicht von ausgehen.
>
> So abwegig?

Nein, aber er ergibt keinen sinn von C Ausdrücken auf generierten 
Assemblycode zu schließen.
Ich garantiere dir, dass ich zu jeder Annahme einen Compiler(version) 
finde dem diese Ahnahme egal ist und es anders macht. ;)

Autor: Regler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich garantiere dir, dass ich zu jeder Annahme einen Compiler(version)
> finde dem diese Ahnahme egal ist und es anders macht. ;)

Das ist ja das Fiese! ;)

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.