Hallo zusammen, habe vorher den MC68HC11 programmiert und dachte bisher immer im Groben, das das Carry-Flag beim Überschreiten der der 8-Bit Grenze oder beim unterschreiten der Null-Grenze gesetzt wird. Nun kommt noch hinzu das, das addieren einer Konstanten beim AVR nur durch subrahieren des Zweierkomplements möglich ist (subi Rd,-Konstante). Und hier natürlich darauf zu achten ist das Rd >= r16 ist. Egal, jetzt kommt es aber noch besser. Beim subrahieren der Zweierkomplementkonstante ist der Wert des Ergebnisses zwar gleich wie bei der addition der Konstanten, aber das Carry-Flag verhält sich genau invetiert. Zum Beispiel : ldi r16,255 subi r16,-5 Das Carry-Flag wird nicht gesetzt, auch kein anderes Flag, aber wie erkenne ich das der 8-Bitwert übergelaufen ist ? Anscheinend nur daran, das der Wert des Ergebnisses kleiner als 5 ist. Hoffe auf aufschlußreiche Antworten. Bis dann Bernd_Stein
Das ist ja höchst interressant. Hab es gerade ausprobiert und tatsächlich wird kein einziges Flag beeinflusst. Dann gibt es da nur noch die Möglichkeit über die benutzung eines 2.Registers und den add-Befehl. ldi r16, 255 ldi r17, 5 add r16, r17
Bernd Stein schrieb: > Beim subrahieren der > Zweierkomplementkonstante ist der Wert des Ergebnisses zwar gleich wie > bei der addition der Konstanten, aber das Carry-Flag verhält sich genau > invetiert. Jau, so isses und wo is nu Dein Problem. Du weißt nun, daß das CY-Flag invertiert reagiert, also CY = 0: Überlauf. Peter
Hi >Das ist ja höchst interressant. Hab es gerade ausprobiert und >tatsächlich wird kein einziges Flag beeinflusst. Warum auch? Bei >ldi r16,255 >subi r16,-5 wird 255-250 gerechnet. Subi setzt die Flags H,S,V,N,Z und C. Bei der Beispielrechnung wird aber keine Bedingung zum Setzen eines dieser Flags erfüllt. MfG Spess
Steffen H. schrieb: > Das ist ja höchst interressant. Hab es gerade ausprobiert und > tatsächlich wird kein einziges Flag beeinflusst. > > Dann gibt es da nur noch die Möglichkeit über die benutzung eines > 2.Registers und den add-Befehl. > > ldi r16, 255 > ldi r17, 5 > add r16, r17 Hallo, gute Idee. Ich merke schon, die neue Generation von µC verlangt flexibles denken. Oder ich bin einfach nur durch die CISC-Archetektur verwöhnt. Bis dann Bernd_Stein
Bernd Stein schrieb: >> ldi r16, 255 >> ldi r17, 5 >> add r16, r17 > > Hallo, > > gute Idee. Schlechte Idee, weil vollkommen überflüssig. Peter
Peter Dannegger schrieb: > Bernd Stein schrieb: >>> ldi r16, 255 >>> ldi r17, 5 >>> add r16, r17 >> >> Hallo, >> >> gute Idee. > > Schlechte Idee, weil vollkommen überflüssig. Das Carry wird bei Unterlauf der Subtraktion gesetzt. Gefragt ist aber der Überlauf bei Addition.
1 | SUBI Rd, K |
2 | |
3 | C: Set if the absolute value of K is larger than the absolute |
4 | value of Rd; cleared otherwise |
spess53 schrieb: ... > > Bei > >>ldi r16,255 >>subi r16,-5 > > wird 255-250 gerechnet. Subi setzt die Flags H,S,V,N,Z und C. Bei der > Beispielrechnung wird aber keine Bedingung zum Setzen eines dieser Flags > erfüllt. > > MfG Spess Hallo, ich habe schon oft gemerkt, das Leute die sich mit einer Materie schon lange auseinander setzen oder Ihnen diese absolut klar ist, sich nicht in die Lage der anderen versetzen können. Ich will hier keine Haarspalterei herbei führen, aber als lernender nehme ich an jeder mir unverständlichen Kleinigkeit anstoß. Also, -5 ist $FA sprich wirklich 250. Im obigen Programm kommt laut Simulator 4 heraus, was ich auch so sehe. 255-250 ist 5 was ich ebenfalls als Richtig erachte. Wo ist mein Denkfehler oder evtl. deiner ? Bis dann Bernd_Stein
Bernd Stein schrieb: > Also, -5 ist $FA sprich wirklich 250. Ne, es ist Zweierkomplement:
1 | 5 = 0b00000101 |
2 | -5 = 0b11111010 + 1 = |
3 | 0b11111011 = 0xFB = 251 |
Hi >Also, -5 ist $FA sprich wirklich 250. >Im obigen Programm kommt laut Simulator 4 heraus, was ich auch so sehe. >255-250 ist 5 was ich ebenfalls als Richtig erachte. Da hat sich bei mir ein Fehler eingeschlichen: -5 ist $FB also dezimal 251. Und damit ist 4 als Ergebnis verständlich. MfG Spess
Sorry, aber ich verstehe die Diskussion nicht. Wieso ist der eine Operand unsigned, der ander signed. Auch bei Assembler gilt doch: Entweder oder, aber immer beide - oder nicht? Interpretation als signed: 0xFF = -1 0XFA = -5 -1 - -5 = 4. Ist doch vollkommen korrekt, wo soll hier ein fracking Überlauf passieren? Das korrekte Ergebnis ist weder kleiner als -128 noch größer als +127. Interpretation als unsigned: 0xFF = 255 0xFA = 251 255 - 251 = 4, ebenfalls korrekt, ebenfalls kein Überlauf. Oder bin ich jetzt auf dem Holzweg? Gruß, DetlevT
Detlev T. schrieb: > Sorry, aber ich verstehe die Diskussion nicht. > > Wieso ist der eine Operand unsigned, der ander signed. Weil es darum geht eine Addition durch eine Subtraktion darzustellen also gilt: x + 5 = x - (-5)
Detlev T. schrieb: > Sorry, aber ich verstehe die Diskussion nicht. > > Wieso ist der eine Operand unsigned, der ander signed. Auch bei > Assembler gilt doch: Entweder oder, aber immer beide - oder nicht? > Interpretation als signed: > 0xFF = -1 > 0XFA = -5 Nein, 0xFA = -6! Der Instruktion ist das egal, die rechnet immer vorzeichenlos. Lediglich dein Assembler verwandelt -5 ins Zweierkomplement, und -5 ist dort eben 0xFB! Es wird 0xFF - 0xFB gerechnet, das ist eben 4. Und da ist nichts dabei, was einen Übertrag auslösen würde.
Läubi .. schrieb: > Weil es darum geht eine Addition durch eine Subtraktion darzustellen > also gilt: x + 5 = x - (-5) Schon klar, aber in dieser Fall kann x nur Werte [-128...127] annehmen. Der Controller kennt doch gar keine negativen Zahlen, gerade deswegen nimmt man doch den Trick mit dem Zweierkomplement. Die Interpretation des Ergebnisses ergibt sich erst aus dem weiteren Programm. Beispiel x = 127 = 0x7F x + 5 = x - (-5) = 0x7F - 0xFB (Hast ja recht, Sven) = 0x84 = -124 ist z.B. ein Überlauf, da der korrekte Wert (132) in 8-Bit(signed) nicht mehr darstellbar ist. In diesem Fall wird aber auch das carry-Flag beeinflusst! Es ist einfach der Denkfehler, zu denken, beim subi könnte der Controller den einen Operanden als unsigned und den anderen als signed betrachten. Ich sehe immer noch keinen Fehler beim Controller. Gruß, DetlevT
Du hast es schon richtig erkannt, das CY ist invertiert bei a = a - (-b) Also mußt Du nur BRCC anstelle BRCS nehmen. Bzw. wenn Du ne 16Bit Konstante addieren willst: SBI rl, low(-Konstante) SBCI rh, high(-Konstante) Wird z.B. gemacht für nen Indexzugriff, die Konstante ist dann der Offset des Arrays. Peter
Sven P. schrieb: > Bernd Stein schrieb: >> Also, -5 ist $FA sprich wirklich 250. > Ne, es ist Zweierkomplement: >
1 | > 5 = 0b00000101 |
2 | > -5 = 0b11111010 + 1 = |
3 | > 0b11111011 = 0xFB = 251 |
4 | > |
Oh ja danke, hatte mich erst vertan. -5 => 0b1111 1001 => $F9. Keine Ahnung was da in meinem Gerhirn falsch gelaufen ist. Dann habe ich mich korregiert 0b1111 1011 und dachte ein Bit mehr als vorher, deshalb $FA passte auch gut zu den 250 von Spess53. Also schon wieder eine Fehlfunktion in meinem Gehirn. Habe aber eigentlich genau das vorgehabt was Du oben beschreibst, nämlich die Zweierkomplementbildung von 5. Nochmals Danke für deine ausführliche Hilfe. Bis dann Bernd_Stein
Bernd Stein schrieb: > > Zum Beispiel : > > ldi r16,255 > subi r16,-5 > > Das Carry-Flag wird nicht gesetzt, auch kein anderes Flag, > aber wie erkenne ich das der 8-Bitwert übergelaufen ist ? > > Anscheinend nur daran, das der Wert des Ergebnisses kleiner als 5 ist. > Hallo, das sollte nur ein Beispiel sein. Meine generell : Hole einen Meßwert und addiere einen Offset hinzu. Wie erkenne ich nun Programmtechnisch elegant (Assembler), das der Zahlenbereich von 8-Bit überschritten wurde ? Bis dann Bernd_Stein
Bernd Stein schrieb: > Wie erkenne ich nun Programmtechnisch elegant (Assembler), das der > Zahlenbereich von 8-Bit überschritten wurde ? Wie schon von Peter gesagt wurde, das Carry-Bit reagiert schlicht und einfach nur invertiert. Also einfach die Verzweigung nach der Subtraktion gegenüber der eigentlich gewollten Addition vertauschen, entweder durch Negation der Sprungbedingung (BRCC durch BRCS bzw. umgekehrt ersetzen), oder eben die Sprungziele vertauschen. Andreas
Bernd Stein schrieb: > Wie erkenne ich nun Programmtechnisch elegant (Assembler), das der > Zahlenbereich von 8-Bit überschritten wurde ? Falls der rauskommende Wert kleiner als dein Offset ist, wars ein Überlauf, ansonsten hat es gepasst. z.B. 68 + 5 = 73 ->passt 200 + 60 = 260 = 4 ->Überlauf 255 + 255 = 510 = 254 ->Überlauf 23 + 200 = 223 -> passt ... Hoffe mein gedankengang ist richtig :-)
Andreas Ferber schrieb: > Bernd Stein schrieb: >> Wie erkenne ich nun Programmtechnisch elegant (Assembler), das der >> Zahlenbereich von 8-Bit überschritten wurde ? > > Wie schon von Peter gesagt wurde, das Carry-Bit reagiert schlicht und > einfach nur invertiert. Also einfach die Verzweigung nach der > Subtraktion gegenüber der eigentlich gewollten Addition vertauschen, > entweder durch Negation der Sprungbedingung (BRCC durch BRCS bzw. > umgekehrt ersetzen), oder eben die Sprungziele vertauschen. > > Andreas Peter Dannegger schrieb: > Du hast es schon richtig erkannt, das CY ist invertiert bei > a = a - (-b) > Also mußt Du nur BRCC anstelle BRCS nehmen. Guten morgen liebe schlaflosen, vielleicht bin ich noch nicht wach genung, um zu verstehen warum das so ist. Aber egal, belassen wir es dabei. Jetzt ist für mich wirklich ein Punkt erreicht wo ich damit abschliesse dies auch noch verstehen zu wollen. Es ist halt so !!! Vielen Dank an alle, die hier mitgewirkt haben. Bis demnächst Bernd_Stein
Bernd Stein schrieb: > Jetzt ist für mich wirklich ein Punkt erreicht wo ich damit abschliesse > dies auch noch verstehen zu wollen. > Es ist halt so !!! Und damit liegst du goldrichtig, es ist letztlich einfach so definiert. Jetzt kann man sich natürlich fragen, warum das so und nicht anders definiert wurde. Dafür gibt es einen einfachen Grund, es macht die Hardware-Implementierung einfacher, nicht mehr und nicht weniger. Siehe auch http://de.wikipedia.org/wiki/Additionsschaltung#Subtrahierer Andreas
Hallo Bernd, das kann ich nachvollziehen. Ich habe auch eine ganze Zeit gebraucht bis ich es verstanden zu haben glaube. Also, du willst y = x + d ausrechnen. Wegen der Einschränkung berechnet der Controller jedoch y = x - (-d). (-d) ist das Zweierkomplement von d, das wissen aber nur du und dein Compiler. Für den Controller ist das eine ganz normale (positive) Binärzahl. Nun sind bei d<> 0 zwei Ergebnisse denkbar: 1.) y > x: Für dich ist das kein Überlauf, denn es wurde eine so kleine Zahl "addiert", dass der Wertebereich nicht verlassen wurde. Der Controller kommt hier aber nur hin, indem er über "Null" subtrahiert, für ihn ist das also ein Überlauf. 2.) y <= x: Für dich ist das ein Überlauf, weil mathematisch die Summe zweier positiver Zahlen nicht kleiner sein kann als die einzelnen Summanden. Für den Controller ist das aber gerade kein Überlauf, denn er kommt wegen der Subtraktion ja gerade an diese Stelle ohne "über Null" zu gehen. Insgesamt stimmt es also, dass die Funktion des Carry-Flags genau invertiert ist, deshalb aber sehr wohl genutzt werden kann. q.e.d. :D Gruß, DetlevT
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.