900ss D. schrieb: > Danke. Mach' einen Smiley dahinter. Er denkt noch, du meinst das ernst.
Johann L. schrieb: > avr-gcc: Braucht 40 Instruktionen für "adu", davon sind 5 32-Bit > Instruktionen. Bei welcher Optimierungsstufe?
A. K. schrieb: > zu Lasten von ein paar > Befehlen mehr > diesen mit 9 Takten doch wesentlichen schnellern Code produziert: Vor diesem Szenario steht man auch öfter bei Asm: weniger Platz oder mehr Performance. In diesem Fall hab ich weniger Platzbedarf den Vorzug gegeben.
Johann L. schrieb: > uint16_t *adc = & ADUC[adc_num]; > uint16_t sum64 = adc[N_ADCs] += ADC; Die beiden Zeilen kommen mir total spanisch vor. Liegt sicher nur an meinem niedrigen Niveau. Warum '+='? 16-Bit-Werte aufaddieren... Das passt zum Schluss immer noch in 16 Bit? Ich durchschaue den Trick nicht. (Bitte nicht hauen!) Und dann noch der extra Index am Zeiger. Ich gebe auf...
:
Bearbeitet durch User
Ralf G. schrieb: > Johann L. schrieb: > uint16_t *adc = & ADUC[adc_num]; > uint16_t sum64 = adc[N_ADCs] += ADC; > > Die beiden Zeilen kommen mir total spanisch vor. Liegt sicher nur an > meinem niedrigen Niveau. Warum '+='? 16-Bit-Werte aufaddieren... Das > passt zum Schluss immer noch in 16 Bit? Ich durchschaue den Trick nicht. > (Bitte nicht hauen!) > > Und dann noch der extra Index am Zeiger. Ich gebe auf... Der ADC hat 10 Bit Auflösung, d.h. die 64 aufsummierten Werte haben jeder höchstens 3FFH. An dieser kryptischen Darstellung würd ich auch verzweifeln ;-)
:
Bearbeitet durch User
Moby A. schrieb: > An dieser kryptischen Darstellung würd ich auch verzweifeln Hatte gerade einen kleinen Brown-Out.
Moby A. schrieb: > Falls Du darauf abzielst für solcherlei Berechnungen besser C samt > 32Bit-Controller zu verwenden zielst Du jedenfalls nicht auf typische > 8-Bit Anwendungen. Da sind solche Berechnungen selten. Hast du schon mal was mit den Sensirion Feuchtesensoren gemacht, SHT11 und Verwandte? Ist meiner Ansicht nach eine durchaus typische 8-Bit Anwendung, die auf einem x8er AVR in einem Auto-Sensormodul steckt, das via Bluetooth mit einem Handy kommuniziert (Feuchte, Temperatur und zum Spass noch Luftdruck). Ist fast durchweg 8/16-Bit Code und problemlos auch in Asm umsetzbar. Nur hinter dieser harmlosen letzten Zeile steckt wohl etwas Arbeit:
1 | int v = result(); |
2 | const int32_t C1 = (int32_t)(-4.0 * 100); |
3 | const int32_t C2 = (int32_t)(0.0405 * 100 * (1L<<28)); |
4 | const int32_t C3 = (int32_t)(-2.8e-6 * 100 * (1L<<30)); |
5 | v = (int)((((((C3 * v) >> 2) + C2) >> 11) * v + (1L<<16)) >> 17) + C1; |
Aber wegen dieser Kleinigkeit gleich einen 32-Bitter nehmen?
:
Bearbeitet durch User
A. K. schrieb: > Hast du schon mal Ja hab schon mal. Einen MS5534c in meiner Wetterstation. Gleiche Rechenorgie. Deshalb schrieb ich "selten" . Aber deshalb auf C/32Bit umsteigen? Wenn das täglich vorkommen würde...
:
Bearbeitet durch User
Moby A. schrieb: > Gleiche Rechenorgie. Ergänzung: Streng geheim!! Ich kann nicht mehr. Ich bin weg. :-)
Ralf G. schrieb: > Ergänzung: Streng geheim!! Genau. Deshalb sag ichs ja. Aber kein Grund zur Panik: > Ich kann nicht mehr. Ich bin weg. :-) Oder liegts am C-Code? ;-)
:
Bearbeitet durch User
Ausnahmsweise: Moby A. schrieb: > Ja hab schon mal. Mensch Moby, das war 'ne Steilvorlage!! Falsch. Das war 'n Elfmeter mit doppelter Torbreite, ohne Torwart, mit zwei Versuchen! Und du versemmelst das! Ich fass' es nicht.
Ralf G. schrieb: > Johann L. schrieb: >> uint16_t *adc = & ADUC[adc_num]; >> uint16_t sum64 = adc[N_ADCs] += ADC; > Die beiden Zeilen kommen mir total spanisch vor. > [...] Und dann noch der extra Index am Zeiger. Ich gebe auf... Das liegt an der asm-Vorlage. Die 2 Variablen, die zur "Verwaltung" eines ADC-Kanals gehören, liegen im Speicher verstreut. Ohnehin ist es recht sinnfrei, einen gegebenen Asm-Code genauso umsetzen zu wollen — das zeigen schon die magischen Konstanten wie $40. (Die zu entsorgen freilich auch mit Asm nix kostete. Sie sind der Tribut an einen Hang zur Kryptophilie). * Die Variablen, die man zur "Verwaltung" eines ADC-Kanals brauch, wird man zusammenhalten wollen, z.B. in einer Struktur wie unten. * Der IRQ-Zähler hat eigentlich nix mit dieser Routine zu tun; den wird man von außen reingeben. Falls er doch zum Modul gehören sollte, dann in die gleiche Struktur in der auch die adcs[] leben:
1 | typedef struct |
2 | {
|
3 | struct adc |
4 | {
|
5 | uint16_t result, temp; |
6 | } adcs[4]; |
7 | uint8_t n_irq; |
8 | } aduc_t; |
9 | |
10 | aduc_t ADUC; |
11 | |
12 | void adu (uint8_t n_irq) |
13 | {
|
14 | uint8_t n_adc = 3 & (n_irq >> 6); |
15 | struct adc *adc = & ADUC.adcs[n_adc]; |
16 | |
17 | uint16_t temp = adc->temp += ADC; |
18 | |
19 | if (0 == (n_irq & 0x3f)) |
20 | {
|
21 | adc->result = temp >> 6; |
22 | adc->temp = 0; |
23 | |
24 | uint8_t refs = (n_irq & 0x80) |
25 | ? (1 << REFS1) | (1 << REFS0) |
26 | : (1 << REFS0); |
27 | |
28 | ADMUX = refs | n_adc; |
29 | }
|
30 | }
|
Der Code wird dadurch etwas kleiner — n_irq (vormals IC) würde dann wie gesagt an adäquater stelle (z.B. ISR) verwaltet. Der avr-gcc Code ist immer noch nicht optimal, das Optimierungspotential wird gar noch größer; der Code ist aber immer noch kleiner als Mobys Code. Aber es geht ja schon längst nicht mehr darum, ob der C-Code ein paar poplige Bytes länger oder kürzer ist. Er ist auf der Ebene einfach besser wartbar, z.B. kann ohne Codeänderung die langsame >> 6 Schleife durch linearen Code ersetzt werden, wie Andereas ja bereits anmerkte. Es wäre wesentlich schneller gewesen, eine gescheite Dokumentation zu haben und anhand dieser eine neue Implementation vorzunehmen, anstatt die Bitgepfriemel reverse-engineeren. Moby A. schrieb: > Johann L. schrieb: >> Ergo: Wenn Moby seinen optimalen ASM-Code noch optimaler bekommen >> will, lohnt ein Blick über den Tellerrand > > Mir Deine Übersetzung zu Gemüte zu führen Lass es. Das implementiert man besser komplett neu :-) Hier noch meine Lösung zum Vergleich gegen 1000000, etwa wie in
1 | extern void f (void); |
2 | |
3 | void caller (uint32_t val) |
4 | {
|
5 | if (val < 1000000) |
6 | f(); |
7 | }
|
Lösung:
1 | caller: |
2 | cpi r22,64 |
3 | sbci r23,66 |
4 | sbci r24,15 |
5 | cpc r25,__zero_reg__ |
6 | brsh .L1 |
7 | jmp f |
8 | .L1: |
9 | ret |
10 | .ident "GCC: (GNU) 5.2.1 20150816" |
Es ist meine Lösung, weil: http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/config/avr/avr.c?r1=179124&r2=179123&pathrev=179124#l3171 Andreas hat sich also doch nicht verzählt... Moby A. schrieb: > Johann L. schrieb: >> Ob Code Code ist oder Hack, entscheidet sich zu 5% am Code und zu 95% an >> Kommentaren und Dokumentation. > > Oh das ist mir neu. > > Johann L. schrieb: >> Ein nicht unwesentlicher Teil der AVR-Entwickler, die sich >> hier tummeln, verwendet ASSEMBLER-Code aus meiner Feder. > > Find ich gut. Schön, wusst ich's doch. Der Code wird nämlich von avr-gcc erzeugt :-) > Ein Blick über den Tellerrand ist immer sinnvoll. > Welche Erkenntnisse das bringt ist die zweite Frage. Kein Teller is so groß, als dass es jenseits seines Randes nichts Neues, nicht Interessantes oder nicht Aufregendes zu entdecken gäbe. Inwieweit wird dazu in der Lage sind, ist keine Frage der Weite des Teller, sondern eine Frage der Höhe der Mauern im Kopf, der Weite der Phantasie, der Kühnheit, Eingeschliffenes infrage zu stellen und auf wackligen Beinen neuen Grund zu betreten, des Mutes, dabei zu stolpern und sich dem Gelächter alter Hasen auszusetzen, des Strebens, wirklich gute Lösungen zu finden ohne sich in Perfektionismus zu verhakeln, und der Muße, guten Dingen und dem Lernen die Zeit zuzugestehen, die ihnen gebührt.
:
Bearbeitet durch User
Johann L. schrieb: > cpi r22,64 > sbci r23,66 > sbci r24,15 > cpc r25,__zero_reg__ Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche, sondern so gemischt. (Ist gleich lang, gleich schnell. Sieht nur 'ungewöhnlich' aus.)
Moby schrieb: > Verstehen hier wirklich so wenige noch Asm? Keiner hängt sich das Assembler-Täfelchen so nachdrücklich um den Hals wie du... Moby A. schrieb: > @TO > In einem öffentlichen wie diesem Thread musst Du mit den Antworten leben Nicht unbedingt. Es es sein Thread. Er hat ihn eröffnet und darf ihn zuallererst selber moderieren. Dass ihm Andere seinen Thread entführen und verunstalten gehört nicht zum guten Umgangston. Im realen Leben ist es, wie wenn er eine Besprechung einberufen hat, und einfach jeder sein Zeug bespricht. Das ist zumindest unhöflich...
Schön, daß der Code weiter verbessert wird, obwohl ich immer noch nicht durchsteige... So kann ich leider noch nicht die Gleichwertigkeit mit meinem Code abschätzen. Allerdings hab ich den Eindruck, daß meine Lösung schneller aufs Papier gebracht war, halte Johann L. aber auch die Zeit fürs Reverse Engineering zugute ;-) Ganz sicher ist aber, daß diese Form kryptischer Problemlösung niemals die meine werden wird. Schließlich wollte ich noch die versprochene Lösung für 900ss nachtragen: Der C-Vorgabe > void f (void); > > void caller (uint32_t val) > { > if (val < 1000000) > f(); > } ist die Lösung > Lösung:caller: > cpi r22,64 > sbci r23,66 > sbci r24,15 > cpc r25,__zero_reg__ > brsh .L1 > jmp f > .L1: > ret > .ident "GCC: (GNU) 5.2.1 20150816" nicht ganz äquivalent, weil die Variable verloren geht. Besser und ohne die Konstante in ihre Bytebestandteile zu zerlegen ist ganz unspektakulär
1 | .equ Konstante = 1000000 |
2 | |
3 | cpi r25,byte4(Konstante) |
4 | brlo f1 |
5 | cpi r24,byte3(Konstante) |
6 | brlo f1 |
7 | cpi r23,byte2(Konstante) |
8 | brlo f1 |
9 | cpi r22,byte1(Konstante) |
10 | brsh end |
11 | f1: ... |
12 | |
13 | end: ret |
Das kostet im Maximum 9 Takte. Lothar M. schrieb: > Moby schrieb: >> Verstehen hier wirklich so wenige noch Asm? > Keiner hängt sich das Assembler-Täfelchen so nachdrücklich um den Hals > wie du... ... mit dem 8-Bit AVR in der Hand. Das bleibt eine ideale Kombination. Da ist das letzte Wort hier noch lange nicht gesprochen. > Es es sein Thread. Er hat ihn eröffnet und darf ihn > zuallererst selber moderieren. D Der TO hat sich lebhaft an der Diskussion beteiligt. Einige Moderatoren (mit mir) auch (nicht immer sehr sachlich). Die Beschwerde kam erst in Form einer üblen Beleidigung. Darum solltet Ihr Moderatoren Euch mal zuallererst kümmern. > Im realen Leben sind wir hier nicht. Das schließt Höflichkeit natürlich nicht aus.
Ralf G. schrieb: > Warum nicht nur Subtraktion bzw. Vergleiche, sondern so > gemischt. Mist. Meine Assemblerkenntnisse sind doch ganz schön eingerostet. (Der Vergleich mit Übertrag...)
Moby A. schrieb: > Das kostet im Maximum 9 Takte. Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem Thread anmerken muss. Beispielsweise wenn r25 > byte4(...) aber r24 < byte3(...).
:
Bearbeitet durch User
A. K. schrieb: > Moby A. schrieb: >> Das kostet im Maximum 9 Takte. > > Und ist falsch. Ich fragte mich schon, warum der Johann dem Moby so eine einfache Aufgabe stellt. Um den Moby an seine Grenzen zu führen, muss doch was richtig Knackiges her. Aber offensichtlich war die Aufgabe immer noch zu schwer :( Und bevor wir hier weiterdiskutieren und immer mehr vom Usprungsthema abkommen: Moby, fang doch bitte einen neuen Thread an. Dann beschwert auch keiner darüber, dass du den Thread kaperst.
Moby A. schrieb: > .equ Konstante = 1000000 > > cpi r25,byte4(Konstante) > brlo f1 > cpi r24,byte3(Konstante) > brlo f1 > cpi r23,byte2(Konstante) > brlo f1 > cpi r22,byte1(Konstante) > brsh end > f1: ... > > end: ret Eben, leider falsch, und sicherheitshalber hier mal zitiert, ansonsten verschwindet das wieder, wie weiter oben schon einmal ein Detail.
A. K. schrieb: > Moby A. schrieb: >> Das kostet im Maximum 9 Takte. > > Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem > Thread anmerken muss. Beispielsweise wenn r25 > byte4(...) aber r24 < > byte3(...). Klar, hast recht. So geht das nun nicht. Ist wohl schon zu spät heute geworden ;-) Ich liefere aber noch eine korrekte Lösung, soviel Ordnung muß sein. Dann soll der TO walten wie er will. Obs dann hier noch lange weitergeht?
A. K. schrieb: > Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem > Thread anmerken muss. Täusche ich mich oder geht es hier immer noch um den Vergleich zweier 4-Byte-Zahlen? Den Fehler hatte ursprünglich ich eingeschleppt: Josef G. schrieb: > Vergleich von zwei unsigned 4-Byte-Zahlen A und B > mit 8bit-CPU und Sprung falls A > B > > Die 4 Bytes seien A3,A2,A1,A0 bzw. B3,B2,B1,B0 > > Methode 1: > > Teste A3 > B3 > Sprung falls A3 > B3 > Teste A2 > B2 > Sprung falls A2 > B2 > Teste A1 > B1 > Sprung falls A1 > B1 > Teste A0 > B0 > Sprung falls A0 > B0 > > Methode 2: > > Berechne B0 - A0 mit Carry > Berechne B1 - A1 mit Carry > Berechne B2 - A2 mit Carry > Berechne B3 - A3 mit Carry > Sprung falls Carry gesetzt Die korrigierte Version von Methode 1 hat A.K. schon angegeben. Ich würde sie so schreiben: Teste A3 > B3 Sprung falls A3 > B3 Abbruch falls nicht A3 = B3 Teste A2 > B2 Sprung falls A2 > B2 Abbruch falls nicht A2 = B2 Teste A1 > B1 Sprung falls A1 > B1 Abbruch falls nicht A1 = B1 Teste A0 > B0 Sprung falls A0 > B0 Dabei ist angenommen, dass der compare-Befehl einen Carry und ein Zero-Flag liefert. Abbruch bedeutet Sprung ans Ende. Bei Methode 2 ist angenommen, dass die CPU bei der Subtraktion den Subtrahenden und den Carry am Addierer invertiert (wie bei 8085) und nicht nur den Subtrahenden invertiert (wie bei 6502), und dass zu Beginn der Carry Null ist.
:
Bearbeitet durch User
Moby A. schrieb: > Ich liefere aber noch eine korrekte Lösung, soviel Ordnung muß sein:
1 | .equ Konstante = 1000000 |
2 | |
3 | cpi r25,byte4(Konstante) |
4 | brlo f1 |
5 | brne end |
6 | cpi r24,byte3(Konstante) |
7 | brlo f1 |
8 | brne end |
9 | cpi r23,byte2(Konstante) |
10 | brlo f1 |
11 | brne end |
12 | cpi r22,byte1(Konstante) |
13 | brsh end |
14 | f1: ... |
15 | |
16 | end: ret |
Also noch BRNE-3 Takte mehr = Max.12 bei zerstörungsfreier Variable. Wiegesagt, selten gebraucht bei 8-Bit AVR! Unbekannt U. schrieb: > Eben, leider falsch, und sicherheitshalber hier mal zitiert, ansonsten > verschwindet das wieder, Du hast ja hier wirklich wichtige Aufgaben desnachts ;-)
Also gut, dann eben zerstörungsfrei:
1 | void g(long); |
2 | void f(long x) |
3 | {
|
4 | if (x < 1000000) |
5 | g(x); |
6 | }
|
Ergebnis vom Compiler:
1 | cpi r22,64 |
2 | ldi r18,66 |
3 | cpc r23,r18 |
4 | ldi r18,15 |
5 | cpc r24,r18 |
6 | cpc r25,__zero_reg__ |
7 | brge .L1 |
Ergebnis von Moby:
1 | cpi r25,byte4(Konstante) |
2 | brlo f1 |
3 | brne end |
4 | cpi r24,byte3(Konstante) |
5 | brlo f1 |
6 | brne end |
7 | cpi r23,byte2(Konstante) |
8 | brlo f1 |
9 | brne end |
10 | cpi r22,byte1(Konstante) |
11 | brsh end |
:
Bearbeitet durch User
A. K. schrieb: > Ergebnis vom Compiler:
1 | cpi r22,64 |
2 | ldi r18,66 |
3 | cpc r23,r18 |
4 | ldi r18,15 |
5 | cpc r24,r18 |
6 | cpc r25,__zero_reg__ |
7 | brge .L1 |
Und der (der Compiler) ist praktisch nur im AVR-Studio auf 'Assembler Help' gegangen, hat das Beispiel zum 'cpc-Befehl' abgekupfert und auf vier Bytes erweitert. ;-)
Ralf G. schrieb: > Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test > gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche, sondern so > gemischt. Für jedes Byte eines Multibyte-Compares wird einzeln die Entscheidung getroffen, welcher Befehl verwendet wird. Fürs erste Byte gibt es CPI, für das letzte das Register mit Inhalt 0. Für die anderen wird nachgesehen, ob die linke Seite überschrieben werden darf. Wenn ja wird SBCI draus, wenn nicht LDI/CPC. Passt so auf beide Versionen des Codes, die vorherige mit SBCI und die jetzige mit LDI/CPC. Siehe Johanns Link oben, das hat er verbrochen. Würde die Entscheidung über die zu verwendenden Methode vorneweg für alle Bytes getroffen, statt für jedes Byte einzeln, wäre hier die Optimierung über das Zero-Register über Bord gefallen. Anders als Assembler-Programmierern ist Compilern die Eleganz des entstehenden Codes gleichgültig. Zu Mobys Fehleinschätzungen gehört wohl die Vorstellung, dass jene Leute, die C verwenden, deshalb keine Ahnung von Asm hätten. Das trifft freilich nicht immer zu.
:
Bearbeitet durch User
A. K. schrieb: > Für jedes Byte eines Multibyte-Compares [...] Ralf G. schrieb: > Mist. Meine Assemblerkenntnisse sind doch ganz schön eingerostet. (Der > Vergleich mit Übertrag...) Wie das funktioneren soll, ist mir schon klar. Ich hatte gedanklich in der Sequenz einen Compare-With-Carry-Befehl drin, der auch Konstanten verarbeitet. Den gibt's aber gar nicht. Und da kommt? ... natürlich die Subtraktion ins Spiel.
Ralf G. schrieb: > der Sequenz einen Compare-With-Carry-Befehl drin, der auch Konstanten > verarbeitet. Den gibt's aber gar nicht. Und da kommt? ... natürlich die > Subtraktion ins Spiel. Ein Compare-With-Carry Befehl ist ohnehin nicht sehr verbreitet. Die meisten Architekturen kennen ihn nicht. Was freilich auch damit zusammenhängt, dass er nur bei Architekturen mit mehreren Rechenregistern im Zusammenspiel mit 2-Register-Befehlen Sinn ergibt. Bei Akkumulator- oder 3-Register-Befehlen ist er sinnlos. Recht clever und ebenfalls selten ist auch die Handhabung des Z-Flags in SBC(I) und CPC, die ein für das Gesamtergebnis gültiges Z-Flag hinterlässt. Bei den meisten Maschinen ist das Z-Flag nur für das letzte Wort gültig und daher beim Multiwort-Vergleich nutzlos.
:
Bearbeitet durch User
A. K. schrieb: > Recht clever ist auch die Handhabung des Z-Flags in SBC(I) und CPC Ja. :) Wie gesagt, ich weiß wo ich nachschlagen muss, da ich mir nicht mehr alle Befehle geläufig sind. Da habe ich dann gesehen, dass es sowas wie 'cpci' gar nicht gibt. Hätte mich dann sicher für sowas... A. K. schrieb: > Ergebnis vom Compiler: > cpi r22,64 > ldi r18,66 > cpc r23,r18 > ldi r18,15 > cpc r24,r18 > cpc r25,__zero_reg__ > brge .L1 ... entschieden. Aber nicht um zu sagen: 'Bei mir existiert die Variable aber noch!', sondern weil ich auf die andere Variante gar nicht gekommen wäre.
Ralf G. schrieb: > sondern weil ich auf die andere Variante gar nicht gekommen wäre. Das ist einfach nur die übliche Variante für zu Fuss programmierte Vergleiche von potentiell längeren Strings, auch bei AVR. Allein schon, weil du bei einem String nicht alle 50 Bytes abklappern willst, wenn es nach den ersten paar Bytes schon klar ist.
Danke Moby, immerhin hast du deinen Code gepostet. Fazit: Auch handgeschriebener ASM-Code ist nicht immer besser als der vom Compiler. Ich verwende wohl weiter den Compiler.... Aber nicht nur deshalb. Alle Vorteile des Compilers wurden ja schon genannt, selbst bei kleinen Projekten ist die Verwendung von ASM-Code nur zweifelhaft von Vorteil. Es gibt Gebiete, wo es sinnvoll ist, ihn einzusetzen (auch schon alles weiter oben erwähnt), genauso wie ein GOTO in 'C'. Warum du Moby, so verbissen an ASM festhälst, wird mir auch ein Rätel bleiben, die von Dir genannten Vorteile sind alle objektiv widerlegt worden. Deine persönliche Begeisterung für ASM-Code ist OK, wenn du mehr Spaß daran hast, dann mach es so. Jedem das was er mag. Allerdings sollte man schon objektiv bleiben und den Tellerrand hat Johann oben ja schon mit gelungenen Worten erwähnt. Neugier: Moby, ist programmieren eher aus Hobby betrieben oder verdienst du dein Geld damit?
Moby A. schrieb: > Ganz sicher ist aber, daß diese Form kryptischer Problemlösung > niemals die meine werden wird. Kryptisch sind beide; kryptisch, weil sie keine oder nur nixnutzige Kommentare enthalten. Johann L. schrieb: > Ob Code Code ist oder Hack, entscheidet sich zu 5% am Code und zu 95% an > Kommentaren und Dokumentation. > Schließlich wollte ich noch die versprochene Lösung für 900ss > nachtragen: > > Der C-Vorgabe > >> void f (void); >> >> void caller (uint32_t val) >> { >> if (val < 1000000) >> f(); >> } > > ist die Lösung > >> Lösung: >>caller: >> cpi r22,64 >> sbci r23,66 >> sbci r24,15 >> cpc r25,__zero_reg__ >> brsh .L1 >> jmp f >> .L1: >> ret >> .ident "GCC: (GNU) 5.2.1 20150816" > > nicht ganz äquivalent, weil die Variable verloren geht. Es ist absolut perfekt 100% äquivalent :-)) Der Wert in R22--R25 wird nämlich nicht mehr benötigt — falls doch, hat Andreas schon eine Lösung gepostet: A. K. schrieb: > Also gut, dann eben zerstörungsfrei:
1 | > void g(long); |
2 | > void f(long x) |
3 | > { |
4 | > if (x < 1000000) |
5 | > g(x); |
6 | > } |
> Ergebnis vom Compiler:
1 | > cpi r22,64 |
2 | > ldi r18,66 |
3 | > cpc r23,r18 |
4 | > ldi r18,15 |
5 | > cpc r24,r18 |
6 | > cpc r25,__zero_reg__ |
7 | > brge .L1 |
> Ergebnis von Moby:
1 | > cpi r25,byte4(Konstante) |
2 | > brlo f1 |
3 | > brne end |
4 | > cpi r24,byte3(Konstante) |
5 | > brlo f1 |
6 | > brne end |
7 | > cpi r23,byte2(Konstante) |
8 | > brlo f1 |
9 | > brne end |
10 | > cpi r22,byte1(Konstante) |
11 | > brsh end |
Doch Vorsich! Der Moby-Vergleich geht NUR für unsigned. Für vorzeichenbehaftete Zahlen muss eine andere Lösung her! > ohne die Konstante in ihre Bytebestandteile zu zerlegen Der von GCC erzeugte Assembler-Code ist selbsterklärend. Ist ja nicht die Aufgabe von GCC, jemand Assembler oder Grundarithmetik beizubringen. Und in Quelle steht "x < 1000000". Da ist nix zerlegt. Yalu X. schrieb: > A. K. schrieb: >> Moby A. schrieb: >>> Das kostet im Maximum 9 Takte. >> >> Und ist falsch. > > Ich fragte mich schon, warum der Johann dem Moby so eine > einfache Aufgabe stellt. Nur aus Interesse. Ehrlich gesagt hatte ich nicht erwartet, dass ein erfahrener Programmierer da strauchelt. Oder zumindest die Haken und Ösen ahnt und 2x nachdenkt bevor er / sie was schreibt. Ich hatte auch nicht erwartet, dass er auf Anhieb die beste Sequenz findet, weil es die eine beste Sequenz nämlich garnicht gibt. > Aber offensichtlich war die Aufgabe immer noch zu schwer :(
Ich bin mir nicht sicher, ob das politisch korrekt ist, wenn ich hier mal (in chronologischer Reihenfolge) was zusammenfasse. (Habe den Beitrag prophylaktisch schon mal selbst gemeldet.) Ich hoffe, die Zitate sind ohne den Zusammenhang noch sinngemäß. ----- Weil eine Hochsprache ein Programm quasi aus Fertigbausteinen zusammensetzt und die Aufgabenstellung damit nur unter Verlusten an Platz und Performance gegenüber der feiner an die Gegebenheiten anpassbaren Asm-Programmierung lösen kann. ----- Hans schrieb: > Wenn du nur 1:1 "übersetztst", dann wird C niemal kleiner als dein ASM > code werden. Kleiner? Wie soll denn das passieren? Da muss sich ein Asm-Programmierer aber schon selten dämlich anstellen :-) ----- Eine uC-Softwarewelt braucht niemand retten, wenn sie mit pure Asm schon im Klartext mit allen seinen Möglichkeiten, Transparenzen und Freiheiten formuliert ist . Immer wieder schön, wenn dann der nächstkleinere Controller genügt ;-) ----- Ich möchte mir von keinem Compiler irgendwas vorschreiben und verschleiern lassen, sondern das Heft des Handelns 100%ig selbst in der Hand behalten. Wo überall geht das heute noch so einfach wie bei den kleinen 8-Bittern? Dazu braucht es nur ein paar Dutzend Asm-Anweisungen und das Datenblatt des Controllers seines Vertrauens. ----- Die wenigen dutzend simplen Asm-Instruktionen bedeuten aber auch, man braucht nicht mehr zu seinem Glück, es vereinfacht und macht die Sache transparent. ----- Vor der Aufgabe, ein gutes Programm zu schreiben stehen Asm- und C- Programmierer gleichermaßen. Asm allein ist nun leider keine Garantie für guten Code [...] ----- X4U schrieb: > Sagt mal, was ist an diesem Codeschnipsel eigentlich lesbar Alles, wenn Du das Datenblatt und die paar Instruktionen kennst. Klartext- und jeder weiß was gespielt wird. ----- Das Ergebnis zählt und ein solches ist natürlich auch in C erreichbar. Das ändert freilich nix an Simplizität und Effizienz von Asm für eine große Klasse von Anwendungen. ----- C ist einfach mehr sprachlicher Aufwand für größere, langsamere Ergebnisse. ----- [ Meine Lieblingsstelle ;-) , Moby an Rufus ] Bist Du fähig mein obiges Beispiel als gleichlange C-Version zu liefern? Nein? Anfänger. Hauptsache große Klappe. ----- Das heißt (zumindest) für viele 8-Bit Projekte: Assembler. Das Werkzeug mit den maximalen Freiheiten und effektivstmöglichen Ergebnissen- mit geringstem bürokratischen Aufwand. ----- Autor: Moby AVR (moby-project) , Sommer 2015 PS: Zählt das eigentlich jetzt schon als Aphorismen
Ralf G. schrieb: > Zählt das eigentlich jetzt schon als Aphorismen Nö. Ein Aphorismus ist ein in sich widersprüchlicher Satz und ohne Kontext verständlich.
A. K. schrieb: > Nö. Ein Aphorismus ist ein in sich widersprüchlicher Satz und ohne > Kontext verständlich. Hmm. Hatte ich jetzt nach... https://de.wikipedia.org/wiki/Aphorismus ... anders interpretiert.
Ralf G. schrieb: > Zählt das eigentlich jetzt schon als Aphorismen Nö, aber man könnte was drauf rappen. Oder so: einfach genialst! https://www.youtube.com/watch?v=9Vg2h_nW0bA
Ralf G. schrieb: > Zählt das eigentlich jetzt schon als Aphorismen Noch nicht ganz. Ich würde es noch eher in die Kategorie der B-Forismen einordnen.
A. K. schrieb: > Nö. Ein Aphorismus ist Johann L. schrieb: > Nö, aber Ich hätte wohl doch ein
1 | ;-) |
hinmachen sollen?
Johann L. schrieb: > Oder so: einfach genialst! > > Youtube-Video "Stoiber On Drums - Jonny König" Sehr schön :-)
Ralf G. schrieb: > Ich hätt's beinahe gegoogelt :-) Vermutlich findet sich dieser Neologismus noch nicht im Duden. Dabei ist die Bedeutung doch ganz einfach: - Bei einem Aphorismus bringt jemand einen Gedanken auf den Punkt. - Bei B-Forismus schreibt jemand in einem Forum immer wieder dasselbe mit anderen Worten. :-)
Ralf G. schrieb: > Johann L. schrieb: >> cpi r22,64 >> sbci r23,66 >> sbci r24,15 >> cpc r25,__zero_reg__ > > Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test > gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche, > sondern so gemischt. Weil es so einfacher ist im Compiler: Der geht alls Bytes von 0 bis N-1 durchund sucht die beste Möglichkeit für den Byte-Vergleich. o CPI geht weil 22 >=16. o CPC 0 geht immer. o SBCI geht weil 23 >= 16 und das Register danach nicht mehr verwendet wird. o CP/CPC geht immer Wobei hier der Code einfach verbessert werden kann: Anstatt zu testen, ob das 32-Bit Register noch verwendet wird, könnte getestet werden, ob das entsprechende 8-Bit Subregister noch verwendet wird: http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/config/avr/avr.c?revision=227035&view=markup#l5394
1 | for (i = 0; i < n_bytes; i++) |
2 | {
|
3 | /* We compare byte-wise. */
|
4 | rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i); |
5 | [...]
|
6 | /* Upper registers can compare and subtract-with-carry immediates.
|
7 | Notice that compare instructions do the same as respective subtract
|
8 | instruction; the only difference is that comparisons don't write
|
9 | the result back to the target register. */
|
10 | |
11 | if (ld_reg_p) |
12 | {
|
13 | if (i == 0) |
14 | {
|
15 | avr_asm_len ("cpi %0,%1", xop, plen, 1); |
16 | continue; |
17 | }
|
18 | else if (reg_unused_after (insn, xreg)) |
19 | {
|
20 | avr_asm_len ("sbci %0,%1", xop, plen, 1); |
21 | continue; |
22 | }
|
23 | }
|
Anstatt auf "xreg" wäre also einfach auf "reg8" zu testen. Ein ideales Einstiegsprojekt für jeden, der schon immer mal am Compiler rumschrauben wollte! Testfall:
1 | extern void f (unsigned); |
2 | |
3 | void test (unsigned long x) |
4 | {
|
5 | if (x < 1000000) |
6 | return f (x); |
7 | }
|
Johann L. schrieb: > Weil es so einfacher ist im Compiler: [...] Ich wusste (also, ich ahnte), dass es schwerer ist als Ralf G. schrieb: > Da habe ich dann gesehen, dass es sowas wie > 'cpci' gar nicht gibt. ;-)
> Doch Vorsich! Der Moby-Vergleich geht NUR für unsigned. Für vorzeichenbehaftete Zahlen muss eine andere Lösung her! Das macht nichts. Kleine AVR's brauchen keine Vorzeichen ;-) Moby's Kühlschrankdisplay zeigt die Temperatur eben in Kelvin an, auch wenn man dabei ein Byte verschwenden muß, denn 255K sind recht kalt ;-) Wenn man sich allein die letzten Diskussionen um Georg's Compilerergebnis anschaut. Soll ich diese Entscheidungen, schnell und fehlerfrei, bei jedem Vergleich selber machen, oder hab ich verstanden, wozu es Software gibt. Auch wenn im Fall Software schreiben/Compiler nur ein Problem gelöst wird, das es ohne IT gar nicht gäbe. Die Aufgabe von Software ist nämlich solche Gedankengänge maschinenausführbar gemacht. Man kann natürlich auch zu Fuß ans Ziel kommen. Aktuell machen das manche zwangsweise um von Griechenland nach DE zu kommen. Aber keiner wird bestreiten, daß man auf dieses "Vergnügen" zugunsten eines 2 1/2h Flugs verziechten kann. So geht's auch denen, die mit Software ihre Brötchen verdienen (mich eingeschlossen). Die Blasen im Hirn haben sich Georg, Jörg und viele andere geholt, dem Rest reicht das Ergebnis. Nur ganz wenige verhandeln mit Atmel wegen Rückgabe unbenützter Flash-Zellen gegen finanziellen Ausgleich. Für die wäre dann eine Berufgruppe aus der Gesundheitsbranche zuständig: die Herren mit den weißen Kitteln.
Horst S. schrieb: > Ich bin jetzt nicht unbedingt davon ausgegangen, dass ein (nicht > optimiertes) Assemblerprogramm in C portiert um 10% größer (und damit > auch langsamer) werden muss. Ist das so? Nachdem ich schon in den ersten Beiträgen eigentlich eine eindeutige Antwort auf meine Frage bekommen hatte, möchte ich mich abschließend bei den Leuten, die sich die Mühe gemacht haben, mein Projekt(chen) anzuschauen und mit konstruktiven Beiträgen zu verbessern, noch mal ganz herzlich bedanken. Ich finde, das ist keine Selbstverständlichkeit und verdient zumindest die Anerkennung, den Antwortern bis zum Schluss zuzuhören (man muss nicht jede Idee übernehmen, aber ausprobieren sollte man das schon mal). Für mich scheint das Problem gelöst, wenn Euch nix Krasses mehr auffällt, sehe ich mich als entlassen. Zu den anderen 90% Beiträgen in diesem Threads: Wenn ich noch mal versehentlich Auslöser solch eines Disputs werde, probier' ich mal ganz blauäugig den "Beitrag melden"-Link und hoffe das Beste. Möge ein Moderator mir beistehen, sein Holzbein überstülpen und (Gregory Peck: "verfluchter Wal") da kräftig mit seiner Harpune reinpieken. Hmmm: wer den Film zu Ende geguckt hat, weiss, das hilft auch nicht immer, aber es sieht zumindest so aus, als ob es Wirkung zeigen könnte. In diesem Sinne Gruß Horst
Horst S. schrieb: > Zu den anderen 90% Beiträgen in diesem Threads Ach, nimm's locker, Horst: allein von Johanns Ausführungen über das, was er (*) da so im Compiler treibt, kann man hinreichend viel auch als gestandener Programmierer noch lernen. ;-) (*) Johann ist derjenige, der in den letzten Jahren am AVR-Backend des GCC massiv herumoptimiert hat. Davor war er zwar auch schon brauchbar, aber eben manchmal recht suboptimal (vermutlich eher das, was Moby sich unter einem Compiler vorstellen würde). Dank Johanns Engagement hat er aber nochmal massiv zugelegt, und es dürfte mittlerweile selbst einem gestandenen Assemblerprogrammierer oft schwer fallen, vergleichbar guten Code zu erzeugen.
Jörg W. schrieb: > und es dürfte mittlerweile selbst einem gestandenen > Assemblerprogrammierer oft schwer fallen, vergleichbar guten Code zu > erzeugen. Oh, wecke mal keine schlafenden Hunde ;-)
900ss D. schrieb: > Oh, wecke mal keine schlafenden Hunde ;-) Nu, immerhin hat Moby heute 2 Beiträge geschrieben ohne ein einziges Mal Assembler zu erwähnen. Kann man vielleicht als Fortschritt werten. ;-) Beitrag "Re: Flashplatzbedarf 32Bit zu 8Bit Microcontroller"
:
Bearbeitet durch User
Moby A. schrieb: > Ich liefere aber noch eine korrekte Lösung, soviel Ordnung muß sein. Moby A. schrieb: > .equ Konstante = 1000000 > ... Der interessanteste Benchmark dieser Aufgabe für mich: 1. Moby braucht dafür 1 Stunde und 5 Minuten 2. avr-gcc braucht bedeutend weniger als 1 Sekunde
:
Bearbeitet durch Moderator
Frank M. schrieb: > Der interessanteste Benchmark dieser Aufgabe für mich: > > 1. Moby braucht dafür 1 Stunde und 5 Minuten Johanns Frage: 28.08.2015 23:08 Mobys Antwort: 29.08.2015 23:37 (die falsche) 30.08.2015 02:02 (die richtige)
A. K. schrieb: > Johanns Frage: 28.08.2015 23:08 > Mobys Antwort: 29.08.2015 23:37 (die falsche) > 30.08.2015 02:02 (die richtige) Ich habe lediglich die Differenz der Zeiten aus beiden der oben zitierten Beiträgen gezogen, weil ich annahm, dass sich Moby dieser Aufgabe tatsächlich erst ab 30.08.2015 00:57 mit dem nötigen Ernst annahm. Alles andere davor war einfach so dahingesaut und nicht ernstzunehmen.
:
Bearbeitet durch Moderator
Moby A. schrieb: > Zeigt mal, wie > sich die Funktionalität in höchstens gleicher C -Codegröße umsetzen > lässt. Das würde ja auf mich viel eher Eindruck machen ;-) Welche Funktionalität denn? Nirgends wird beschrieben, was der Code überhaupt machen soll! Die paar wenigen Zeilenkommentare kannst Du Dir an die Backe schmieren, die sagen 0,nix über die Gesamtfunktion aus. Zu einer ordentlichen Assemblerprogrammdoku gehört auch erstmal die Beschreibung der Regeln, die Du Dir selbst in Deinem Kopf zurecht gelegt hast, wie RAM-Aufteilung, Parameterübergabe, Registerreservierung (zerstörbar, Parameter, Interrupt, Sonderfunktion), Byteorder usw. Wenn Du denkst, jemand kämpft sich durch Dein Assemblerkauderwelsch, um es dann in eine Funktionsbeschreibung zurück zu übersetzen, dann bist Du schief gewickelt. Du verlangst quasi, den Döner (Assembler) in ne Kuh (Funktionsbeschreibung) zurück zu verwandeln, um dann ne Roulade (C) daraus zu machen. Mache erstmal nen PAP oder beschreibe in Worten, was das Programm machen soll, dann erst kann man das auch in C umsetzen.
:
Bearbeitet durch User
Peter D. schrieb: > Welche Funktionalität denn? > Nirgends wird beschrieben, was der Code überhaupt machen soll! Ja, genau das hab ich vor paar Tagen auch schon vergeblich eingefordert...
Moby schrieb: > Es braucht diesbezüglich kein zeitvernichtendes Hinterherhecheln hinter > den neuesten Technologien und Programmiermethoden Da musste man als C-Progammierer niemals irgendwie hinterherhecheln: C ist viel älter als der AVR. Der AVR wurde sogar von Atmel zusammen mit IAR für C-Compiler optimiert.
1 | Atmel and IAR Systems have worked together since 1995, when we participated |
2 | in the design of the successful AVR 8-bit RISC microcontroller core, and |
3 | delivered a tailor-made C compiler. |
(Quelle https://www.iar.com/iar-embedded-workbench/atmel/) Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur und seinen verbastelten Compiler herumgeärgert hatten. Und wenn es schon einen optimierten Prozessor und dazu einen kostenlosen sehr guten Compiler gibt, dann bin ich fertig. Da fange ich nicht mal mehr für den Tiny9 ein Assemblerprojekt an. BTW: Ich kann mir übrigens vorstellen, warum der Thread inzwischen im Offtopic gelandet ist, obwohl er im ersten Fünftel noch hübsche technische Ansätze hatte...
Lothar M. schrieb: > Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller > Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen > Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur > und seinen verbastelten Compiler herumgeärgert hatten. Der 8051 wurde ein einer Zeit entwickelt, in der man solche Aufgaben nicht in C gelöst hat, sondern meist in Assembler. Und für Aufgaben, die mit 256 Bytes RAM auskommen. Da ist er ziemlich gut. Eine Akku-Architektur ist kein Problem für einen C Compiler. Vorzugsweise mit 16-Bit Akku wie 68x11/12. Auf GCC sollte man dann aber verzichten, der ist auf Register konzipiert.
:
Bearbeitet durch User
Lothar M. schrieb: > Da fange ich nicht mal > mehr für den Tiny9 ein Assemblerprojekt an. Da stimme ich zu. Ein simpler PWM-Controller auf einem ATtiny10: die Hälfte vom Flash für eine PWM-Tabelle und der Rest hat immer noch für's Programm gereicht. Ich bleibe beim Compiler, solange es keinen zwingenden Grund für Assembler gibt.
Moby A. schrieb: > Hab mal meine bereits weiter oben zur Sprache gekommene ASM Lösung aus > einem anderen Hochsprachen-Thread(problem) angehängt. Zeigt mal, wie > sich die Funktionalität in höchstens gleicher C -Codegröße umsetzen > lässt. Das würde ja auf mich viel eher Eindruck machen ;-) Deine beiden Codeschnipsel sind Mini-Programme und damit realitätsfern. Bei realistischen Projekten (erzeugte Codegröße ab ca. 2KB) kann man mit Assembler nicht mehr mithalten. Je größer das Programm, desto größer auch der Speicherplatzgewinn mit C. So gut kann kein Assembler-Programmierer sein, dass er bei mittelgroßen bis großen Projekten so gut optimiert wie die Maschine. Ein Compiler kann hier immer noch den Überblick behalten, während der Assembler-Programmierer diesen so langsam aber sicher verliert.
So Moby, jetzt hab ich mir deinen asm Programm mal angesehen. Da sind einige Dinge drin, die unsauber sind. zB hier:
1 | DATARAM: |
2 | KEY0S: .DB 1 ;Key0 (0/$ff= un/betätigt Status) |
3 | KEY0C: .DB 1 ;Key0 (Betätigungsdauer, Counter) |
4 | KEY1S: .DB 1 ;Key1 (0/$ff= un/betätigt Status) |
5 | KEY1C: .DB 1 ;Key1 (Betätigungsdauer, Counter) |
6 | KEY2S: .DB 1 ;Key2 (0/$ff= un/betätigt Status) |
7 | KEY2C: .DB 1 ;Key2 (Betätigungsdauer, Counter) |
Hier definierst Du sechs Variablen, welche hinternander im Speicher liegen. Ok. Aber hier:
1 | systemint: |
2 | ..ldi ZL,low (KEY0S-2) |
3 | ldi ZH,high(KEY0S-2) |
Hier setzt du den Z-Poiter auf zwei Speicherzellen vor das KEY0S. Das funktioniert zwar, weil Du hier:
1 | keyproc: |
2 | adiw ZH:ZL,2 |
beim Aufruf immer plus zwei rechnest und die Tasten in exakt der Reihenfolge abfragst/aufrufst, in der Du die in DATARAM definiert hast. Aber das ist bei weitem keine ordentliche Lösung. Wie soll ein fremder Programmierer, der (nur) die Funktion keyproc bekommt/sieht/analysiert. wissen, was das soll? Sowas ist kein sauberes Programmieren. Sauberer wäre es, keyproc die "Taste" im DATARAM mitzugeben. Weiter:
1 | systemint: |
2 | ... |
3 | sec ;Entprellung Key1 (PB6) |
4 | sbis PINB,6 |
5 | clc |
6 | rcall keyproc |
Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc aufgerufen wird. Weiter:
1 | keyproc: |
2 | ... |
3 | ldd XL,Z+0 ;8x alle 5ms testen |
4 | rol XL ;= 200% Bulletproof ;-) |
5 | std Z+0,XL |
Das LDD/STD speicher/lädt den Wert KEYxS aus DATARAM. Das ROL schiebt das Carryflag (von der Taste) von rechts rein. Ergebnis: (bleibt) Null, wenn Taste nicht betätigt. Sonst: 0,1,3,7,15,31,63,127,255,255,255,255 bis wieder losgelassen. Weiter:
1 | keyproc: |
2 | ... |
3 | breq keyproc2 |
Wird aufgerufen, wenn obiger Zähler Null ist. Also wenn acht Samples hinternander die Taste nicht gedrückt ist. ...
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller > Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen > Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur > und seinen verbastelten Compiler herumgeärgert hatten. Der 8051 hatte noch viele andere geniale Befehle, CJNE, MOVC A,@A+DPTR, JMP @A+DTPR hab ich sehr oft benötigt. Und Bitlogik ging auch sehr einfach mit MOV C,bit, ORL C,(/)bit, MOV bit,C, CPL bit, JBC usw. Ich fands genial, was der Herr Keil da geleistet hat. Meine Assemblerprogramme waren durchweg länger, als später in C geschrieben. Und das Funktionen per default nicht reentrant waren, hat kaum gestört. Die Idee mit dem SRAM-Overlay hätte man nie in Assembler umsetzen können, das kann nur ein Compiler.
Matthias L. schrieb: > Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc > aufgerufen wird. Weiter: > keyproc: > ... > ldd XL,Z+0 ;8x alle 5ms testen > rol XL ;= 200% Bulletproof ;-) > std Z+0,XL Du hättest statt der "..." die entsprechenden Befehle vollständig hinschreiben sollen:
1 | keyproc: adiw ZH:ZL,2 ;Tastenstatus entprellend ermitteln |
2 | in YH,GPIOR0 |
3 | mov YL,YH |
4 | ldd XL,Z+0 ;8x alle 5ms testen |
5 | rol XL ;= 200% Bulletproof ;-) |
Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt, im konkreten Fall mit 0. Somit schiebt ROL in das XL-Register nur Nullen hinein, was den nett gemeinten Programmiertrick völlig versagen lässt. Wir wissen zwar nicht, was Mobys Programm tun soll (er verrät es uns ja nicht), eins kann aber sicher gesagt werden: Es entprellt keine Tasten. Und was lernen wir daraus? 1. Das Carry-Flag ist eigentlich gedacht für das Zusammensetzen von Multibyte- aus mehreren Einzelbytebefehlen (Addition, Shift usw.) und für Vergleiche mit anschließenden bedingten Sprüngen. Dabei wird das Flag in einem Befehl geändert und im direkt darauffolgenden Befehl ausgewertet. Es ist nicht gedacht für den Transport von booleschen Informationen über weite Strecken innerhalb des Programms. Wenn man das trotzdem tut, muss man sehr vorsichtig sein, damit man nicht versehentlich einen Befehl dazwischen einfügt, der das Flag überschreibt. => Wenn man schon Assembler programmiert und dabei auzch noch tief in die Trickkiste greift, sollte man gut ausgeschlafen sein und jede Code-Änderung dreimal mit dem Auge durchgehen und zusätzlich intensiv testen. 2. Ich vermute, Moby hat aus seinem Fundus eine ältere keyproc-Routine übernommen, die zunächst nur für eine einzelne Taste vorgesehen war. Er hat sie auf mehrere Tasten erweitert, musste dazu aber die indirekte Adressierung für das Z-Register und damit verbunden den ADIW-Befehl einführen, was schließlich zu dem Fehler führte. => Wiederverwendbarkeit von Code erfordert eine genaue und vollständige Dokumentation nicht nur der Funktion, sondern auch der Nebeneffekte. Das ist hier offensichtlich nicht geschehen. Da Moby der Assembler-Gott ist, der immer alles richtig macht, hat er auch keinen Bedarf gesehen, die Routine vor ihrer Veröffentlichung wenigstens einmal zu testen ;-) 3. Hochsprachen sind weniger anfällig gegen solche Fehler, da dort Information ausschließlich über Variablen transportiert wird. Wenn eine Variable an einem Punkt geschrieben wird und etliche Anweisungen später wieder gelesen wird, fällt es normalerweise auf, wenn dazwischen eine weitere Zuweisung an die Variable erfolgt. Ausnahme: Die Variable ist global und wird als Nebeneffekt eines Unterprogrammaufrufs überschrieben. Dann ist der Fehler ähnlich schwer zu erkennen wie in Mobys Fall. Das ist aber auch der Grund, warum globale Variablen (vor allem Schreibzugriffe auf dieselben) vermieden werden sollten. Aber selbst diese Fehlerursache lässt sich aus der Welt schaffen, indem man auf der Programmierprachenleiter noch eine Stufe höher steigt (ich sehe schon Mobys entsetzten Gesichtsausdruck vor mir) und eine Funktionalsprache verwendet. Damit gehören solche Fehler (und viele andere auch) endgültig der Vergangenheit an.
Jetzt sind meine Feststellungen ja hier immer noch Thema. Hatte Mod Yalu nicht angemahnt: > Und bevor wir hier weiterdiskutieren und immer mehr vom Usprungsthema > abkommen: > Moby, fang doch bitte einen neuen Thread an. Dann beschwert auch keiner > darüber, dass du den Thread kaperst. Hatte Mod Lothar M. nicht beklagt: > Dass ihm Andere seinen Thread > entführen und verunstalten gehört nicht zum guten Umgangston. Nun erklärte ich mich bereit, dem TO Horst S. wieder das Feld zu überlassen. Was vom TO folgt ist nun aber nur noch > möchte ich mich abschließend ... bedanken. Ja was jetzt? Was willst Du eigentlich? Deine Antworten hast Du also bekommen. Darf nun darüber hinaus nicht mehr diskutiert werden? Mußtest Du diesen Kübel Unrat weiter oben über mich ausgießen? Ich frage mich schon sehr, welche Höflichkeit das nun meinerseits noch wert sein soll... Ich werde sobald möglich noch auf einige in der Zwischenzeit aufgelaufenen Beiträge eingehen. Ein extra Thread dafür ist Blödsinn, weil man sich nicht mehr sinnvoll auf vorhergehende Beiträge beziehen kann. Danke an alle, die sich konstruktiv mit meinen Sourcen auseinandergesetzt haben. Ich hoffe daß ich auch noch was draus lernen kann.
>Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt Das hatte ich sogar noch übersehen. >Es ist nicht gedacht für den Transport von booleschen Informationen >über weite Strecken innerhalb des Programms Dafür würde das SREG das T-Flag bieten. Dieses kann frei verwendet werden und wird nicht bei arithmetischen Ops geändert. Sprungbefehle dafür gibt es aber genauso.
Peter D. schrieb: > Moby A. schrieb: >> Zeigt mal, wie >> sich die Funktionalität in höchstens gleicher C -Codegröße umsetzen >> lässt. Das würde ja auf mich viel eher Eindruck machen ;-) > > Welche Funktionalität denn? > Nirgends wird beschrieben, was der Code überhaupt machen soll! > > Die paar wenigen Zeilenkommentare kannst Du Dir an die Backe schmieren, > die sagen 0,nix über die Gesamtfunktion aus. Peter, hast du immer noch nicht verstanden, dass Mobys Code qua Definition selbsterklärend ist? > Nirgends wird beschrieben, was der Code überhaupt machen soll! Ich bezieht mich hier mal auf den Code für den LM335: Mal unabhängig davon, was dieser Asm- oder C- oder In-was-für-einer-Sprache-auch-Immer-Code genau tut, wäre interessant zu wissem, wie der Code einzusetzen ist. Für jeden erzeugten ADC-Wert wird über 64 Werte gemittelt. Warum? Erhöht das die Genauigkeit? Was ist die maximale Aufruffrequenz für die Funktion? Intention ist wohl, die adu-Funktion über eine ADC-ISR aufzurufen, und der ADC liefert beständig neue Werte / IRQs per ADATE (ADC Auto Trigger Enable). Problem: Die adu-Funktion fummelt an der ADC-Konfiguration rum: o Nach Ändern des Input-MUX dauert es recht lange (*), bis wieder brauchbare ADC-Werte verfügbar sind. Die ersten ADC-Werte sind Schrott. o Vermutlich wurde die Mittelung eingeführt, weil sich damit genauere Ergebnisse erzielen lassen; die Mittelung maskiert also nur das MUX-Problem ohne es zu benennen oder zu lösen. Eine Lösung wäre z.B. den 63. ADC-Wert in den 0. zu kopieren. (Falls die MUX-Zeit nicht größer als 2 Wandlungen ist, in welchem Falle noch mehr Werte zu kopieren wären...) o Vermutlich gilt ähnliches für Rumfummeln an REFSx, also Auswahl der Referenzspannung. (*) Seinerzeit hab ich ebenfalls versucht über Zeitscheiben ein quasi-paralleles Einlesen mehrerer ADC MUX-Inputs umzusetzen. Ergebnis: Schrott. Das Datenblatt (ATmega8 oder ATmegax IIRC) gab die Info nicht her, und erst eine Anfrage beim Hersteller ergab Klarheit: Die nach einer MUX-Umschaltung benötigte Zeit ist so hoch, dass ich den Ansatz verwarf und schließlich eine komplett andere Lösung wählte. Irgendwie kann ich mich des Eindrucks nicht erwehren, dass hier eine nerdig-neurotische Fixierung darauf, das letzte Byte aus einer Implementierung zu quetschen, den Blick auf die reale Anwendbarkeit des Codes und deren Einschränkungen verstellt. Natürlich liegt es in der Verantwortung des Anwenders, der Mobys Code anwendet, seine Hardware adäquat zu initialisieren. Jedoch erwähnt Moby in seinem Code diese MUX-Fußangel an keiner Stelle. Da er sich ihrer offenbar nicht bewusst ist, würd ich darauf tippen, dass sein LM335-Code nicht getestet ist — zumindest nicht so, dass man ihn guten Gewissens in einem öffentlichen Forum weitergeben möchte... Natürlich macht der Code Byte für Byte was sein Autor will — inwieweit das überhaupt sinnvoll ist oder Mumputz, steht auf einem anderen Blatt; inzwischen vielleicht sogar im Datenblatt.
:
Bearbeitet durch User
Moby schrieb: > Asm allein ist nun > leider keine Garantie für guten Code, wie man beim TO-Programm schön > sehen kann ;-) Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru, aber einfach abfrühstücken lasse ich mich auch nicht von Dir. Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung.
> Der 8051 wurde ein einer Zeit entwickelt, in der man solche Aufgaben nicht in C gelöst hat, sondern meist in Assembler. Wikipedia: PLM compilers have been made for 8008, 8080, 8085, 8051, 8052, 8096. 80196, 8086, 80186, 286 and 386. Nun ist PLM von der Syntax her kein C, aber sonst C ähnlicher als Assembler. Und wenn man 8008 liest, offenbar ein Zeitgenosse von frühem C anfang der 70er. Von Intel (und seinen Kunden) wurde mit PLM alles gelöst was ging. Ich erinnere mich an eine digitale Regelung um die 4 Farbwerke einer großen Druckmaschine zu synchronisieren (damit die Farben richtig übereinander kommen). Das hatte eine Schweizer Firma 1982 (da war ich Werkstudent in der Druckerei) mit einem 8085-Board in PLM80 gemacht. Auch das 8085-Entwicklungssystem hatte ein OS (ISIS II) in PLM80 geschrieben. Das Konkurrenzprodukt CP/M bestand in Teilen auch aus PLM-Code. (grad gesehen: es gibt die CP/M Sourcen in Netz, dabei auch die F66-Source des Intel PLM80 Compilers. Er soll mit Gnu-FORTRAN übersetzbar sein)(das ist fast wie Oldtimerhefte durchblättern 8-)) Einziger Nachteil an dem Zeug damals: Intel lies es sich vergolden. Und heute haben wir den avr-gcc. 0€, satte Gegenleistung. Ich bekenne: alles Off-Topic, aber das hat in diesem Thread ja Tradition ;-)
:
Bearbeitet durch User
Johann L. schrieb: > (*) Seinerzeit hab ich ebenfalls versucht über Zeitscheiben ein > quasi-paralleles Einlesen mehrerer ADC MUX-Inputs umzusetzen. Ergebnis: > Schrott. Kann ich nicht bestätigen. Ich benutze immer den MUX und habe keinerlei Übersprechen der anderen Eingänge oder falsche Messungen. Z.B. wenn ich 6 Eingänge messen will, lege ich ein Array für die 6 Ergebnisse an. Ein Timerinterrupt liest dann die vorherige Messung ins Array, startet die Messung und schaltet den MUX weiter. Das Main nimmt sich dann den benötigten Wert, ohne auf den ADC warten zu müssen. Nur wenn man die interne Referenz messen will, muß man etwa 8 Meßwerte wegschmeißen, ehe der Wert stimmt. Vermutlich ist da ein hochohmiger Widerstand drin und der Sample-Kondensator braucht dadurch lange zum Umladen. http://www.avrfreaks.net/comment/493872#comment-493872
:
Bearbeitet durch User
>Das hatte eine Schweizer Firma
Ferag AG?
Bobster, oder so. Das ist über 30 Jahre her!
Horst S. schrieb: > Moby schrieb: >> Asm allein ist nun >> leider keine Garantie für guten Code, wie man beim TO-Programm schön >> sehen kann ;-) > > Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent Beispiel:
1 | //Transmitter/Receiver enabled/interrupt enabled |
2 | ldi d0, (1<<TXCIE0) + (1<<RXCIE0) + (1<<TXEN0) + (1<<RXEN0) |
3 | sts UCSR0B, d0 |
Bereis diese 3 Zeilen sind ein Albtraum der Unwartbarkeit und ab weibischer Weitschweifugkeit nicht zu überbieten! Der Kommentar ist überflüssig und lenkt vom Wesentlichem ab, nämlich dem Code. Er verwirrt den Leser, ist redundant und verschwendet wertvolle Bytes in deinem Rechner, auf deiner Festplatte, und in unser aller Birnen! Die nächste Zeile verwändet abermals die Anti-Pattern Byteverschwendung und Zeitverschwendung durch dein Assembler-Programm: Die << und | müssen aufwändigst von deinem Rechner errechnet werden — ein Glück, dass der Assembler, den du verwendest, von erfahrenen Assembler-Experten hochoptimiert programmiert wurde. Nur so ist es möglich, dass es nich Minuten oder gar STunden dauert, bis dein Projekt übersetzt ist! Aber ich schweife ab... "d0" ist ein sehr guten Ansatz, denn es spart 8 wertvolle Bits gegenüber einem "R16" — und das sogar 2× !. Dennoch: Solche symbolischen Namen sind die totale Verfehlung und zeigen die Degeneriertheit deiner Gedankenwelt, ausgelöst durch wiederholten Lesens von Hochsprachen-Code und Kontakt mit Individuen, welche solche Widerlichkeiten ernsthaft in Betracht ziehen oder gar ausüben! Hie noch die selbsterklärende, ultimative Asm-Lösung, die keine Fragen offen lässt!
1 | LDI R16, $db |
2 | STS 132, R16 |
Alles andere ist kindischer Schnickschnack! p.s. ich hab noch eine kürzere Lösung gefunden, die weitere wertvolle Bytes spart!
1 | .word $affe |
2 | .word $dead |
:
Bearbeitet durch User
>Das hatte eine Schweizer Firma
Ferag AG?
Gerade mal Google befragt:
Bobst, machen heute in Verpackungsmaschinen und nicht mehr in
Druckmaschinenausrüstung.
Verdammt, wo soll ich denn dann mit meinen 8GB Ram und 1,3MHz hin? Nur Fickelfilme gucken?
Horst S. schrieb: > Verdammt, wo soll ich denn dann mit meinen 8GB Ram und 1,3MHz hin? Nur > Fickelfilme gucken? Musst die Kiste in Assembler programmieren. Andernfalls ist sie (bei 1,3GHz jedenfalls) für normale Anwendungen viel zu schnell. Nur in Assembler wird es dir gelingen, sie auf vernünftiges Mass zu drosseln. ;-) Aus dem gesparten RAM machst du dann eine RAM Disk. Fürs Swapfile.
:
Bearbeitet durch User
8Gb-RAM und nur 1,3MHz, da kann booten von Windows etwas dauern ;-)
Johann L. schrieb: > Hie noch die selbsterklärende, ultimative Asm-Lösung, die keine Fragen > offen lässt! > LDI R16, $db > STS 132, R16 Das R16 könnte man noch durch die Adresse ersetzen...
Carl D. schrieb: > 8Gb-RAM und nur 1,3MHz, da kann booten von Windows etwas dauern > ;-) Ich boote nicht, ich standbye. (Is'n Notebook.)
Peter D. schrieb: > Johann L. schrieb: >> (*) Seinerzeit hab ich ebenfalls versucht über Zeitscheiben ein >> quasi-paralleles Einlesen mehrerer ADC MUX-Inputs umzusetzen. Ergebnis: >> Schrott. > > Kann ich nicht bestätigen. Ich benutze immer den MUX und habe keinerlei > Übersprechen der anderen Eingänge oder falsche Messungen. > Z.B. wenn ich 6 Eingänge messen will, lege ich ein Array für die 6 > Ergebnisse an. Ein Timerinterrupt liest dann die vorherige Messung ins > Array, startet die Messung und schaltet den MUX weiter. > Das Main nimmt sich dann den benötigten Wert, ohne auf den ADC warten zu > müssen. > > Nur wenn man die interne Referenz messen will, muß man etwa 8 Meßwerte > wegschmeißen, ehe der Wert stimmt. Vermutlich ist da ein hochohmiger > Widerstand drin und der Sample-Kondensator braucht dadurch lange zum > Umladen. > http://www.avrfreaks.net/comment/493872#comment-493872 Ich hab nur noch meine Antwort an den Atmel-Support gefunden, aus der eine Zeit von 125µs hervorgeht:
1 | The device is an ATmega8. However, I assumed that all AVRs are |
2 | equiped with the same input MUX, i.e. you do not taylor input |
3 | MUXs for every AVR derivative. |
4 | |
5 | The ATmega8 manual does not mention these 125µs. |
6 | |
7 | 125µs are *very* long. I would expect transition times in the |
8 | range of ns after a channel selection like in stand alone |
9 | analogue switches / multiplexers. |
Den Datasheets von z.B. ATmega32 und ATtiny26 zufolge betrifft das nur den differentiellen Modus, und den hat nicht jeder AVR. Der ATmega8 hat ihn nicht und da steht es folgerichtig auch nicht drin. "Special care should be taken when changing differential channels. Once a differential channel has been selected, the gain stage may take as much as 125µs to stabilize to the new value. Thus conversions should not be started within the first 125µs after selecting a new differential channel. Alternatively, conversion results obtained within this period should be discarded. The same settling time should be observed for the first differential conversion after changing ADC reference (by changing the REFS1:0 bits in ADMUX)."
:
Bearbeitet durch User
Jörg W. schrieb: > allein von Johanns Ausführungen über das, was er (*) da so im > Compiler treibt, kann man hinreichend viel auch als gestandener > Programmierer noch lernen. ;-) > > (*) Johann ist derjenige, der in den letzten Jahren am AVR-Backend > des GCC massiv herumoptimiert hat. Davor war er zwar auch schon > brauchbar, aber eben manchmal recht suboptimal (vermutlich eher > das, was Moby sich unter einem Compiler vorstellen würde). Ja, ein Compiler arbeitet bestimmt nicht so, wie sich Lieschen Müller das ausmalt. Aber in einem muss ich Moby recht geben: Der erzeugte Code ist nicht optimal. Das Verbesserungspotential würd ich mit 10% oder mehr ansetzen. Aber andererseits ist auch die frage, die weit ein Assemblerprogrammierer vom Optimum (das wir i.d.R nicht kennen) entfernt ist, insbesondere auch wie weit er davon entfernt bleiben will weil er seinen Code nicht kaputt-optimieren mag. Bei Mobys Code könnte man z.B. einiges an Zeit sparen wenn — wie schon erwähnt — auf die Schiebeschleife verzichtet würde und zudem die Funktion inline in der ISR wäre. Dass der Code selbst ein paar Ticks mehr braucht ist dabei garnicht das Problem, aber bei AVRs sind ISRs in der Regel blockierend, und die Latenzzeiten aller anderen ISRs werden höher. > Dank Johanns Engagement hat er aber nochmal massiv zugelegt, Leider geht teilweise viel Zeit drauf, manchen Atmel-Änderungen wie dem Specs-Zeug hinterher zu wischeln. Allein das hat mich mehrere Tage AVR-Zeit gekostet, was in Real Time dann locker Wochen bis Monate sind :-( A. K. schrieb: > Den Datasheets von z.B. ATmega32 und ATtiny26 zufolge betrifft das nur > den differentiellen Modus, und den hat nicht jeder AVR. Der ATmega8 hat > ihn nicht und da steht es folgerichtig auch nicht drin. Ja, es stand / steht nicht im Datenblatt, und es war für ein Device ohne differentiellen Modus. Wenn ich's richtig verstand wurde vom 2nd-LevelSupport nachgemessen, und ich musste einige Tage warten bis die das Ergebnis hatten. Die genaue ADC-Config des ATmega8 hab ich allerdings nicht mehr, eingestampft wie gesagt.
Na da hat sich ja einiges getan, seit ich in diesen Thread das letzte mal reingeschaut habe. Ja, genau so etwas hab ich schon erwartet. Das ist oft der Normalfall, auch in den Programmierforen. Die ärgesten Assembler-Verfechter glänzen da bei Assembler Fragen meistens mit Abwesenheit. Aber das das rückzugsgefechtartige Gestammel von Moby so deutlich ausfallen würde, das hab ich dann doch nicht erwartet. Besonders schön natürlich das Bonmont mit der fehlerhaften Adressierung im BST in der ominösen ADC Routine. Moby, was machst du eigentlich, wenn ich eine andere Verteilung der Referenzspannungen haben will, oder mehr Kanäle, oder nicht 64 Samples sondern weniger? Oder gar, Gott bewahre, mehr? Dann platzt deine ach so tolle handoptimierte Bitpfriemelei wie eine Seifenblase und die Arbeit geht von vorne los. Das alles sind Dinge, die mir in C nur ein Schulterzucken kosten. Einen Zahlenwert ändern und soll sich doch der Compiler was überlegen, wie er das anständig umsetzt. Und sorry. Ich weiss ja nicht, was du für Programme schreibst. Aber die Welt hört beileibe nicht bei 8 Bit Arithmetik auf. Ein bisschen rechnen ist ausserdem keineswegs so selten, wie du das hinstellst. Ganz im Gegenteil: ein paar Werte in ein paar Register schreiben, das ist der eigentlich geringfügigere Teil in einem Programm. Das kann man gut in Assembler machen. Allerdings: Das kriegt der Compiler genau so gut hin. Und wie man gesehen hat, ist der Schwellwert an Komplexität, den du noch überblicken kannst, so gross dann auch wieder nicht. Ich gebe gerne zu, dass ich den 32 Bit Vergleich nicht so elegant hingekriegt hätte. Muss ich auch nicht. Bei mir macht das der Compiler. Mich interessiert es schlicht und ergreifend nicht besonders wie er das macht. Ich kümmere mich lieber darum, welche Bedeutung dieser Vergleich im Kontext meines Programmes hat, warum er da stehen muss, ob es ein kleiner oder doch ein größer sein muss. Die Details der Umsetzung - die macht der Compiler für mich. Und wenn er da ein paar Takte zuviel reinhaut stört das in mehr als 95% aller Fälle nicht die Bohne. Dafür, und diesen Seitenhieb kann ich mir nicht verkneifen, macht der das zum Ausgleich korrekt und braucht nicht anderthalb Stunden dafür. Ich hab mit meiner Zeit wirklich was besseres zu tun, als mich mit Routine-Angelegenheiten rumzuschlagen. So interessant sind die auch wieder nicht. Aber ein ausgefuchster Algorithmus, der kann mich dann auch schon ein paar Stunden oder Tage beschäftigen. Nur - so weit kommst du gar nicht, weil du ihn gar nicht wegen des Umfangs im absehbarer Zeit implementieren kannst. Oder - was noch viel wichtiger ist - du kannst gar nicht Varianten davon genauer studieren, weil du viel zu sehr damit beschäftigt bist, warum das Carry Flag schon wieder mal an einer Stelle nicht den Wert hat, den es haben sollte (jetzt nur mal so zum Beispiel). Kurz und gut: du musst dich auf einer Ebene mit Problemen rumschlagen, die nichts mit der eigentlichen Aufgabenstellung zu tun haben. Die eigentliche Aufgabenstellung mag lauten, anhand einer Uhrzeit ein Temperaturprofil mit einem PID Regler abzufahren. Ob du dabei den X-Pointer oder doch den Z-Pointer zur Indizierung in die Temperaturtabelle benutzt ist dabei völlig nebensächlich. Du musst auch mal in etwas größeren Dimensionen denken als nur "Wenn Taster dann Licht an".
:
Bearbeitet durch User
Karl H. schrieb: > rückzugsgefechtartige Gestammel von Moby Na na nicht so vorschnell. Es soll doch da tatsächlich noch andere Dinge im Leben geben als hier permanent präsent zu sein. Oder etwa nicht? Karl H. schrieb: > Besonders schön natürlich das > Bonmont mit der fehlerhaften Adressierung im BST in der ominösen ADC > Routine. Wir werden doch nun einen Flüchtigkeitsfehler nicht so hoch aufhängen! Daß es hier im Forum unentschuldbar ist, einen Quelltext mit einem solchen zu veröffentlichen, ok, daß muß und werde ich zukünftig berücksichtigen. Karl H. schrieb: > Moby, was machst du eigentlich, wenn ich eine andere Verteilung > der Referenzspannungen haben will, oder mehr Kanäle, oder nicht 64 > Samples sondern weniger? Oder gar, Gott bewahre, mehr? Dann platzt deine > ach so tolle handoptimierte Bitpfriemelei wie eine Seifenblase und die > Arbeit geht von vorne los. Da platzt gar nichts. Oder ist eine entsprechende Umformulierung nun gleich High-Tech? Nein, es ist Kiki. Wenngleich flüchtigkeitsfehleranfällig und damit hier nicht sofort veröffentlichungswürdig. Aber was man schließlich hat das hat man...
Moby A. schrieb: > Da platzt gar nichts. Oder ist eine entsprechende Umformulierung nun > gleich High-Tech? Nein, es ist Kiki. Na Moby... wieder ganz der Alte? ;-(
Karl H. schrieb: > rückzugsgefechtartige Gestammel Da mokieren sich die einen Mods über vaterlandsgefährdende Threadübernahme, die anderen über Rückzug. Da werden beleidigende Kommentare von Forumsteilnehmern kritisiert- und Mods schlagen in die gleiche Kerbe. Diese Forummodlogik für in sich konsistent zu halten würde ich Gestammel nennen... Aber so sind sie, die Menschen. Einer wie der andere. Karl H. schrieb: > Aber die > Welt hört beileibe nicht bei 8 Bit Arithmetik auf. Sicher nicht. Das für Asm wie für 8-Bit AVR nachteilige Thema hatten wir schon. Eine große Klasse von Steuerungs-Anwendungen kommt da ohne aufwendiges 32 Bit aus. Sensoreinlesen, verarbeiten und verschiedene Ausgaben veranlassen (z.B. an seriell angebundene Aktoren/Webinterfaces) haben größere Berechnungen selten am Bein. > Allerdings: Das kriegt der Compiler genau so gut hin. Berechnungen? Sicher doch. Das ist dann aber nur ein Aspekt von vielen und ich erspare mir an dieser Stelle weitere Wiederholungen zu den Vorteilen von Asm. > Mich interessiert es > schlicht und ergreifend nicht besonders wie er das macht. Was man in Asm hat das hat man. Über die Jahre begeisterten Asm-Programmierens kann das eine ganze Menge werden. > braucht nicht anderthalb Stunden dafür. Ja es ist wirklich interessant was sich aus den Zeitdaten veröffentlichter Beiträge so alles ableiten lässt ;-) > ausgefuchster > Algorithmus, der kann mich dann auch schon ein paar Stunden oder Tage > beschäftigen. Nur - so weit kommst du gar nicht, weil du ihn gar nicht > wegen fehlender Notwendigkeit eines solchen ;-) > weil du viel zu sehr damit beschäftigt bist, warum das Carry > Flag schon wieder mal an einer Stelle nicht den Wert hat, den es haben > sollte C-Programmierer haben da andere, gewichtigere Probleme: Den ganzen Zirkus von C-Konstruktionen mitsamt komplexer Ausdrücke und Compileroptionen unter Kontrolle zu behalten... Was ist denn da ein Carry Flag ;-) > in etwas größeren Dimensionen denken > als nur "Wenn Taster dann Licht an". Das Zusammenwirken vieler Sensoren und Aktoren verknüpft über drahtlose Netze stellt durchaus ein paar Anforderungen. Nur eben weniger an Berechnungen.
Ich verweise auf die Universalantworten, auch zu diesem Thema Beitrag "Re: 8bit-Computing mit FPGA" Beitrag "Re: 8bit-Computing mit FPGA" 'Nuff said
Johann L. schrieb: > Das Verbesserungspotential würd ich mit 10% oder mehr ansetzen. Meine Rede. Insbesondere bei kurzen Programmen sind die Chancen dieses Potential zur Geltung zu bekommen hoch. > Aber > andererseits ist auch die frage, die weit ein Assemblerprogrammierer vom > Optimum (das wir i.d.R nicht kennen) entfernt ist, insbesondere auch wie > weit er davon entfernt bleiben will weil er seinen Code nicht > kaputt-optimieren mag. Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich interessiert allein die effiziente,simple Lösung und kein 32bittiges Herumprotzen mit Ressourcen und Vernichtung derer mit Hochsprachen.
Falk B. schrieb: > Ich verweise auf die Universalantworten, auch zu diesem Thema Ja Falk, verweise ruhig was das Zeug hält ;-) Mein Anspruch ist nun aber die praktikable Lösung-und wenn ich mich in der Bude so umschaue- sorry Falk, dann kann ich nicht anders als mich darin total bestätigt zu fühlen ;-) Der Spaß an der Sache ist allerdings auch nicht zu unterschätzen!
Falk B. schrieb: > Ich verweise auf die Universalantworten, Hmm..., jaa..., neee... Da muss es noch was anderes geben. Moby A. schrieb: > Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich > interessiert allein die effiziente,simple Lösung und kein 32bittiges > Herumprotzen mit Ressourcen und Vernichtung derer mit Hochsprachen. Das kommt mir wie 'ne Politikerrede vor. Beeindruckende Wortwahl und nichts dahinter.
Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. Klar: nur dort. Schon bei mittleren nämlich nicht mehr. Schließlich ist auch dein Leben endlich … Was du generell unterschätzt: die, gegen die du hier ankämpfst, sind fast durchweg Leute, die eine solche Sturm-und-Drang-Phase, die du da gerade hast, schon vor ein oder zwei (oder drei) Jahrzehnten durchlaufen haben. Es sind alles Leute, die teilweise wohl viel besser als du wissen, wie ein Assembler funktioniert (und der vom AVR Studio ist in dieser Hinsicht ohnehin nur eine Krücke auf eher unterem Niveau), die teilweise Assembler-Pamphlets von mehreren Dutzend Seiten fabriziert und zumindest zur geplanten Funktion bekommen haben. Im Gegensatz zu dir wissen sie jedoch aus gerade dieser Erfahrung, dass es um die dabei verschwendete Lebenszeit schade war, wenn stattdessen eine Maschine einen durchaus vergleichbar guten Job mittlerweile innerhalb von ein paar Sekunden hinlegt. Moby A. schrieb: > Da werden beleidigende Kommentare von Forumsteilnehmern Nur mal so, weil du das immer wieder anbringst: geh' mal zum Staatsanwalt deines geringsten Misstrauens und befrage ihn, was er als „Beleidigung“ ansieht. Du wirst dich ziemlich wundern, wie hoch die Schwelle dafür liegt. Ein paar flapsige Kommentare eines Forenteilnehmers, dessen Thread du letztlich mit deiner dir üblichen Penetranz gekapert hast (ohne ihm damit auch nur im geringsten zu helfen), fallen da ganz gewiss nicht drunter.
Jörg W. schrieb: > Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. > > Klar: nur dort. Schon bei mittleren nämlich nicht mehr. Schließlich > ist auch dein Leben endlich … Bei mittleren muß man systematischer rangehen. Funktionalität als unabhängiges Modul formulieren das sich von weiteren Nebenabhängigkeiten befreit zum Beispiel flexibel in einem Timerinterrupt aufrufen lässt. So wie die beiden (ADU+Tastenentprell) Beispiele. > Was du generell unterschätzt: die, gegen die du hier ankämpfst, sind > fast durchweg Leute, die eine solche Sturm-und-Drang-Phase, die du da > gerade hast, schon vor ein oder zwei (oder drei) Jahrzehnten durchlaufen > haben. Es sind alles Leute, die teilweise wohl viel besser als du > wissen, wie ein Assembler funktioniert (und der vom AVR Studio ist in > dieser Hinsicht ohnehin nur eine Krücke auf eher unterem Niveau), die > teilweise Assembler-Pamphlets von mehreren Dutzend Seiten fabriziert und > zumindest zur geplanten Funktion bekommen haben. Im Gegensatz zu dir > wissen sie jedoch aus gerade dieser Erfahrung, dass es um die dabei > verschwendete Lebenszeit schade war, wenn stattdessen eine Maschine > einen durchaus vergleichbar guten Job mittlerweile innerhalb von ein > paar Sekunden hinlegt. Ich möchte gegen niemand ankämpfen. Schon gar nicht jemand, der aus vielerlei Gründen (beruflich) Lösungen in Hochsprache undoder 32-bittig umzusetzen hat. Wenn die gleichen Leute dies aber in einer Form verallgemeinern, die Asm und AVR generell in Frage stellen wiederspreche ich vehement. > Nur mal so, weil du das immer wieder anbringst: geh' mal zum > Staatsanwalt deines geringsten Misstrauens und befrage ihn, was er als > „Beleidigung“ ansieht. Da darf ich Dich beruhigen- sooo wichtig ist mir dann das Forum als solches nicht ;-)
:
Bearbeitet durch User
Moby A. schrieb: > umzusetzen hat Du siehst das immer noch durch die falsche Brille: wir müssen das nicht so machen, sondern machen das alle völlig freiwillig so. Weil wir wissen, dass es auf den von dir beschworenen (und dann ja oft doch nichtmal wirklich erreichten) letzten Taktzyklus sowieso nur in 0,001 % der Fälle ankommt. Das vorletzte Mal, dass ich das hatte, war die Diskettenzugriffsroutine meines CP/M-BIOS vor reichlich 25 Jahren. Eine Vierfach-Schleife um die innere Schleife herum (die je 256 Byte einlas) hätte nicht funktioniert, also habe ich sie per Makro im Assembler wirklich viermal eingefügt. (Dummerweise können natürlich auch Compiler sowas, das nennt sich dann loop unrolling, und das machen sie, wenn man sie drängt, auf Geschwindigkeit zu optimieren.)
:
Bearbeitet durch Moderator
A. K. schrieb: > Also gut, dann eben zerstörungsfrei:void g(long); > void f(long x) > { > if (x < 1000000) > g(x); > } > > Ergebnis vom Compiler: > cpi r22,64 > ldi r18,66 > cpc r23,r18 > ldi r18,15 > cpc r24,r18 > cpc r25,__zero_reg__ > brge .L1 Schön. Interessant. Dankeschön. Bei den Takten kommen wir aber auch auf 7...8. Und das wird noch mehr wenn x>16777215.
Wie wärs Moby, könntest du deine Variante noch auf 32 Bits mit Vorzeichen ausdehnen?
Moby A. schrieb: > Und das wird noch mehr wenn x>16777215. Du meintest eventuell 'wenn x mit einer Konstanten größer 16777215' verglichen wird? Da schreibt man die Konstante hin und zack!, hat der Compiler den entsprechenden Code gezaubert.
Jörg W. schrieb: > Du siehst das immer noch durch die falsche Brille: wir müssen das nicht > so machen, sondern machen das alle völlig freiwillig so. Dann bitte auch gern freiwillig. Warum auch nicht? Ich bin doch nicht so verrückt anzunehmen, jeder C-Programmierer sei auf dem Holzweg. Entscheidend ist was hinten rauskommt. Da sehe ich den Asm-Programmierer bei typischen 8-Bit Projekten auf 8-Bit Controllern aber im Vorteil. Erreichbare Performance/Codesize sind auch nur zwei technische Aspekte. Mir fast noch wichtiger sind übersichtliche Programmstruktur (bei sinnvoller Funktionskommentierung) wie überhaupt der Bruchteil notwendiger sprachlicher Mittel, um ans Ziel zu kommen. Direkt. Und daß der unmittelbare Kontakt zum Datenblatt nun wirklich nicht schadet sieht man weiter oben...
Wir sollten anfangen, die Argumente zu nummerieren. Spart Tipparbeit, weil man dann in der hiesigen schon heftig entrollten Argumentationsschleife nur noch die Nummern hinschreiben muss.
A. K. schrieb: > Wie wärs Moby, könntest du deine Variante noch auf 32 Bits mit > Vorzeichen ausdehnen? Nö. Brauch ich nicht. Wozu? Um hier irgendwas zu beweisen? Ist das fertig kommst Du mit dem nächsten um die Ecke ;-) Versuch Du doch umgekehrt mal gegebene Asm-Texte mit C einzudampfen. Weitere Gelegenheiten werde ich noch liefern.
Moby A. schrieb: > Bei den Takten kommen wir aber auch auf 7...8. Und da gibts noch einen Nachteil. Die 7...8 Takte sind bei obiger Compiler-Lösung die Regel, bei meiner schon fast die Ausnahme ;-)
Horst S. schrieb: > Moby schrieb: > Asm allein ist nun > leider keine Garantie für guten Code, wie man beim TO-Programm schön > sehen kann ;-) > > Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so > vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne > großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru, > aber einfach abfrühstücken lasse ich mich auch nicht von Dir. > > Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung. Die Entschuldigung kannst Du Dir sparen. Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das jedenfalls nicht für Deinen Asm-Code. Die lange diesbezügliche Rumbastelei am C-Code im übrigen auch nicht für C.
Moby A. schrieb: > Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das > jedenfalls nicht für Deinen Asm-Code. Allerdings waren die alternativen (und besseren) C-Varianten, die Horst geholfen haben, schon nach wenigen Forums-CPU-Takten verfügbar. Eine alternative Assembler-Variante hast du ihm jedenfalls bis heute noch nicht angeboten. Damit bleiben all deine Argumente reine Theoretisiererei, die vielleicht deinem Ego hilft, aber sonst niemandem. A. K. schrieb: > Wir sollten anfangen, die Argumente zu nummerieren. So, wie die beiden Typen mit den Witzen. Gute Idee. :-)
Johann L. schrieb: > Peter D. schrieb: > Welche Funktionalität denn? > Nirgends wird beschrieben, was der Code überhaupt machen soll! > Die paar wenigen Zeilenkommentare kannst Du Dir an die Backe schmieren, > die sagen 0,nix über die Gesamtfunktion aus. > > Peter, hast du immer noch nicht verstanden, dass Mobys Code qua > Definition selbsterklärend ist? > > Nirgends wird beschrieben, was der Code überhaupt machen soll! > > Ich bezieht mich hier mal auf den Code für den LM335: Asm-Code ist selbsterklärend. Es braucht nämlich nur die Instruktionsbeschreibung und das Datenblatt sowie ein paar funktionserklärende Kommentare. Da es aber zu meiner Überraschung offensichtlich Fragen zum Einsatz und dem Wie&Warum gibt werde ich das in dem entsprechenden Projekte-Beitrag nochmal thematisieren.
Jörg W. schrieb: > deinem Ego hilft Das spielt die letzte Geige, sonst wär durchaus schon eine Menge meiner veröffentlichungsfähigen Entwicklungen in den Projekten. Wenn man das aber trotzdem verstärkt tun sollte dann weil ich natürlich gemerkt habe, daß es diesbezüglich hier einen gewissen Nachhol- bzw. Wissensbedarf gibt und die besten Argumente immer noch überzeugender Code liefert.
900ss D. schrieb: > Danke Moby, immerhin hast du deinen Code gepostet. Fazit: Auch > handgeschriebener ASM-Code ist nicht immer besser als der vom Compiler. Wiegesagt, das C-Ergebnis sollte dann aber erstmal wirklich gleichwertig sein was es so nicht ist. > Warum du Moby, so verbissen an ASM festhälst, wird mir auch ein Rätel > bleiben, die von Dir genannten Vorteile sind alle objektiv widerlegt Das sehe ich anders aber es mag sein, daß es noch ein paar überzeugenderer Beispiele bedarf ;-) > Neugier: Moby, ist programmieren eher aus Hobby betrieben oder verdienst > du dein Geld damit? Mobby Hobby.
:
Bearbeitet durch User
> Und daß der unmittelbare Kontakt zum Datenblatt nun wirklich nicht schadet sieht man weiter oben... Man glaubt zwar kaum, aber auch C-Programmierer dürfen DBs lesen. Und tun das auch. Und was finden sie da: Codefragment in ASM und C. Zum direkten Vergleichen. Ob C nun wirklich mehr oder weniger Schlüsselworte hat, als ein AVR Maschinenbefehle? Auf alle Fälle bringt es beim Anwenden einer Sprache Vorteile, wenn man nicht ständig in Vokabel- und Grammatikheft blättern muß. Ich benutze das DB für die Hardware. Die Sprache kann ich nämlich schon. Und andere (Computer aller Größenklassen) sprechen die auch. Das ist vielleicht der Unterschied zwischen (nur) Hobby und 30 Jahre sich selbst und 20 Jahre noch drei Andere mit Programmieren zu versorgen. Darf aber jeder selber entscheiden, wie er es machen will. JEDER, nicht nur Moby! Und damit verbietet sich die Missionstätigkeit spätesten dann, wenn alle Anderen sagen: "is gut jetzt". Schreibt ein sich fischiger Haßtiraden sicherer, aktuell sehr müder Geselle, der bis gerade für Brötchen in einer von wenigen gekannten, aber von vielen belächelten, auf einer in C und C++ geschriebenen VM ausgeführten Sprache geschrieben hat, deren Vor- und Nachteile er seit 25 Jahren kennt und sinnvoll einsetzt. Der kann sogar die Opcodes der VM im Debugger lesen und zum Glück gibt es für diese keinen Assembler, denn dann bleiben ihm zumindest in dem Umfeld fischige Diskussionen erspart. Mobby Hobby? Wohl eher Moby Hoby!
:
Bearbeitet durch User
Carl D. schrieb: > Auf alle Fälle bringt es beim > Vorteile, wenn man nicht ständig in Vokabel- und > Grammatikheft blättern muß. Ja, die Grammatik gilt es im Gegensatz zu Asm bei C ja noch zusätzlich zu beherrschen. > Und damit > verbietet sich die Missionstätigkeit spätesten dann, wenn alle Anderen > sagen: "is gut jetzt". Die würde sich für mich nur dann verbieten, wenn meine Erfahrungen mit Asm denn schlechte wären. Sind sie aber nicht! Das ist auch kein Wunder, weil Asm alle Voraussetzungen zum effizienten Programmieren mit allen erdenklichen Möglichkeiten, zu minimalem Aufwand bietet. > auf einer in C und C++ geschriebenen VM > ausgeführten Sprache geschrieben hat, deren Vor- und Nachteile er seit > 25 Jahren kennt und sinnvoll einsetzt. Der kann sogar die Opcodes der VM > zum Glück gibt es für diese keinen Assembler, denn > dann bleiben ihm zumindest in dem Umfeld fischige Diskussionen erspart. Warum werde ich bloß nicht müde zu betonen, für welche Zielplattform und für welche Anwendungen ich Asm vorn sehe? Warum fühlt sich jeder Profi bemüßigt, das sogleich auf sein Gebiet- bis hin zur PC Programmierung zu beziehen?
Wannkappierst du eigentlich, daß dein Ges.... keiner mehr hören kann. Soll ich dir ständig runterbeten, womit ich schon gute Erfahrungen gemacht hab? Spätestens nach der Erfahrung, daß andere es nicht mehr hören wollen, würde ich es für mich behalten und mich ganz allein an der glückseeligmachen Erkenntnis laben. Und schon garnicht würde ich einer solchen Gruppe von Ignoranten auch noch demonstrieren, wie rudimentär ich mein Spezialgebiet tatsächlich nur beherrsche. Aber vielleicht wollte ich deshalb auch nie Klassenkasper werden. Oder bekommst du Provision dafür, Threads ins OffTopic zu treiben?
Carl D. schrieb: > der bis gerade für Brötchen in einer von wenigen gekannten, > aber von vielen belächelten, auf einer in C und C++ geschriebenen VM > ausgeführten Sprache geschrieben hat Siehst Du. Viele belächeln diese. Nichtmal auf dem Level ein eindeutiges Urteil. Was sagt uns das? Zuvieles jenseits harter Fakten wird subjektiv erlebt und kann individuell durchaus verschieden bewertet werden. So erklärt sich dann wohl auch manche Vorliebe in der Diskussion C vs. Asm.
Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen > Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. Wenn jemand 18 Jahre lang in Assembler programmiert und damit seine ganze Haussteuerung umgesetzt hat, wird er doch wohl ein paar fehlerfreie Zeilen Quelltext vorweisen können?! > Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich > interessiert allein die effiziente,simple Lösung Die interessiert uns auch. Aber es sind ja Sie, welcher behauptet, die "effiziente,simple Lösung" zu haben. Belege dafür bleiben Sie schuldig, unterstellen den Anwesenden aber > 32bittiges Herumprotzen mit Ressourcen und Vernichtung derer mit > Hochsprachen. Das interessiert vermutlich die wenigsten hier -- weder die 32 Bit, noch das Herumprotzen, noch die Vernichtung von Ressourcen. Ich habe auch noch nie jemanden mit so etwas "herumprotzen" sehen. Sie etwa? Johann Lay, Jörg Wunsch und Peter Danegger, die sich an diesem Thread ja mehrmals beteiligt haben, "protzen" jedenfalls nicht mit 32-Bit oder der "Vernichtung von Ressourcen". Diese Leute könnten mit ihrem fehlerlosen Code "protzen", und trotzdem tut es keiner. Deren Code hat übrigens auch keine "Flüchtigkeitsfehler".
Carl D. schrieb: > Wannkappierst du eigentlich, daß dein Ges.... keiner mehr hören > kann. Du musst hier nichts lesen oder gar schreiben. Immerhin ist es Dir ja wert auf mich zu reagieren. Sogar so spät/so früh ;-) Was meinst Du was ich alles nicht mehr hören mag? > Provision dafür, Threads ins OffTopic zu treiben? Tatsächlich sind wir hier nach wie vor bei C vs. Assembler -> Performance und nicht etwa schon beim Kuchenbacken...
:
Bearbeitet durch User
Moby A. schrieb: > Asm-Code ist selbsterklärend. Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei einem "selbsterklärenden Code" passieren?
Sheeva P. schrieb: > Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen > Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. > > Wenn jemand 18 Jahre lang in Assembler programmiert und damit seine > ganze Haussteuerung umgesetzt hat, ... dann wird ja wohl das allermeiste ohne Fehler funktionieren ;-) > Aber es sind ja Sie, welcher behauptet, die > "effiziente,simple Lösung" zu haben. Ich habe nicht die effiziente simple Lösung, sondern sage daß Asm alle nötigen Mittel dafür bietet. > Ich habe auch > noch nie jemanden mit so etwas "herumprotzen" sehen. Sie etwa? In vielen Jahren hier zur Genüge ;-) > Deren Code hat übrigens auch > keine "Flüchtigkeitsfehler". Das bestreite ich jetzt einfach mal so. Wenn sich später in den Projekten auch kaum noch davon was findet. Ich bin weit davon entfernt, wegen Flüchtigkeitsfehlern die Ohren hängenzulassen. Aber in die Projektveröffentlichungen (meine erste und einzige mit Quellcode wohlgemerkt) gehören sie nicht hin. Hatte ich das nicht weiter oben schon gesagt?
Sheeva P. schrieb: > Moby A. schrieb: > Asm-Code ist selbsterklärend. > > Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei > einem "selbsterklärenden Code" passieren? Hatte ich eigentlich auch schon erklärt: Der im Einsatz befindliche Code funktioniert, der für die Projekte leicht veränderte Code (zunächst) nicht. Wirst Du mir daraus jetzt den großen Strick drehen? Bitte bitte nicht, ich flehe um Gnade ;-)
:
Bearbeitet durch User
Moby A. schrieb: > Asm-Code ist selbsterklärend. So wie Josefs Krypto-Asm. Zusammen wärt ihr unschlagbar. ;-)
Moby A. schrieb: > Asm-Code ist selbsterklärend. Auf den Niveau von > die Instruktionsbeschreibung und das Datenblatt ist C das auch, das ist aber nicht der Sinn einer ordentlichen Dokumentation.
Moby A. schrieb: > Sheeva P. schrieb: >> Moby A. schrieb: >> Asm-Code ist selbsterklärend. >> >> Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei >> einem "selbsterklärenden Code" passieren? > > Hatte ich eigentlich auch schon erklärt: Der im Einsatz befindliche Code > funktioniert, der für die Projekte leicht veränderte Code (zunächst) > nicht. > > Wirst Du mir daraus jetzt den großen Strick drehen? > Bitte bitte nicht, ich flehe um Gnade ;-) Wie kann das sein?
Wow, drei Seiten Diskussionstext in ein paar Tagen. Davon gefühlte 99% Ping-Pong mit einem Troll. Bei jedem anderen Thema wären die Herren Moderatoren nicht so zimperlich, aber hier scheints ihnen Spaß zu machen...
Ich habe gerade zwanzig Benachrichtigungsemails zu diesem Thread gelöscht. Die Diskussion geht immer noch um dasselbe Nicht-Thema. Irgendjemand muß sehr, sehr einsam sein.
Moby A. schrieb: > Es soll doch da tatsächlich noch andere Dinge > im Leben geben als hier permanent präsent zu sein. Oder etwa nicht? Gute Idee.
Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen > Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. Da bin ich mal gespannt. Ich wette, jedes Deiner zukünftiger "Projektbeispiele"(*) lässt sich in C performanter und kürzer umsetzen - sowohl was Programmier- als auch Prozessoraufwand betrifft. Moby A. schrieb: > Versuch Du doch umgekehrt mal gegebene Asm-Texte mit C einzudampfen. Es gibt nur keine vorn Dir. Und wenn doch, konnte gezeigt werden, dass es mit C kürzer geht - sowohl was Horsts als auch Dein Mini-Progrämmchen betrifft. 2:0.... Damit bist Du ziemlich im Rückstand, Moby. > Weitere Gelegenheiten werde ich noch liefern. Also wenn ich Deine Programmiergeschwindigkeit in ASM hochrechne (einen simplen Vergleich zu programmieren dauert bei Dir über eine Stunde), dürftest Du so in ca. einem Jahr etwas praxisrelevantes abliefern. Du bleibst also weiter bei Deiner Blender-Strategie. (*) Jedenfalls dann, wenn das Compilat die 1KB-Grenze überschreitet, es sich also nicht um einen Codeschnipsel handelt, der für sich allein nicht einsetzbar ist.
:
Bearbeitet durch Moderator
@ Walter Tarpan (nicolas) >gelöscht. Die Diskussion geht immer noch um dasselbe Nicht-Thema. >Irgendjemand muß sehr, sehr einsam sein. Oder ein ZEN-Meister? https://de.wikipedia.org/wiki/Zen#Lehre
Sheeva P. schrieb: > Moby A. schrieb: >> Asm-Code ist selbsterklärend. > > Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei > einem "selbsterklärenden Code" passieren? Der Code erklärt sich halt nur sich selbst, aber nicht anderen. Zumindest wenn es mehr als ein paar Zeilen sind.
>Der Code erklärt sich halt nur sich selbst, aber nicht anderen. >Zumindest wenn es mehr als ein paar Zeilen sind. WUrde ja bereits gesehen. Der von mir gepostete Asm COde wurde von Moby bisher nicht erklärt. Obwohl es doch selbsterklärend ist.
@Matthias Lipinsky (lippy) >>Der Code erklärt sich halt nur sich selbst, aber nicht anderen. >>Zumindest wenn es mehr als ein paar Zeilen sind. >WUrde ja bereits gesehen. Der von mir gepostete Asm COde wurde von Moby >bisher nicht erklärt. Obwohl es doch selbsterklärend ist. Das erklärt doch alles!
Falk B. schrieb: > Das erklärt doch alles! Jetzt bist du uns aber eine Erklärung schuldig! :) Icke ®. schrieb: > Davon gefühlte 99% Ping-Pong mit einem Troll. Moby ist kein Troll. Der Unterschied ist, dass ein Troll vorsätzlich eine Dikussion stört. Moby stört sie auch, es ist auch Vorsatz dabei, aber ich würde ihm mal nicht unterstellen, dass er sie tatsächlich stören will. Es ist halt nur seine (sehr, sehr penetrant dargelegte) Meinung, dass doch seine Philosophie für alle das beste wäre … Da Horst aber bereits am Anfang des Threads gut und (so ich ihn verstanden habe) ausreichend geholfen worden ist, denke ich, dass es nicht übermäßig stört, hier weiterzudiskutieren. Wenn du dir den ein oder anderen Beitrag mal ansiehst (also eher nicht Mobys, aber beispielsweise Johanns), dann kann man durchaus noch bisschen dabei lernen. OK, von Mobys Beiträgen kann man auch lernen, aber wohl nicht in seinem Sinne. :-))
Moby A. schrieb: > Warum werde ich bloß nicht müde zu betonen, für welche Zielplattform > und für welche Anwendungen ich Asm vorn sehe? Warum fühlt sich jeder > Profi bemüßigt, das sogleich auf sein Gebiet- bis hin zur PC > Programmierung zu beziehen? Weil du dein Assembler Anpreisung auch nicht auf die von dir vorne gesehenen Anwendungen beschränkst. Du kommst mir vor, wie der in Österreich berühmt berüchtigte Flachlandtiroler, der meint nur weil er zu Hause gerade noch so seine 120 Meter hohe Schutthalde raufschnaufen kann, dass er geradezu prädestiniert dazu wäre, andere davon zu überzeugen, dass man die Eiger Nordwand auch mit Sandalen und etwas Bindfaden bezwingen kann.
:
Bearbeitet durch User
Moby A. schrieb: > Asm-Code ist selbsterklärend. Es braucht nämlich nur die > Instruktionsbeschreibung und das Datenblatt sowie ein paar > funktionserklärende Kommentare. Brainfuck, Befunge, Malbolge, FRACTRAN und wie sie alle heißen (https://de.wikipedia.org/wiki/Esoterische_Programmiersprache) sind deiner Definition nach ebenfalls selbsterklärend, denn für jede davon gibt es eine klare Sprachspezifikation, die zudem sogar sehr viel kürzer ausfällt als das AVR Instruction Set Manual. Die allerkürzeste Instruktionsbeschreibung haben diese Prozessoren: https://en.wikipedia.org/wiki/One_instruction_set_computer Deren Assemblersprache müsste für dich somit das Optimum aller Programmiersprachen darstellen, was das Selbsterklärendsein betrifft. Was du bei der Bewertung der Sprachen völlig auser Acht lässt, ist ihre Ausdrucksstärke, d.h. die maximale Komplexität der Problems, das mit einer gegebenen Menge an Code gelöst werden können. Die ist bei den eben erwähnten Sprachen nahezu null, beim AVR-Assembler sehr niedrig, bei C aber schon recht hoch, wie das obige Beispiel des Vergleichs mit einer Konstanten deutlich zeigt: Der aus 9 Zeichen bestehende Term x<1000000 in C ist nicht nur viel kürzer, sondern darüberhinaus auch noch besser lesbar und leichter änderbar als die entsprechende CPI/SBCI-Kette in Assembler. Und wie man gesehen hat, hat selbst ein überzeugter Assembler-Only-Programmierer immense Schwierigkeiten, dieses noch recht einfache Beispiel erst einmal fehlerfrei runterzuprogrammieren und dann auch noch zu optimieren.
Eine sehr schöne Routine, die so nur in C praktikabel ist, ist z.B. der Scheduler: Beitrag "Wartezeiten effektiv (Scheduler)" Die original Idee ist nicht von mir, ich habe sie nur etwas auf den 8051 und den AVR optimiert. Durch die Vorsortierung ist das sehr effizient. Sie läuft unverändert auf jeder anderen CPU und man kann bequem festlegen, ob die Zeitbasis 8, 16, .. 64bittig ist. In Assembler wäre das ein Albtraum und weder anpaßbar noch lesbar oder gar portabel.
Yalu X. schrieb: > Brainfuck, Befunge, Malbolge, FRACTRAN und wie sie alle heißen > (https://de.wikipedia.org/wiki/Esoterische_Programmiersprache) sind > deiner Definition nach ebenfalls selbsterklärend, denn für jede davon > gibt es eine klare Sprachspezifikation Ich kann da nur wieder dieses Beispiel ans Herz legen, was nicht aus einer vorsätzlich irren Programmiersprache stammt. Siehe auch http://fafner.dyndns.org/~vaxman/publications/apl.pdf
Yalu X. schrieb: > Moby A. schrieb: >> Asm-Code ist selbsterklärend. Moby hat einfach nur Schwierigkeiten zu verstehen, dass wir unter 'Code erklären' etwas anderes verstehen als er. Für ihn besteht die 'Erklärung' eines Codes darin, dass er für jeden Assembler Memnonic ein entsprechendes Wort kennt.
1 | ldi r16, 25 |
erklärt er mit
1 | hier wird das Register 16 mit der Konstanten 25 geladen |
Und so 'erklärt' er dann den Code ohne zu begreifen, dass er nichts erklärt, sondern einfach nur vorliest. Alles schön und gut. Nur dass das ganze dann in Summe einen Quicksort ergibt, das entzieht sich seiner Aufmerksamkeit, weil er viel zu sehr mit diesen Low-Level Details beschäftigt ist, bzw. weil sich der eigentliche Zweck eines Codestückes in diesen Details verliert. Wenn Moby C programmieren würde, dann würde er so kommentieren bzw. erklären
1 | i = 5; // i mit 5 laden |
2 | j++; // j um 1 erhöhen |
und das ist genau die Art Kommentierung, die komplett am Sinn einer Kommentierung vorbei geht. Wie ich in einem anderen Thread schon mal sagte: Man kann die Funktionsweise einer Raffinerie nicht dadurch ergründen und erklären, dass man sich alle Schrauben, Muttern und Beilagscheiben ansieht. Klar sind die für die Funktionsweise wichtig, aber auch sind die CAD Programme schon so weit, dass sie Schraubverbindungen selbsttätig dimensionieren und einsetzen. Das CAD, in dem ich zuletzt mitgearbeitet habe, hatte viele derartige Automatismen. Kein Architekt verbringt mehr seine Zeit damit, die Sparren eines Dachstuhls einzeln zu zeichnen. Der zeichnet die Firstlinie, gibt an welches Dach er haben will und das CAD konstuiert den kompletten Dachstuhl anhand des Grundrisses und der sonstigen Angaben für ihn.
:
Bearbeitet durch User
@ Karl Heinz (kbuchegg) (Moderator) >Flachlandtiroler, der meint nur weil er zu Hause gerade noch so seine >120 Meter hohe Schutthalde raufschnaufen kann, dass er geradezu >prädestiniert dazu wäre, andere davon zu überzeigen, dass man die Eiger >Nordwand auch mit Sandalen bezwingen kann. Ein Sandal! ähh, Skandal!
Jörg W. schrieb: > Moby ist kein Troll. Ich kenne Moby und seine Diskussionskultur schon von anderen Threads. Deswegen halte ich mich hier auch raus. > OK, von Mobys Beiträgen kann man auch lernen Ich habe daraus gelernt, daß jeglicher Versuch, Menschen mit derartig zementierten Standpunkten (nannte man früher "Betonköpfe") von ihrem Holzweg abzubringen, selbst unter Zuhilfenahme einleuchtendster Argumente kläglich scheitert. Noch ein klein wenig Topic. Ich programmiere auch gern in ASM, aber ich kenne die Grenzen. Ab einer gewissen Komplexität macht das einfach keinen Sinn mehr. Es ist auch schön, per Pedes durch den Wald zu streifen, den Geräuschen zu lauschen und mit den Füßen direkten Bodenkontakt zu spüren. Und es macht Sinn, die 100m bis zum Bäcker um die Ecke zu laufen. Aber für den Großeinkauf oder die Urlaubsfahrt steig ich dann doch lieber ins Auto.
Karl H. schrieb: > und das ist genau die Art Kommentierung, die komplett am Sinn einer > Kommentierung vorbei geht. In diesem Fall würde ich da eine Ausnahme machen und auch eine Kommentierung der Bedeutung der einzelnen Statements nahelegen: Beitrag "Ein Vorschlag zur Intervall-Arithmetik"
Moby A. schrieb: > Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das > jedenfalls nicht für Deinen Asm-Code. Wenn das Dein einziges Argument ist, gehe ich nicht davon aus, dass Du Dir die Mühe gemacht hast, das Projekt überhaupt zu öffnen. Die reinen Zahlen für die intellektuelle Höchstleistung des numerischen Vergleiches im vierstelligen Bereich (ab der 3. Klasse praktiziert) waren ja im Thread deutlich ablesbar.
Frank M. schrieb: > Moby A. schrieb: > Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch > (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen > Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. > > Da bin ich mal gespannt. Ich wette, jedes Deiner zukünftiger > "Projektbeispiele"(*) lässt sich in C performanter und kürzer umsetzen - > sowohl was Programmier- als auch Prozessoraufwand betrifft. Dann bin ich schon sehr gespannt... Wer die realisierte Funktionalität dann kürzer umsetzt gewinnt den Hauptpreis: Moby hält bzgl. Überlegenheit von Asm die Klappe ;-) > 2:0.... Damit bist Du ziemlich im Rückstand, Moby. Geduld, Geduld. Das Spiel läuft noch nicht lange. > Also wenn ich Deine Programmiergeschwindigkeit in ASM hochrechne (einen > simplen Vergleich zu programmieren dauert bei Dir über eine Stunde) ... schließt Du aus den Zeiten meiner Beiträge? Du bist ein Fuchs ;-) Leider mach ich das nicht hauptberuflich und soviel Zeit steht in der Freizeit nun auch nicht gerade zur Verfügung ;-( > Du bleibst also weiter bei Deiner Blender-Strategie Wen meinst Du kann ich hier blenden? Daß Asm eine Menge Potential hat, nun, da bin ich nicht der Einzige der das behauptet- und täglich erlebt ;-)
Moby A. schrieb: > Leider mach ich das nicht hauptberuflich und soviel Zeit steht in der > Freizeit nun auch nicht gerade zur Verfügung Tja, da geht's den Menschen wie den Leuten. Genau sowas ist halt der Grund, warum so ziemlich alle anderen Mitdiskutanten hier, trotz teils guter oder sogar sehr guter Kenntnisse der jeweiligen Assembler-Welt (siehe Johanns Code) ihre Zeit eben nicht damit verplempern wollen, sich nun zu überlegen, ob in der nächsten Zeile ein gesetztes oder ein gelöschtes Carry-Flag ausgewertet werden soll, und ob die Auswertung direkt als bedingter Sprung erfolgen kann oder wegen eines schier unerreichbaren Sprungziels indirekt (also negiert), indem der nächste (lange) Sprungbefehl stattdessen ausgelassen wird. Diesen ganzen aufwändigen Kleinkram beherrscht eine Maschine namens Compiler einfach mal um mehrere Größenordnungen schneller und vor allem weniger fehleranfällig, weil sie ständig inhärent alle Randbedingungen berücksichtigen kann (wie die Länge eines Sprungs oder eben den adressierbaren Bereich einer BST-Anweisung) und auch bei doppelter Verneinung noch keinen Knoten im Gehirn bekommt. Dafür wiederum kann man dann, ganz ohne es hauptberuflich tun zu müssen, auch mal schnell ein paar Zeilen Code nur für eine Antwort im Forum zusammenhacken, um einem Menschen, der um Hilfe bittet, schnell und unbürokratisch zu helfen – nebenbei, neben der ganz normalen Arbeit, Familie, sonstigen Freizeitbeschäftigungen.
Klaus W. schrieb: > Der Code erklärt sich halt nur sich selbst, aber nicht anderen. > Zumindest wenn es mehr als ein paar Zeilen sind. Das gilt für C genauso. Selbsterklärend im Sinne von 'die Sprach-Vorkenntnis überflüssig machend' ist keine von beiden. Direkter Asm-Text sagt aber direkt was nun wirklich Fakt ist und sich bei C nur über Umwege erschließt. Freilich, man muß es oft gar nicht unbedingt 100%ig wissen. Wenn man auf den Effizienzvorteil von Asm verzichten kann und seine einschränkende Hochsprache liebt. Matthias L. schrieb: > Der von mir gepostete Asm COde wurde von Moby > bisher nicht erklärt. Obwohl es doch selbsterklärend ist. Bitte Geduld Matthias. Siehst ja was hier los ist. Danke für Deine Analyse, die ist noch auf meinem Stack geparkt ;-) Falk B. schrieb: > Das erklärt doch alles! Falk und seine schnellen Erklärungen. Hattest Du den AVR nicht schon längst in der Steinzeit verortet? Wie zum Teufel kann der hier heute immer noch so präsent sein? Karl H. schrieb: > Weil du dein Assembler Anpreisung auch nicht auf die von dir vorne > gesehenen Anwendungen beschränkst. In der Tat sehe ich für Asm größeres Potential wenn ein paar andere Randbedingungen erfüllt wären. Das hier zum Thema zu machen wäre aber uferlos. Bleiben wir mal bitteschön beim Thread-aktuellen AVR!
Jörg W. schrieb: > Diesen ganzen aufwändigen Kleinkram Aufwand? Machen wir mal das AVR Instruction Set nicht aufwendiger als es ist. So ein AVR ist schön überschaubar. Und der "Kleinkram" ist ja gerade jenes Kleinteilige was die bessere Anpassbarkeit an die Hardware und damit die bessere Effizienz von Asm ausmacht! > weil sie ständig inhärent alle Randbedingungen > berücksichtigen kann (wie die Länge eines Sprungs oder eben den > adressierbaren Bereich einer BST-Anweisung) und auch bei doppelter > Verneinung noch keinen Knoten im Gehirn bekommt. Das sind gar nicht soviele Randbedingungen. Anders als beim ARM. Daß BST mit einem falschen Operanden unbemängelt assembliert wird muß wirklich nicht sein. Und was den Knoten im Gehirn angeht: Der entsteht mit komplexen C-Ausdrücken sehr viel schneller. Und da reden wir noch nicht vom weitaus abstrakteren OOP wo der Bezug zur Hardware-Wirklichkeit vollends den Bach runter geht.
Moby A. schrieb: >> Diesen ganzen aufwändigen Kleinkram > > Aufwand? Ja. Aufwand. Schließlich hast du dich gerade beklagt, dass dir die Zeit für bestimmte Dinge fehlt. Glaubst du etwa, die anderen Leute hier würden hauptamtlich fürs Forum schreiben, hätten alle keine Familie, keine anderen Hobbys? Moby A. schrieb: > Und was den Knoten im Gehirn angeht: Der entsteht mit komplexen > C-Ausdrücken sehr viel schneller. Ganz gewiss nicht. Hier geht's noch um so einfache Dinge wie
1 | if (i < 1000000) |
wie dir oben bereits ausgiebig demonstriert worden ist. > Und da reden wir noch nicht vom > weitaus abstrakteren OOP wo der Bezug zur Hardware-Wirklichkeit vollends > den Bach runter geht. Ach ja. Das kannst du bestimmt auch mit Code belegen, oder? Moby, du bist einfach mal 50 Jahre zu spät geboren worden. Vor 50 Jahren hättest du dir als "Mel" ja vielleicht noch Respekt erheischt. https://en.wikipedia.org/wiki/The_Story_of_Mel
:
Bearbeitet durch Moderator
Yalu X. schrieb: > Brainfuck, Befunge, Malbolge, FRACTRAN > Die allerkürzeste Instruktionsbeschreibung haben diese Prozessoren Hochsprachen erklären immer mehr oder weniger schlecht was wirklich vor sich geht. Genau diese Wirklichkeit aber adressiert und erklärt Asm. Das ist es was für mich zählt. Andere Prozessoren? Wir wollen doch nun kein neues Faß aufmachen wenn es hier um AVR geht... > Was du bei der Bewertung der Sprachen völlig auser Acht lässt, ist ihre > Ausdrucksstärke, d.h. die maximale Komplexität der Problems, das mit > einer gegebenen Menge an Code gelöst werden können. Da stimme ich Dir sogar zu. Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für maximale Komplexität bekannt, und das ist gut so ;-) Ausdrucksstärke/Flexibilität und mögliche Komplexität sind die zwei Seiten einer Medaille! > hat selbst ein überzeugter Assembler-Only-Programmierer > immense Schwierigkeiten, dieses noch recht einfache Beispiel erst einmal > fehlerfrei runterzuprogrammieren und dann auch noch zu optimieren. Nochmal: 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke. 2. Was man hat das hat man. Für AVR gibts auch genügend fertigen Asm- Beispielcode so denn umfangreichere Berechnungen mal nötig sind. 3. Sind sie ständig nötig ist AVR/ASM die falsche Wahl.
Jörg W. schrieb: > Moby A. schrieb: > Diesen ganzen aufwändigen Kleinkram > > Aufwand? > > Ja. Aufwand. Schließlich hast du dich gerade beklagt, dass dir die > Zeit für bestimmte Dinge fehlt. Glaubst du etwa, die anderen Leute hier > würden hauptamtlich fürs Forum schreiben, hätten alle keine Familie, > keine anderen Hobbys? Oh welche weiten Zusammenhänge man da doch gleich herstellen kann ;-) Das AVR-Instruktion Set ist weniger Aufwand als das bücherfüllende C-Universum. So definier ich das. > Hier geht's noch um so einfache Dinge wie if (i < > 1000000) Und? Das in Asm hinzuschreiben ist nun kein Hexenwerk. Ich bezog mich beim Thema Gehirnknoten auf komplexere Ausdrücke. Beispiele finden sich weiter oben ;-) > Ach ja. Das kannst du bestimmt auch mit Code belegen, oder? Das belegt jeder OOP Code ;-) > Moby, du bist einfach mal 50 Jahre zu spät geboren worden. Meinst Du? Ich hab eher den Eindruck noch gerade richtig, um mit leistungsstarken kleinen simplen AVRs die Chance zu haben, selber wirklich alles in der Hand zu behalten und gestalten zu können!
Moby A. schrieb: > Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für > maximale Komplexität bekannt, und das ist gut so ;-) Warum meinst du, baut Atmel dann AVRs mit 256 KiB und mehr an Flash? > 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke. Hier irrst du bezüglich des AVR gewaltig. Der AVR ist bei der 32-Bit-Arithmetik viel besser als manch anderer 8-Bitter. Selbst die 32-Bit-Gleitkommaarithmetik von AVR-GCC/avr-libc (und auch IAR) ist so rasend schnell, dass du Mühe haben wirst, ihr mit handgefeilter 24-Bit-Ganzzahlarithmetik in deinem Assemblercode das Wasser zu reichen – wobei du dann immer noch die Grenzen des Wertebereichs im Blick behalten musst, während float eben in der Richtung von selbst skaliert. (OK, Turbo-Pascals 48-Bit-Gleitkomma konnte das auch schon vor 30 Jahren auf dem Z80. Nicht ganz so schnell, aber genauso bequem für den Anwender.) > 2. Was man hat das hat man. Für AVR gibts auch genügend fertigen Asm- > Beispielcode so denn umfangreichere Berechnungen mal nötig sind. Ja, und? Für C gibt es mehr Bibliotheken, als du dir auch nur ansatzweise ausmalen kannst. Viele davon laufen durchaus auch auf einem AVR. > 3. Sind sie ständig nötig ist AVR/ASM die falsche Wahl. Trenne mal zwischen AVR und ASM. Die beiden sind nicht miteinander verheiratet (außer in deinem Kopf), und selbst die ältesten Randnotizen von Atmel bezüglich des AVR zeigen, dass Alf Bogen und Vegard Wollan schon vor 20 Jahren deiner Denkweise massiv voraus waren, da sie bereits in der Designphase einen Compilerhersteller (IAR aus Schweden) mit ins Boot genommen haben. Ihnen war klar, dass man den damals fest aufgeteilten Markt an Microcontrollern (zwichen 8051, PIC und MC68) nur dann neu aufrollen kann, wenn bereits die CPU-Architektur möglichst gut auf eine Sprache wie C passt. Dir ist das selbst 15 Jahre später noch nicht klar.
Peter D. schrieb: > Eine sehr schöne Routine, die so nur in C praktikabel ist, ist > z.B. der Scheduler: > Beitrag "Wartezeiten effektiv (Scheduler)" Ohne jetzt den Code im Einzelnen durchgegangen zu sein- fürs "Warten ohne Rechenzeitverschwendung" ist nun wirklich kein C nötig. Meine Controller haben meist einen mehr oder weniger gleichschnellen Timerinterrupt für allgemeine Aufgaben, so auch zur zeitgesteuerten Taskauslösung bzw. Wartezyklen. Das muß nicht zum Albtraum ausarten.
Moby A. schrieb: > Oh welche weiten Zusammenhänge man da doch gleich herstellen kann ;-) Diese Zusammenhänge sind so ziemlich jedem hier klar, nur dir nicht. Aber geben wir's auf, du willst sie ja nicht sehen. > Das AVR-Instruktion Set ist weniger Aufwand als das bücherfüllende > C-Universum. So definier ich das. Definieren kannst du natürlich, was du willst. Der Gültigkeitsbereich der Definition wird dann allerdings auf dein privates Universum beschränkt bleiben. AVR-Befehlssatz: irgendwas um die 150 Seiten C-Sprachbeschreibung (Kapitel 6 im Standard): 135 Seiten > Ich bezog mich > beim Thema Gehirnknoten auf komplexere Ausdrücke. >> Ach ja. Das kannst du bestimmt auch mit Code belegen, oder? > > Das belegt jeder OOP Code ;-) OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und irgendwer hat dir mal gesagt, es sei "komplex".
Jörg W. schrieb: > Warum meinst du, baut Atmel dann AVRs mit 256 KiB und mehr an Flash? Für Daten? Und natürlich für ausschweifende Hochsprachen! > Der AVR ist bei der 32-Bit-Arithmetik viel besser als manch anderer > 8-Bitter. Und? Deshalb ist ein 32Bitter in diesem Fall immer noch sinnvoller. Aber freut mich das hier so festgestellt zu wissen ;-) > Selbst die 32-Bit-Gleitkommaarithmetik von AVR-GCC/avr-libc (und auch > IAR) ist so rasend schnell, dass du Mühe haben wirst, ihr mit > handgefeilter 24-Bit-Ganzzahlarithmetik in deinem Assemblercode das > Wasser zu reichen – wobei du dann immer noch die Grenzen des > Wertebereichs im Blick behalten musst, während float eben in der > Richtung von selbst skaliert. Klasse wenns so ist! Für umfangreichere Arithmetik hätte ich aber auch super Asm Code in der Hinterhand, wenngleich nicht aus meiner Feder. > Ja, und? Für C gibt es mehr Bibliotheken, als du dir auch nur > ansatzweise ausmalen kannst. Viele davon laufen durchaus auch auf einem > AVR. Ja und? Deshalb hab ich wiegesagt damit trotzdem keine Mühe. Das mit den vielen vielen Bibliotheken sehe ich kritisch. Man begibt sich damit in gewisse Abhängigkeiten, nimmt unbekannte Fehlerquellen in Kauf, oft ist eine Funktion schneller selbst geschrieben als irgendwo passend gefunden und verstanden. > wenn bereits die CPU-Architektur möglichst > auf eine Sprache wie C passt. Warum sollte das verwundern wenn sich der potentielle Anwenderkreis damit erweitert? Deshalb bleibt die einfache Architektur weiter einfachem Asm zugänglich. Asm ist da seeehr flexibel ;-)
Karl H. schrieb: > weil er viel zu sehr mit diesen Low-Level > Details beschäftigt ist Nö. Mit der Hardware- Wirklichkeit. Und bestmöglicher programmtechnischer Anpassung an diese. Damit mit der optimalen Chance auf effizienten Code. > Wenn Moby C programmieren würde, dann würde er so kommentieren bzw. > erklären i = 5; // i mit 5 laden > j++; // j um 1 erhöhen So ein Quatsch. Wenn ich sage daß ldi r16,25 selbsterklärend ist (mit Kenntnis der Instruktion) dann würde ich doch in C nicht derart kommentieren ;-) > und das ist genau die Art Kommentierung, die komplett am Sinn einer > Kommentierung vorbei geht. Richtig. Das wäre so. Aber ich sehe schon Du krallst Dich wieder an subjektiven Kommentierungsfragen fest. Wozu ist eigentlich dieses Forum im allgemeinen und die Projekte-Abteilung im speziellen da? Richtig. Zum Fragen. > Man kann die > Funktionsweise einer Raffinerie nicht dadurch ergründen und erklären, > dass man sich alle Schrauben, Muttern und Beilagscheiben ansieht. Es muß langen, Funktionalität und Interfaces zu beschreiben. Mehr Doku- Aufwand treibe ich nicht. Punkt. Alles andere kann erfragt werden. Asm Quellcode bleibt damit herrlich übersichtlich. Von langatmigen Klammerwüsten keine Spur ;-)
Jörg W. schrieb: > OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und > irgendwer hat dir mal gesagt, es sei "komplex". Noch einer schrieb: > Beide Aussagen sprechen von einer Überforderung durch > Informationen und Optionen > Im laufe der Jahrzehnte hat sich die Programmierung komplett geändert. > In die Register eines 8-Bit Controllers, oder auch in ein DOS-Programm > konnte man sich noch vollständig einarbeiten. Heutzutage ist es so > umfangreich - bis man alle Detail durchgearbeitet hat, ist es schon > wieder veraltet. > Es spaltet sich auf - der eine schreibt Python-Libraries für > Raspberry-Peripherie, der andere schreibt damit Web-Oberflächen für > Steuerungen. Pic32 liegt vielleicht noch an der Grenze, wo sich einer > alleine in alles einarbeiten kann. Bei Cortex-A geht das nicht mehr. > > Und dann kommt noch etwas total bescheuertes dazu: > > 20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme > auf 40 verschiedene Arten. C++ ist da am schlimmsten. Man findet in > einem Programm alles von K&R bis Java-Stil; Selbst gebastelte Container > mit obskurer Garbage-Collection neben QList, STL und alten C-Arrays; > Präprozessor-Tricksereinen neben Inline-Funktionen. > > Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während > man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon > wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut. Soweit zum Thema Komplexität und Kleinkram. Aufgegabelt in "C++ für Mikrocontroller" gleich nebenan ;-)
Icke ®. schrieb: > Ich habe daraus gelernt, daß jeglicher Versuch, Menschen mit derartig > zementierten Standpunkten (nannte man früher "Betonköpfe") von ihrem > Holzweg abzubringen, selbst unter Zuhilfenahme einleuchtendster > Argumente kläglich scheitert. Das höre ich oft als letztes verbleibendes Argument. Immerhin ist das aber noch irgendwo verständlich im Gegensatz zu jenen, die glauben, man müsse nur hinreichend beleidigen. > Noch ein klein wenig Topic. Ich programmiere auch gern in ASM, aber ich > kenne die Grenzen. Ich auch. Nur sind die weit weg. Außer es stehen wirklich mal größerer Berechnungen an ;-) > Es ist auch schön, per Pedes durch den Wald zu streifen, den Geräuschen > zu lauschen und mit den Füßen direkten Bodenkontakt zu spüren. Und es > macht Sinn, die 100m bis zum Bäcker um die Ecke zu laufen. Aber für den > Großeinkauf oder die Urlaubsfahrt steig ich dann doch lieber ins Auto. Ja ja die Vergleiche. Habens wirklich in sich.
Yalu X. schrieb: > Matthias L. schrieb: > Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc > aufgerufen wird. Weiter: > keyproc: > ... > ldd XL,Z+0 ;8x alle 5ms testen > rol XL ;= 200% Bulletproof ;-) > std Z+0,XL > > Du hättest statt der "..." die entsprechenden Befehle vollständig > hinschreiben sollen:keyproc: adiw ZH:ZL,2 ;Tastenstatus entprellend > ermitteln > in YH,GPIOR0 > mov YL,YH > ldd XL,Z+0 ;8x alle 5ms testen > rol XL ;= 200% Bulletproof ;-) > > Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt, im > konkreten Fall mit 0. Somit schiebt ROL in das XL-Register nur Nullen > hinein, was den nett gemeinten Programmiertrick völlig versagen lässt. So. Hab mal drübergeschaut. In der Tat löscht adiw ZH:ZL in jedem Fall das C-Flag. Vermutlich hab ich das später noch hinzugefügt/umgeändert. Abhilfe: Aufruf von keyproc mit T- statt C-Flag und nach mov YL,YH ein brtc zum ldd XL,Z+0 sowie zwischendrin noch ein sec. Also 2 Instruktionen mehr. Es stimmt, das Programm ist noch nicht getestet, sollte aber auch nur im ursprünglichen Thread eine einfache Problemlösung in Asm andeuten. Nach einem Test soll der Main-unabhängige Timerinterrupt-Baustein zur Tastenentprellung und Feststellung der Betätigungsdauer beliebiger IO-Pin Tasten in die Codesammlung. > Wir wissen zwar nicht, was Mobys Programm tun soll Was sollen solche halbgaren Feststellungen? Die beabsichtigte Funktionalität ist doch klar definiert. > Und was lernen wir daraus? > 1. Das Carry-Flag ist eigentlich gedacht Man muß sich nicht unbedingt daran orientieren wofür etwas gedacht ist. Damit geht vielleicht ein höheres Risiko für Fehler (wie hier) einher aber man bewahrt sich alle technischen Möglichkeiten. > Wenn man schon Assembler programmiert und dabei auzch noch tief in > die Trickkiste greift, sollte man gut ausgeschlafen sein und jede > Code-Änderung dreimal mit dem Auge durchgehen und zusätzlich intensiv > testen. Flüchtigkeitsfehler sind wirklich nicht die größten Probleme. Die sind eher systematischer Natur, etwa in Zusammenhang mit unklaren realen Messwerten. > Er hat sie auf mehrere Tasten erweitert, musste dazu aber die > indirekte Adressierung für das Z-Register und damit verbunden den > ADIW-Befehl einführen, was schließlich zu dem Fehler führte. Gut möglich. > => Wiederverwendbarkeit von Code erfordert eine genaue und > vollständige Dokumentation nicht nur der Funktion, sondern auch der > Nebeneffekte. Das ist hier offensichtlich nicht geschehen. Richtig. > Da Moby der Assembler-Gott ist, der immer alles richtig macht, hat er > auch keinen Bedarf gesehen, die Routine vor ihrer Veröffentlichung > wenigstens einmal zu testen ;-) Schön wärs. > 3. Hochsprachen sind weniger anfällig gegen solche Fehler Dafür gegen andere. Also sollte der C-Flag Fehler der Einzige im Programm gewesen sein bin ich schon zufrieden. Das Angebot zum kürzeren Formulieren der beschriebenen Funktionalität in C steht nach wie vor... Dabei muß man sich auch nicht an meiner Programmlogik orientieren.
:
Bearbeitet durch User
Moby A. schrieb: > Jörg W. schrieb: >> OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und >> irgendwer hat dir mal gesagt, es sei "komplex". > > Noch einer schrieb: >> Beide Aussagen sprechen von einer Überforderung durch >> Informationen und Optionen ... >> Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während >> man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon >> wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut. > > Soweit zum Thema Komplexität und Kleinkram. > Aufgegabelt in "C++ für Mikrocontroller" gleich nebenan ;-) Na und? Du bist halt nicht der einzige, der nicht programmieren kann.
Nö, Moby hat in einer Hinsicht schon recht. Von Assembler zu C zu C++ steigern sich Abstraktion und Komplexität - wobei ich damit nicht die des erzeugten Codes meine. Mit der Länge des Handbuchs ist das nur unzureichend beschrieben. So steht der Assembler-Befehl XXX R0,R1 für eine klare Anweisung, genau an dieser Stelle genau das zu tun, was da steht, und es reicht weitgehend aus, die Beschreibung des Befehls nachzulesen um zu verstehen, was die Zeile genau tut. Man kann aufgrund des vielen Kleinklein zwar das Programm schlechter anhand des Codes erfassen, aber die einzelnen Zeilen sind einfacher. Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt sich die tatsächliche Operation erst aus den Datentypen der Operanden. So ist nicht von vorneherein klar, ob mit oder ohne Vorzeichen verglichen wird, weil das von den exakten Datentypen und dem Typenmodell des Compilers abhängig ist (u16 < i32 => signed, u32 < i32 => unsigned). Dafür aber sieht man gleich, dass es ein Vergleich ist, egal ob dahinter nur ein Maschinenbefehl sitzt, oder hunderte. Die ersten C Compiler waren auch noch auf einer Ebene, der C die Einstufung als glorifizierter Makroassember verdankte. Sie übersetzten ziemlich linear den geschriebenen Code in Maschinencode. Wer Registeroptimierung wollte, der tat das selbst und schrieb "register" hin. Code wurde nicht wegoptimiert, nicht verschoben. Probleme mit in Interrupts verwendeten Daten entstanden erst, als die Compiler besser wurden, weshalb dann "volatile" nachgereicht wurde. Dieses "volatile" sorgt zwar nur für ein paar Zeilen im Handbuch, hat aber fundamentalen Einfluss auf bestimmte Programmierkonzepte, wie viele µC-Programmierer erst lernen müssen. Moby bleibt dies erspart. Mit C++ setzt sich das fort. So kann man sich bei eigentlich per Referenz übergebenen Parametern von dummerweise vom Compiler nur temporär angelegten Daten überraschen lassen, wodurch das Ergebnis im Nirvana entschwindet. Aus dem Quellcode der Zeile geht das nicht hervor, da muss man weit mehr überblicken. Inwieweit das freilich gegen die Programmierung in Hochsprachen spricht muss jeder für sich entscheiden. Komplexität ist nicht grundsätzlich ein Nachteil, weil man oft nur aufgrund der Komplexität der Mittel überhaupt erweiterte Probleme lösen kann. Moby beschränkt sich dann eben auf jene Probleme, die er lösen kann. Die anderen negiert er gerne, weil "braucht man kaum". Das Problem mit Moby ist nicht seine Beschränkung auf Werkzeuge, deren Komplexität er überblicken kann, sondern sein Sendungsbewusstsein, diese persönliche Eigenheit zu Mass der Dinge zu erklären und andere davon überzeugen zu wollen. Ihn schreckt der höhere Abstraktionsgrad höherer Sprachen, andere Leute aber nicht, und das versteht er nicht.
:
Bearbeitet durch User
Moby A. schrieb: > Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für > maximale Komplexität bekannt, und das ist gut so ;-) Du hast gar keine Ahnung, wie "typische 8-Bit-Apps" für AVRs aussehen. Da passt schon jede Menge an Funktionalität rein, von denen Du noch nichtmals zu träumen wagst. Beschränke Dich mal bei Deinen ganzen Behauptungen auf ATTiny mit höchstens 1KB Flash. Da machen Deine Argumente (und damit Assembler) vielleicht noch in einigen Ausnahmefällen überhaupt Sinn. Deine Welt ist klitzeklein, Moby. Du wüsstest noch nichtmals, was Du mit einem ATmega328 anfangen könntest. "Typische AVR-Anwendungen" finden aber eher in diesen Größenordnungen statt.
A. K. schrieb: > So steht der Assembler-Befehl XXX R0,R1 für eine klare Anweisung, ... ... > Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt... So kann man aber nicht sinnvoll vergleichen, es sei denn man misst seine Arbeit in Anzahl Programmzeilen. Es geht ja in der Regel nicht darum, Text zu produzieren, sondern ein Problem zu lösen. Und dann kann man nicht einen C-Ausdruck mit einem Assemblerbefehl vergleichen, sondern müsste den C-Ausdruck mit der entsprechenden Folge von Assemblertext vergleichen, der funktional gleichwertig ist. Und genau dann ist Assembler bei nichttrivialen Problemen eben schon nicht mehr so klar und übersichtlich - wie man an den Fehlern in Mobys ach so klaren, übersichtlichen und selbsterklärenden Programmen sieht. Hier sehe ich den die Crux der ganzen Diskussion (neben dem Missioniergeist, der mit Verblödung regelmäßig einhergeht in jeder Religion): EIN Assemblerbefehl ist übersichtlich, klar. Aber die vielen, die man für ein halbwegs komplexes Problem braucht, sind es nicht mehr. Auch ein typisches C-Programm besteht ja nicht mehr aus einem Vergleich, sondern aus wesentlich mehr. Wenn man dann für jedes Detail etliche Maschinenbefehle erfassen muß, hat man einfach keinen Überblick. Außer man ist so genial wie Moby; ich bin zu doof für sowas.
> ich bin zu doof für sowas.
Viele hier sind zu doof dafür, mich eingeschlossen. Deshalb müssen wir
mit Programmieren unsere Brötchen verdienen. Nur einer macht das als
Hobby, der Mobby! (wie er sich diesen NickName ausgesucht hat. Welch
Weitblick!)
(bin ich froh, daß ich den nicht als Kollegen hab. Obwohl, der ein oder
andere, um den ich einen großen Bogen mache, ist auf einem "guten" Weg)
Klaus W. schrieb: > Und dann kann man nicht einen C-Ausdruck mit einem Assemblerbefehl > vergleichen, Doch, kann man schon. Man kann Programmzeilen vergleichen und man kann Lösungen vergleichen. Ich hatte oben eine Programmzeile verglichen, um den Unterschied der Komplexität dieser Programmzeile hervorzuheben. Dass man für die gleiche Lösung wesentlich mehr Asm-Zeilen benötigt ist unstrittig und eine andere Art von Vergleich. > Aber die vielen, die man für ein halbwegs komplexes Problem braucht, > sind es nicht mehr. Klar. > Außer man ist so genial wie Moby; ich bin zu doof für sowas. Die Grösse eines Programms, das man noch einigermassen überblicken kann ist begrenzt. Weshalb die Lösungen, die man noch alleine stemmen kann, mit der Komplexität des verwendeten Werkzeugs wachsen. Weshalb man in einer geeigneten Hochsprache komplexere Lösungen stemmen kann als in Assembler. Er beschränkt sich auf das, was er überblicken kann, und definiert alles darüber hinaus als "braucht man nicht". ;-)
:
Bearbeitet durch User
A. K. schrieb: > Er beschränkt sich auf das, was er überblicken kann, und definiert alles > darüber hinaus als "braucht man nicht". ;-) Genau dieser Mikrokosmos von Moby ist der Grund für diesen ellenlangen Thread.
Moby A. schrieb: >> Wir wissen zwar nicht, was Mobys Programm tun soll > > Was sollen solche halbgaren Feststellungen? > Die beabsichtigte Funktionalität ist doch klar definiert. Ok, das nehme ich zurück. Ich hatte das mit deinem anderen Code (adu.asm) verwechselt, dem tatsächlich die Beschreibung der Gesamtfunktion fehlt. > Also sollte der C-Flag Fehler der Einzige im Programm gewesen sein bin > ich schon zufrieden. Ich habe das Programm genauso wenig getestet wie du. Der Fehler mit dem Carry-Flag ist mir aufgefallen bei dem Versuch, die Funktion des Codes wenigstens grob zu verstehen. Die meisten Fehler werden aber nicht beim Durchlesen des Codes, sondern erst beim realen Test aufgedeckt. Zum Thema Moby A. schrieb: > Hardware- Wirklichkeit Es ist sicher kein Fehler, wenn ein C-Programmierer auch ein wenig Ahnung von Assembler-Programmierung auf der von ihm eingesetzten Plattform hat, ganz im Gegenteil: Dadurch hat er ein besseres Gefühl dafür, was er mit bestimmten C-Konstrukten der CPU tatsächlich zumutet. Ich behaupte mal, dass C-Programmierer, die auch etwas Assembler können, i.Allg. effizienteren Code schreiben als diejenigen, die nur in Hochsprachen unterwegs sind. Umgekehrt gilt das aber auch: Assembler-Programme von Leuten, die auch regelmäßig in Hochsprachen programmieren, haben i.Allg. eine bessere Struktur. Dazu gehören bspw. die Vermeidung von Nebeneffekten in Unterprogrammen (wo möglich), einheitliche Konventionen für den Transfer der Input- und Outputdaten von Unterprogrammen und die Behandlung zusammengehörender Daten als eine Einheit (Datenstrukturen). Das kostet zwar evtl. ein paar Prozent CPU-Leistung, erleichtet dafür aber die Wiederverwendung von früher geschriebenem Code und reduziert dabei gleichzeitig die Gefahr von Flüchtigkeitsfehlern, wie sie dir bei der Anpassung relativ kurzer Code-Abschnitte jetzt schon zweimal passiert sind. Mein Rat an dich: Bleib bei deinem Assembler, wenn es dir Spaß macht, aber versuche parallel dazu, mehr Einblick in die C-Programmierung zu bekommen. Du wirst dabei immer wieder Aha-Effekte erleben, die dir auch bei der Assembler-Programmierung zugute kommen. Als Nebeneffekt wirst du dann auch bei Assembler-vs-C-Diskussionen wie dieser hier von den anderen ernster genommen :) Moby A. schrieb: > Asm Quellcode bleibt damit herrlich übersichtlich. > Von langatmigen Klammerwüsten keine Spur ;-) Du siehst ein C-Programm als eine langatmige Klammerwüste, weil du von C keine Ahnung hast. Mir geht es ähnlich, wenn ich mir das von A. K. gepostete APL-Beispiel anschaue: A. K. schrieb: > Ich kann da nur wieder dieses Beispiel ans Herz legen Weil ich von APL keine Ahnung habe, stellt sich das Beispiel für mich als Wüste von seltsamen Symbolen dar. Ich käme aber nicht auf die Idee, in einer Diskussion mit APL-Programmierern APL deswegen schlecht zu reden, denn ich weiß genau: - Alle anderen Diskussionsteilnehmer verstehen diesen Code und sehen zwar die Symbole, aber keine Wüste. - Als einziger Ahnungsloser werde ich von den anderen zunächst mitleidig belächelt werden. - Wiederhole ich meine Auffassung, dass APL Käse ist, zu oft, werde ich irgendwann in hohem Bogen aus der Diskussion hinausfliegen. Wenn das Wetter am Wochenende schlecht ist, werde ich mir das APL-Beispiel vielleicht mal genauer anschauen und dann mein erstes Urteil über diese Sprache bilden. Einen Startpunkt habe ich schon gefunden: http://tryapl.org/ :)
Yalu X. schrieb: > Es ist sicher kein Fehler, wenn ein C-Programmierer auch ein wenig > Ahnung von Assembler-Programmierung auf der von ihm eingesetzten > Plattform hat, ganz im Gegenteil: Dadurch hat er ein besseres Gefühl > dafür, was er mit bestimmten C-Konstrukten der CPU tatsächlich zumutet. Das kann ich nur bestätigen. Auch ich habe mal in den 80ern Z80-Assembler gelernt und konnte nach einiger Übung sogar Binär-Programme direkt in HEX-Codes in den Rechner eingeben, ohne einen Assembler bemühen zu müssen - hatte also den Assembler sozusagen eingeatmet :-) Auf jeden Fall ist die Kenntnis einiger Assembler Dialekte (später kam noch 68000 dazu) auch für einen Hochsprachen-Programmierer sehr nützlich. Denn er weiß dann, wie er dem Compiler "Hilfestellung" beim Compilieren/Optimieren geben kann. Als Beispiel sei hier nur das Arbeiten mit Kopien von volatile-Variablen in ISRs genannt. Auch heute schaue ich noch ab und zu in das vom Compiler generierte Assembler-File, einfach weil ich neugierig bin, wie er diese oder jene (kniffligere) Aufgabe gelöst hat und bin manchmal sehr überrascht, wie effizient die Lösung ist. > Ich behaupte mal, dass C-Programmierer, die auch etwas Assembler können, > i.Allg. effizienteren Code schreiben als diejenigen, die nur in > Hochsprachen unterwegs sind. ACK. > Umgekehrt gilt das aber auch: Assembler-Programme von Leuten, die auch > regelmäßig in Hochsprachen programmieren, haben i.Allg. eine bessere > Struktur. Sehe ich genauso. Ich weiß leider nicht, ob Moby aus Deinen Argumenten eine nützliche Lehre ziehen kann, denn manchmal kommt mir sein Horizont ziemlich beschränkt vor.
:
Bearbeitet durch Moderator
Lasst euch nicht auf fundamentale Assembler-Programmierer, die nichts anderes können oder (können) wollen, ein. Sie ziehen euch auf ihr Niveau herunter und besiegen euch mit langjähriger Erfahrung... Yalu X. schrieb: > Weil ich von APL keine Ahnung habe, stellt sich das Beispiel für mich > als Wüste von seltsamen Symbolen dar. Ich würde da auch erst mal nach der Baudrate sehen, wenn sowas über eine serielle Schnittstelle hereinkäme ;-)
:
Bearbeitet durch Moderator
Frank M. schrieb: > Denn er weiß dann, wie er dem Compiler "Hilfestellung" beim > Compilieren/Optimieren geben kann. Das kann allerdings auch in die Hose gehen, wenn man die Maschine wechselt, neue und alte Maschine sich erheblich unterscheiden und man die Regeln der alten Welt im Kopf hat. So verleitet C Programmierung auf 8-Bittern genau diesen Personenkreis dazu, umfänglich mit globalen oder statischen an Stelle lokaler Variablen oder Struct-Parametern zu programmieren. Statisch adressieren können die sehr gut, während sie sich mit Adressierung relativ zu Pointern mitunter deutlich schwerer tun (insbesondere 8051 und PIC). Wechseln man dann auf beispielsweise ARM, dann führt das zu ausgesprochen ineffizienten Programmen, da es bei denen genau umgekehrt ist. Statische Adressierung ist ineffizient, relative Adressierung effizient, und man nimmt dem Compiler die Chance zur Optimierung über Register.
:
Bearbeitet durch User
Wie heisst es schön: Wir leben zwar alle unter dem gleichen Himmel, haben aber nicht alle denselben Horizont.
Moby A. schrieb: > Frank M. schrieb: >> Moby A. schrieb: >> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch >> (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen >> Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen. >> >> Da bin ich mal gespannt. Ich wette, jedes Deiner zukünftiger >> "Projektbeispiele"(*) lässt sich in C performanter und kürzer umsetzen - >> sowohl was Programmier- als auch Prozessoraufwand betrifft. > Dann bin ich schon sehr gespannt... > Wer die realisierte Funktionalität Können wir gerne machen. Wir vereinbaren einen Zeitpunkt an dem du und ich Zeit haben. Ein paar Forneteilnehmer denken sich eine Aufgabe aus, irgendjemand (du, ich, wir beide) wählt eine der Aufgaben aus und dann schaun wir mal, wer schneller das Programm stehen hat und wer es fehlerfreier hinkriegt. Ich hab nur eine Bedingung: es darf kein Pipifax Beispiel sein sondern sollte schon was ordentliches sein. Wir müssen uns noch auf eine zu verwendende Hardware einigen. AVR, ein paar Taster und ein 2 oder 4 zeiliges LCD. VOn mir aus kann ich auch noch ein paar Lichtschranken improvisieren. Aber eine CNC Ansteuerung ist zb so für einen Interessenten nicht machbar, denn keiner von uns beiden hat die Hardware da und ohne testen zu können mach ich sowas nicht.
:
Bearbeitet durch User
Lothar M. schrieb: > Ich würde da auch erst mal nach der Baudrate sehen, wenn sowas über eine > serielle Schnittstelle hereinkäme ;-) Ich würde dann aber an deiner Stelle auch am Terminal zweifeln. Zeig mir mal, an welcher Stelle deines 8-Bit Zeichensatzes Symbole wie ⍳, ⌹ oder ⍴ zu finden sind. ;-)
:
Bearbeitet durch User
> AVR, ein paar Taster und ein 2 oder 4 >zeiliges LCD. Vielleicht eine Art Laufschrift, welche beim Starten aus dem EEPROM geladen und dargestellt wird. Mit den Tasten kann man dann in einen Editiermodus gehen und den Text verändern. Dieser würde dann wieder im EEPROM abgelegt... Ich denke, das geht über eine blinkende Led heraus. Aber Tastenentprellung, LCD-Ansteuerung, etwas EEPROM sind ein klar abgesteckter Rahmen. Aber eben etwas mehr als ein >Pipifax Beispiel einer blinkenden LED.
Also wenn ihr das wirklich ernst meint, dann nehmt ein Beispiel, das im Simulator gut getestet werden kann.
:
Bearbeitet durch User
Matthias L. schrieb: >>Pipifax Beispiel > einer blinkenden LED. blinkende LED kann ruhig auch dabei sein. 3 oder 4 Stück, die voneinander unabhängig in einer vom Benutzer eingebbaren Frequenz blinken sollen. Kleine Menüsteuerung noch dazu, mit der man die LED zb auf einen Triggereingang 'verkabeln' kann. Eventuell eine kleine Ablaufsteuerung, damit auch Datenstrukturen ins Spiel kommen. Vielleicht noch ein oder 2 Servos (wenn Moby welche hat) ... Irgendsowas. Ein bunter Mix aus Beherrschung der Hardware, Basistechniken, ein bisschen rechnen, Speicherverwaltung, ..... Aber erst mal muss er den Fehdehandschuh aufgreifen. Mal sehen, obs so kommt wie es immer kommt, wenn ich sowas anbiete :-)
:
Bearbeitet durch User
A. K. schrieb: > Das kann allerdings auch in die Hose gehen, wenn man die Maschine > wechselt, neue und alte Maschine sich erheblich unterscheiden und man > die Regeln der alten Welt im Kopf hat. Ja, natürlich. Wenn man aber nicht nur in der (eingeschränkten) Welt der µCs zuhause ist, sondern zum Beispiel auch für diverseste sehr heterogene UNIX-Umgebungen (beileibe nicht nur x86), programmiert, bekommt man langsam mit der Erfahrung ein "Gefühl" dafür, was unter welcher Plattform sinnvoll ist und was nicht. > Wechseln man dann auf beispielsweise ARM, dann führt das zu > ausgesprochen ineffizienten Programmen, da es bei denen genau umgekehrt > ist. Statische Adressierung ist ineffizient, relative Adressierung > effizient, und man nimmt dem Compiler die Chance zur Optimierung über > Register. Okay. Manchmal muss man dann halt Kompromisse machen - gerade wenn man so portabel programmiert, dass ein- und dasselbe Programm sowohl auf ARM als auch auf AVR und PIC läuft. Wenn ich aber ein Programm erstelle, dass nur auf einem ARM laufen soll, gehe ich da mit ganz anderen Methoden dran. Die hier eher üppigen Ressourcen verleiten mich dazu, den Processor auch als "erwachsene Maschine" auszunutzen. Dazu gehören auch die Methoden zur Adressierung von Speicher bzw. dessen Verwaltung. Das macht wesentlich mehr Spaß als das eher beschränkte Programmieren von 8-Bit-AVRs.
Karl H. schrieb: > blinkende LED kann ruhig auch dabei sein. 3 oder 4 Stück, die > voneinander unabhängig in einer vom Benutzer eingebbaren Frequenz > blinken sollen. Kleine Menüsteuerung noch dazu, mit der man die LED zb > auf einen Triggereingang 'verkabeln' kann. Mein Vorschlag: 8-Kanal Software-UART (nur Eingänge), um 8 verschiedene LEDs mit SW-PWM zu steuern. Hierbei kann dann jeder Teilnehmer Skalierbarkeit seiner Software demonstrieren. Kleines UART-Protokoll dazu: Bn<CR> Helligkeit (Brightness) auf n% Ft,n<CR> Fading innerhalb der Zeit t auf n% Beispiele: B80<CR> Helligkeit (Brightness) auf 80% B00<CR> Ausschalten B100<CR> Brightness auf 100% F10,80<CR> Fading innerhalb von 10 Millisekunden auf 80% F100,00<CR> Fading innerhalb von 100 Millisekunden auf 0% Diese Aufgabe halte ich für sinnvoller, da die Lösung nachher nicht für die Tonne ist, sondern durchaus für das eine oder andere Projekt verwendet werden kann :-)
:
Bearbeitet durch Moderator
A. K. schrieb: > Nö, Moby hat in einer Hinsicht schon recht. Von Assembler zu C zu C++ > steigern sich Abstraktion und Komplexität Die Abstraktion steigt, aber auch die Komplexität? Eher nicht. Es gibt ja schließlich Gründe, warum Spaghetticode wie in Assembler so einen enorm schlechten Ruf hat und warum dringendst von der Verwendung des "goto"-Befehls in C und C++ abgeraten wird: weil das den Code unübersichtlich (vulgo: komplizierter) macht sowie Pflege und Wiederverwendung erschwert. Ja, eine einzelne Assembler-Instruktion ist "einfacher" insoweit als sie nur einen einzigen, winzigen kleinen Teil des Programms ausmacht. Aber das ist nur der eine Teil der Wahrheit, und der andere Teil lautet: eine einzelne Instruktion ist eben nur ein winzig kleiner Teil eines deutlich größeren Programms. Genau da liegen aber die Vorteile einer besseren Strukturierung und Abstraktion durch die Hochsprachen, im Gegensatz zu Spaghetticode, in dem zwischen verschiedenen Sprungmarken und Codeteilen wild hin- und hergesprungen wird. > Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt > sich die tatsächliche Operation erst aus den Datentypen der Operanden. Das ist nicht komplizierter, sondern viel einfacher, weil der Compiler dem Entwickler die Entscheidung, welche Maschineninstruktion(en) zu verwenden sind, ganz einfach abnimmt. Dank der deklarierten Datentypen der Variablen weiß der Compiler nämlich, welche Operation benutzt werden muß, und nimmt automatisch und ohne jedes Zutun die Richtige(tm). Für den Entwickler ist das eine enorme Vereinfachung und Erleichterung seiner Arbeit, und nicht zuletzt deswegen ist die Produktivität eines Entwicklers in Hochsprachen so viel höher als in Assembler. Richtig ist, daß der Entwickler dabei ein wenig von der Kontrolle darüber verliert, was sein Code genau macht. Mehr Kontrolle bedeutet aber immer mehr Arbeit und Komplexität, um die sich der Entwickler kümmern muß.
Sheeva P. schrieb: > Die Abstraktion steigt, aber auch die Komplexität? Eher nicht. In aller Kürze: Bei geeigneten Werkzeugen wird die Lösung eines nicht trivialen Problems durch die Wahl eines komplexeren Werkzeugs oft einfacher, sofern man nicht an der Komplexität des Werkzeugs scheitert. Es ist weitaus schneller, nach Malle zu fliegen als zu schwimmen. Aber man behilft sich dabei eines hochkomplexen Werkzeugs namens "Flugzeug" und überlässt dessen Komplexität andern Leuten und Automaten. Schwimmen ist ein Vorgang von weitaus geringerer Komplexität und ist dabei nicht unmöglich, aber es ist nicht wirklich als Lösungsansatz zu empfehlen. Gäbe es keine Piloten (inkl. Auto-) und man müsste selber ans Steuer des Vogels, dann würde viele Leute wohl den Moby machen und in einfacher erreichbaren heimatlichen Gefilden urlauben. "Komplexität" ist ein weiter Begriff. Ich bezog mich darauf, dass man die Abfolge von Assembler-Befehlen relativ leicht anhand der einzelnen Beschreibungen der Befehle nachvollziehen kann. In einer Hochsprache hingegen gibt es eine Vielzahl an Faktoren, die in die exakte Funktion einer Zeile einfliessen können. Viele dieser Faktoren sind quer über die Sprachbeschreibung gestreut und der Programmierer muss sie im Kopf haben und zum passenden Zeitpunkt mit der Zeile assoziieren. > Ja, eine einzelne Assembler-Instruktion ist "einfacher" insoweit als sie > nur einen einzigen, winzigen kleinen Teil des Programms ausmacht. Weshalb ich ja auch vorhin schon zwischen der Komplexität der Zeile und der Komplexität der Lösung unterschied. >> Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt >> sich die tatsächliche Operation erst aus den Datentypen der Operanden. > > Das ist nicht komplizierter, sondern viel einfacher, weil der Compiler > dem Entwickler die Entscheidung, welche Maschineninstruktion(en) zu > verwenden sind, ganz einfach abnimmt. Die Codegenerierung ist nur ein Teil der Gesamtproblematik. Ein häufiges Problem unter C Programmieren ergibt sich aus der Kombination vorzeichenfreier und vorzeichenbehafteter Typen. Aus if(a < b)... ergibt sich nicht direkt, ob der Vergleich mit oder ohne Vorzeichen stattfindet. Auch wenn "unsigned a" und "long b" bekannt sind ist das noch nicht klar, denn 16- und 32-Bit Maschinen verhalten sich dann völlig verschieden. Der Programmierer muss also jenseits der Bedeutung des "<" Operators auch die in C üblichen Konvertierungsregeln im Kopf haben und diese in Bezug zur realen Maschine setzen. Es ist diese Art der Komplexität einer Sprache, auf die ich mich beziehe. > muß, und nimmt automatisch und ohne jedes Zutun die Richtige(tm). Er nimmt das, was sich aus den Regeln ergibt. Das ist keineswegs immer die richtige Wahl in Bezug auf die Lösung des Problems. Das "do what I mean, not what I say" Problem ist nach wie vor ungelöst. > Für den Entwickler ist das eine enorme Vereinfachung und > Erleichterung seiner Arbeit, Richtig. Weshalb ich ja diese Form der Komplexität nicht ablehne. Ich weise nur darauf hin, dass es sie gibt.
:
Bearbeitet durch User
A. K. schrieb: > Doch, kann man schon. Man kann Programmzeilen vergleichen und man kann > Lösungen vergleichen. Wenn man die Anzahl von Programmzeilen in Assembler, C und, sagen wir, Ruby vergleicht, wird daraus aber zwangsläufig ein Vergleich von Äpfeln, Bananen, und Rinderhacksteaks, oder anders gesagt: solche Vergleiche hinken und sind weder sinnvoll, noch zielführend. Zumal die Zeilen, die Du vergleichen willst, nicht einmal näherungsweise etwas ähnliches tun. Das ist aber gerade das, was einen Programmierer interessiert: nämlich das, was sein Programm tut, also daß das Programm sein Problem löst. Wie es das Problem dann tatsächlich löst, ist eher nebensächlich. Programmieren ist schließlich kein Selbstzweck, sondern soll praktische Probleme lösen, wie hier im Beispiel den Vergleich zweier Zahlen. > Ich hatte oben eine Programmzeile verglichen, um den Unterschied der > Komplexität dieser Programmzeile hervorzuheben. Dass man für die gleiche > Lösung wesentlich mehr Asm-Zeilen benötigt ist unstrittig und eine > andere Art von Vergleich. Es ist die einzige Art von Vergleich, die einen Sinn ergibt. Aber auch wenn wir bei Deinem Vergleich bleiben, zeigt sich, wie viel komplizerter ASM ist: ein "if(a < b)" versteht sogar jemand, der überhaupt keine Ahnung von der Programmiersprache C oder überhaupt vom Programmieren hat. In Assembler steht da etwas wie "cp r16, r17", "cpc r16, r17" oder "cpi r16, r17", was sich einem Betrachter nur erschließen kann, wenn er weiß, was "cp", "cpc" und "cpi" tun und was die Register "r16" und "r17" sind. Um Dein Assembler-Beispiel aber auch nur halbwegs vergleichbar mit jenem in C zu machen, kommt allerdings noch der Sprungbefehl hinzu, und erst wenn man den hinzunimmt, kommt am Ende etwas heraus, das wenigstens im Ansatz mit dem C-Beispiel äquivalent und vergleichbar ist. Denn das ist schließlich jener Grad an Komplexität, die der Programmierer letztlich behandeln und beherrschen muß. Und dann bekommt die Sache einen Sinn:
1 | if(a < b) mach_dies(); |
ist viel einfacher und lesbarer und sogar für Laien verständlicher als
1 | cp r16, r17 |
2 | brlo mach_dies |
-- und das gilt nur für vorzeichenlose (unsigned) Zahlen in r16 und r17. Wenn die Zahlen vorzeichenbehaftet (signed) sind, heißt die Instruktion nicht mehr "brlo", sondern "brlt"... Das erschließt sich jemandem, der Programmieren kann, aber ein Laie versteht nichtmal, warum es da zwei verschiedene Instruktionen gibt, die (vermeintlich) dasselbe tun. Und weil nur Masochisten und Ideologen sich an solcherlei Kinkerlitzchen aufhalten, reale Programmierer aber praktische Probleme schnell und effizient lösen wollen, wird Assembler heute nurmehr in wenigen Ausnahmefällen benutzt. Für einen, der sie beherrscht, sind C und, wo wir gerade dabei sind, auch C++ sehr viel klarer und einfacher als Assembler.
für unterschiedliche Leute sind halt verschiedene Sachen eine 'Erklärung/Dokumentation'. Hier mal ein klassischer Filmausschnitt: https://www.youtube.com/watch?v=rFz2llnnC1o Es ist ganz klar was dieses Objekt (Zeile Code) tut. Nur das 'wozu' fehlt.
Sheeva P. schrieb: > Wenn man die Anzahl von Programmzeilen in Assembler, C und, sagen wir, > Ruby vergleicht, Wir schreiben aneinander vorbei. Ich beziehe mich stets auf die Komplexität des Werkzeugs und du zählst andauernd Programmzeilen. Wer ein komplexes Werkzeug beherrscht, der hat bei der Lösung eines für dieses Werkzeug geeigneten Problems weniger Arbeit als jemand, der mit einem weitaus einfacheren Werkzeug auskommen muss. Das ändert nichts an der Komplexität des Werkzeugs, sehr wohl aber den Aufwand zur Lösung
:
Bearbeitet durch User
A. K. schrieb: > Wer ein komplexes Werkzeug beherrscht, der hat bei der Lösung eines für > dieses Werkzeug geeigneten Problems weniger Arbeit als jemand, der mit > einem weitaus einfacheren Werkzeug auskommen muss. Das ändert nichts an > der Komplexität des Werkzeugs, sehr wohl aber den _Aufwand zur Lösung_ Akzeptiert und Zustimmung. Ja ich weiss, du wolltest nur diese Feststellung treffen - und da teile ich deine Sichtweise. In diesem Sinne ist Assembler natürlich einfacher, taugt aber trotzdem nicht als tragfähiges Argument. In diesem Sinne ist auch eine Feinsäge und ein Stechbeitel einfacher als eine Tischkreissäge samt entsprechendem Zubehör. Aber dieses Zubehör erlaubt es mir, eine verzinkte Verbindung in windeseile perfekt herzustellen. Etwas wozu ich mich Feinsäge und Stechbeitel viel länger brauchen würde und wo ich schon viel Übung benötigen würde, um ein technisch gleichwertiges Ergebnis hinzukriegen. Dazu kommt noch: Beherrsche ich mein Zubehör, dann wird jede Verzinkung perfekt und ich komme jedesmal in den Genuss der Zeitersparnis. Zum Ausgleich kann ich die gesparte Zeit dann an anderer Stelle in meinem Projekt gut gebrauchen, indem ich mir die Anordnung der SChubladen im Schrank dann eben gut überlege und wenn sich rausstellt, dass das alles nicht so schlau war, dann kann ich ganz schnell neue (verzinkte) Schubladen herstellen. Ich kann vielleicht (abhängig von meinem Werkzeug) nicht jedes beliebige Mass in der Verzinkung erreichen - kann aber mit dieser Einschränkung gut leben. Eine andere Analogie wäre für mich Schach: Die möglichen Züge sind so etwas wie Assembler. Einfach, simpel, schnell zu lernen. Aber Schach ist mehr als nur irgendwelche Züge. Natürlich lässt sich ein Damengambit letzten Endes auch nur auf Züge reduzieren. Aber der Sinn der Sache, die Wirkung, erschliesst sich erst, wenn ich von dieser Zugebene weggehe und mir überlege, wie ich mit einer Zugfolge Druck auf meinen Gegner aufbauen kann. Um eine der banannten Zugfolgen wirklich zu verstehen, muss ich die Gesamtheit des Spielbrettes betrachten und wie sich dort die Kräfte verteilen. Mit Einzelzügen hat das nicht mehr viel zu tun.
:
Bearbeitet durch User
Karl H. schrieb: > Eine andere Analogie wäre für mich Schach: > Die möglichen Züge sind so etwas wie Assembler. Der Vergleich mit Schach stellt aber auch schnell die Aussage 'Wenn der Computer(Compiler) besser ist, dann war der Schachspieler(ASM-Programmierer) nicht gut' stark in Frage. Inzwischen ist die Menge der 'guten' Schachspieler ja schon die leere Menge.
Dumdi D. schrieb: > Inzwischen > ist die Menge der 'guten' Schachspieler ja schon die leere Menge. Ich bin gerne bereit zuzugestehen, dass es für praktische Zwecke nicht akzeptabel ist, dass ein Compiler 20 Minuten an der Übersetzung eines moderaten Codes arbeitet. Würde man ihm die Zeit geben, dann würde er auch die perfekte Lösung finden können. Inklusive rumprobieren, welche Variablen er global in welche Register legt, wie er auf einem AVR das T-Bit für Einzelbitflags sinnvoll nutzen kann, wie er die Pipeline aufs Beste befüllt halten kann. etc. Bruth Force vom Feinsten. Da aber Compiler, anders als die 'großen Schachprogramme', kein Prestigeobjekt sind, wird da nicht so viel investiert.
:
Bearbeitet durch User
Dummerweise wächst der Aufwand extrem mit der Länge und ist daher allenfalls für relativ kleine Schleifen noch praktikabel. Für kurze Sequenzen gibt es ein paar Ansätze: https://en.wikipedia.org/wiki/Superoptimization Karl H. schrieb: > Da aber Compiler, anders als die 'großen Schachprogramme', kein > Prestigeobjekt sind Doch, manchmal schon. Es wurden schon Compilerbauer dabei erwischt, dass sie Benchmarkcode identifizierten und durch handoptimierten Code oder Abkürzungen ersetzten.
:
Bearbeitet durch User
Hach, wer hätte das ausgerechnet bei 14-Bit PICs vermutet? "PIC Microcontroller SuperOptimizer The PIC Microcontroller SuperOptimizer is a program that, given a function, tries to find the shortest sequence of microcontroller instructions that implement that function. It tries every sequence of instructions from a restricted set." http://freecode.com/projects/picsuperoprimizer
:
Bearbeitet durch User
Karl H. schrieb: > Können wir gerne machen. > Wir vereinbaren einen Zeitpunkt an dem du und ich Zeit haben. Ein paar > Forneteilnehmer denken sich eine Aufgabe aus, irgendjemand (du, ich, wir > beide) wählt eine der Aufgaben aus und dann schaun wir mal, wer > schneller das Programm stehen hat und wer es fehlerfreier hinkriegt. > > Ich hab nur eine Bedingung: es darf kein Pipifax Beispiel sein sondern > sollte schon was ordentliches sein. Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem Mega2560? :P
Karl H. schrieb: > Da aber Compiler, anders als die 'großen Schachprogramme', kein > Prestigeobjekt sind, wird da nicht so viel investiert. Der Aufwand, die optimale Lösung zu finden, sollte nicht grösser sein als die Differenz zur suboptimalen leicht ermittelbaren Lösung. Das ist wie beim Informatikern wohlbekannten Problem des Handlungsreisenden. Wenn der erst losfährt, nachdem er seine lange Reiseroute voll durchoptimiert hat, kann es sehr gut sein, dass er insgesamt länger braucht als wenn er einfach so frei Nase losgefahren wäre.
:
Bearbeitet durch User
Kaj G. schrieb: > Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem > Mega2560? :P Da muss ich mich erst mal schlau machen, was das überhaupt ist :-)
Karl H. schrieb: > Kaj G. schrieb: > >> Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem >> Mega2560? :P > > Da muss ich mich erst mal schlau machen, was das überhaupt ist :-)
1 | ccTalk (pronounced see-see-talk) is a serial protocol in widespread use |
2 | throughout the money transaction and point-of-sale industry. Peripherals |
3 | such as the currency detectors for coins and banknotes found in a diverse |
4 | range of automatic payment equipment such as transportation, ticketing, |
5 | payphones, amusement machines, and retail cash management use ccTalk to |
6 | talk to the host controller. |
Wie testen wir die Implementierungen?
Karl H. schrieb: > Karl H. schrieb: >> Kaj G. schrieb: >> >>> Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem >>> Mega2560? :P >> >> Da muss ich mich erst mal schlau machen, was das überhaupt ist :-) > ... > Wie testen wir die Implementierungen? Das war ja jetzt erstmal nur ein spontaner Vorschlag von mir, weil ich das in meiner jetzigen Firma schon machen musste. :) Die Implementierung könnte man Testen, in dem Jemand einen Master schreibt, der den Slaves (in einer euch unbekannten reihenfolge) kommandos schickt. Die Reihenfolge muss natürlich für beide Tests gleich sein. Generell müsste man die Aufgabe aber noch etwas spezifizieren. So würde ich zum Beispiel sagen, das es 2 Hopper und 1 Münzprüfer als Slaves sind. Und man müsste nochmal drüber reden ob mit oder ohne Verschlüsselung. Die Spezifikationen zu ccTalk gibt es hier: http://www.cctalk.org/ Auf der rechten Seite: Download Part 1 - 4 Wie gesagt, war jetzt einfach nur ein spontaner Vorschlag :) Das ganze gibt es auch noch mit MDB ( https://de.wikipedia.org/wiki/Multi-Drop_Bus ), davon hab ich aber keine ahnung.
:
Bearbeitet durch User
Könnte man das dann gleich praktisch nutzen? Zb für gratis Bahnfahrten?
Matthias L. schrieb: > Könnte man das dann gleich praktisch nutzen? Zb für gratis Bahnfahrten? Wenn du die Verschlüsselung (wo jeder Hersteller seine eigene haben dürfte, so wie wir) nachbauen/knacken kannst, klar :)
Kaj G. schrieb: > Wenn du die Verschlüsselung (wo jeder Hersteller seine eigene haben > dürfte, so wie wir) nachbauen/knacken kannst, klar :) Nicht ist so verlässlich unsicher, wie selbstgebaute Verschlüsselung. ;-)
A. K. schrieb: > Nicht ist so verlässlich unsicher, wie selbstgebaute Verschlüsselung. Stimmt schon, aber lass dir gesagt sein: Wenn man es wie wir mit organisierter Kriminalität zu tun hat, steckt da sehr viel Zeit, Geld, und auch entsprechende versuche (von sehr kreativen/kompetenten leuten), das ding zu knacken, drin ;) Oder anders gesagt: Selbst wenn du den Algorithmus kennst, kannst du die Verschlüsselung nicht brechen ;) Also "können" schon, dafür muss man dann aber unverhältnis mäßig viel aufwand treiben.
:
Bearbeitet durch User
So, mal zurück zum Thema: Kaj G. schrieb: > Die Implementierung könnte man Testen, in dem Jemand einen Master > schreibt, Das reicht aber nicht, denn wirklich interessant wird es erst, wenn jemand "das Gerät bedient", also z.B. "Geld einwirft und ausgezahlt haben möchte". Geld einwurf könnte man z.B. durch Taster simulieren (10, 20, 50 cent, 1 und 2 euro, je münze ein taster). Ich denke mögliche Aufgaben gibt es genug. Nur wie wird das ganze dann nachher effektiv verglichen, und was ist wann besser? Geht es nur um den Asm-Code, oder auch sachen wie "Lesbarkeit"? geht es um die laufzeit? Was genau will man nachher wie vergleichen? Und wer beurteilt am Ende, was jetzt "besser" ist? Oder geht es nur um "selbstgeschriebenen Asm" vs. "vom Compiler erzeugten Asm"? (Ja ich geb zu, ich hab irgendwo nach 150 Beiträgen auf gehört zu lesen und hab erst jetzt wieder angefangen)
Frank M. schrieb: > Diese Aufgabe halte ich für sinnvoller, da die Lösung nachher nicht für > die Tonne ist, sondern durchaus für das eine oder andere Projekt > verwendet werden kann :-) Sorry, Kay, aber Franks "Anforderung" bezüglich Wiederverwenbarkeit hat was! ;-)
> Ich würde dann aber an deiner Stelle auch am Terminal zweifeln. Zeig mir mal, an
welcher Stelle deines 8-Bit Zeichensatzes Symbole wie ⍳, ⌹ oder ⍴ zu finden sind.
;-)
Es gab zu APL auch spezielle Schablonen, die man auf
MainFrameTerminalTastaturen legte, damit man auch eintippen konte, was
auf dem Display zu sehen war. Das Terminal war dabei im APL-Mode. APL
hab ich zwar nie benutzt, aber an diese komischen Schablonen kann ich
mich erinnern.
Konrad S. schrieb: > Sorry, Kay, aber Franks "Anforderung" bezüglich Wiederverwenbarkeit hat > was! ;-) Ist ja völlig legitim. Ich hatte ja einfach nur was in den Raum/Chat geworfen :-)
Kaj G. schrieb: > Geht es nur um den Asm-Code, oder auch sachen wie "Lesbarkeit"? geht es > um die laufzeit? Zuallererst geht es um die Funktionsfähigkeit. Und zwar fehlerfrei :-) Laufzeit ist ein natürlich ein Thema. Da kann sich Moby was aussuchen. Zeitbedarf in der Erstellung ist ebenfalls ein Thema. Speziell wo doch Moby eh so wenig Zeit für sein Familie hat (Sorry, could not resist) > Was genau will man nachher wie vergleichen? Und wer beurteilt am Ende, > was jetzt "besser" ist? Da hätt ich einen fiesen Ansatz :-) Jeder von uns beiden baut einen Fehler in seine Version ein. Und dann schaun wir mal, welche Fraktion (Assembler oder C) den Fehler schneller findet. :-) Aber kein Sorge. Wenn die Dinge so laufen, wie sie eigentlich immer laufen, wird es nie zu so einem Wettstreit kommen. Ich bin übrigens das Wochenende über unterwegs. Daher nicht wundern, wenn ich (falls doch etwas zu stande kommt), nicht zeitnah antworte. > Oder geht es nur um "selbstgeschriebenen Asm" vs. "vom Compiler > erzeugten Asm"? Es geht darum, die vollmundigen Aussagen endlich mal auf einen Prüfstand zu stellen. Und zwar mit ein bischen mehr als Micky Mouse "Wenn Taster gedrückt, dann LED ein" Programmen (oder Variationen davon). Da Moby kein Profi ist, gestehe ich ihm eine Beschränkung der Komplexität der Aufgabenstellung zu. Aber auch nicht zu trivial.
:
Bearbeitet durch User
Frank M. schrieb: > 8-Kanal Software-UART (nur Eingänge), um 8 verschiedene LEDs mit SW-PWM > zu steuern Oh die Idee klingt gut. Ein Programmierkontest :-) Aber ich steige jetzt schon aus wenn Johann mitmacht. Ich kenne den Source seiner Scopeuhr ;-)
:
Bearbeitet durch User
Karl H. schrieb: > Da Moby kein Profi ist, Also wenn ich die erste Seite dieses Threads richtig verstehe, macht Moby seit 18 Jahren Asm, da sollte man doch schon zu den "Profis" zählen, oder? :)
Kaj G. schrieb: > Karl H. schrieb: >> Da Moby kein Profi ist, > Also wenn ich die erste Seite dieses Threads richtig verstehe, macht > Moby seit 18 Jahren Asm, da sollte man doch schon zu den "Profis" > zählen, oder? :) Hätte ich auch gesagt. Aber auf der anderen Seite wenn ihn ein 32 Bit Vergleich schon vor so unübeerwindliche Hürden stellt. (Den Fehler im ADC Beispiel seh ich so wie er nicht als verzeihlichen Flüchtigkeitsfehler an, sondern der ist schon massiv mittelprächtig schwer und genau von der Sort, vor denen wir Asm-Programmierer immer warnen: du musst dir bei einer Änderung ALLES ansehen. Und ALLES meint auch wirklich alles. Du musst dich um jeden Kleinscheiss selber kümmern: Adressierung, Flags, Registerbenutzung. So gesehen wäre genau dieser Fehler das beste Argument, warum ein Compiler sinnvoll ist. Aber seis drum. Wir alle machen mal Fehler das man sich hinterher nur noch auf den Kopf greift und fragt: Wie konnte das passieren?)
:
Bearbeitet durch User
Moby A. schrieb: > Das Angebot zum kürzeren Formulieren der beschriebenen > Funktionalität in C steht nach wie vor... Dabei muß man > sich auch nicht an meiner Programmlogik orientieren. Du schreibst, du willst den optimalen Code? Warum sparst zu dann auf Teufel-komm-raus 1, 2 läppische Instruktionen anstatt SCHNELLEN Code zu schreiben? Z.B dein Code für den LM335: o Ob der der 2 Byte kürzer oder länger ist, ist sooo egal, egaler geht's nicht. o Der Code läuft in einer ISR. Warum machst du den Code extra lahm, obwohl er in einer ISR laufen soll??? Es ist doch total hirnrissig, paar Bytes zu sparen wenn der Code schnell sein soll! Fangen wir mal mit der Erbsenzählerei an: o RCALL, RET und dein arschlahmer Rechtsschift kosten 2 + 5 = 7 Instruktionen. o Ohne große Verrenkungen macht man den 16-Bit Rechtsshift in 9 Instruktionen OGOTTOGOTT 9 INSTRUKTIONEN HÖLLE!!! o Zieh die 7 Instruktionen für CALL + RET + Schnach-Schift ab, und es bleiben 2 Mehrinstruktionen. o Wenn der Code eh in der ISR laufen soll, wozu dann CALL und RET? Sind doch unnötig wien Kropf! Und jetzte schaust du NICHT auf deinen Codelängenfetisch, sondern schaust dir mal eine SIMULATION an und hälst die SIMULIERTEN BEFEHLE nebeneinander! DAS ist nähmlich, was hier zählt. > 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke. Das ist doch Käse. Assembler ist ein exzellentes Einsatzgebiet für Arithmetik. Und wenn ich solchen Assembler schreibe, dann fuchse ich auch um jedes Byte und jeden Tick. Aber der Code landet dann auch nicht in der Tonne, sondern wird von Tausenden von Compiler-Anwendern eingesetzt.
900ss D. schrieb: > Aber ich steige jetzt schon aus wenn Johann mitmacht. > Ich kenne den Source seiner Scopeuhr ;-) Ja, die Scope-Uhr; Morpheus und Rudi. Ist momentan eingemottet, was aber nicht an Morpheus liegt ("Morpheus" is der Projektname der Software), sondern an Rudi ("Rudi" ist der Projektname für die Handware). Es gab sogar schon Interesse die Uhr zu vermarkten, aber dazu müsste es eine vermarktbare Hardware geben, und mit dem Zeug kenn ich mich nicht aus. Um das professionell und verkaufbar zu machen müsste jemand vom Fach her... Übrigens hab ich "Morpheus" als Name für die Software gewählt, weil ich Gimmiks wie folgendes implementieren wollte: Beitrag "Re: Wie Parametrisierung für Kurve finden?" https://www.mikrocontroller.net/attachment/52470/A-ani.gif https://www.mikrocontroller.net/attachment/52552/AB-ani.gif
Moby A. schrieb: > Das Angebot zum kürzeren Formulieren der beschriebenen Funktionalität > in C steht nach wie vor... Dabei muß man sich auch nicht an meiner > Programmlogik orientieren. "Angebot" angenommen ;-) Es geht doch um deinen Assemblercode in diesem Beitrag: Moby A. schrieb: > Hab mal meine bereits weiter oben zur Sprache gekommene ASM Lösung aus > einem anderen Hochsprachen-Thread(problem) angehängt. Im Anhang findest du den entsprechenden C-Code, der bis auf ein paar Kleinigkeiten die gleiche Funktion wie dein Assemblercode hat. Die Unterschiede: - Die Anzahl der zu verarbeitenden Tasten ist statt auf 8 nur durch die Anzahl der verfügbaren Portpins limitiert. Für jede Taste wird ein zusätzliches RAM-Byte benötigt, dafür bleibt aber das GPIOR0-Register frei. Für die Erweiterung auf mehr als 3 Tasten müssen nur das Makro KEYS auf den entsprechenden Wert gesetzt und zusätzliche Aufrufe von debounce in der Funktion processAllKeys hinzugefügt werden. - Die Anzahl der Abtastwerte lässt sich mit dem Makro DEBOUNCE_SAMPLES leicht ändern. Insbesondere sind auch Werte größer als 8 möglich (für besonders stark prellende Taster). - Es wird nicht nur die Dauer des Tastendrucks, sondern auch die des Loslassens gemessen. Dieses Feature braucht man zwar eher selten, aber wenn doch, dann ist es bereits da und muss nicht mehr implementiert werden. - Die Funktion debounce wird wie bei dir die Routine keyproc für jede Taste aufgerufen, allerdings ist die Aufrufreihenfolge von debounce unwichtig. So kann bspw. die Auswertung einzelner Tasten ausgelassen werden, wenn diese in einer bestimmten Situation gar nicht aktiv sein müssen, was dann etwas CPU-Zeit spart. - In deinem Code muss man bei der Erweiterung der Aktionsroutinen (key<i>pressed und key<i>released) darauf achten, dass darin die Register R27 (XH), R30 (ZL) und R31 (ZH) nicht versehentlich überschrieben werden, da in diesen Informationen zwischen zwei Aufrufen von keyproc aufgehoben werden. Das wird – wie schon beim Carry-Flag geschehen – ganz sicher zur Falle, wenn du deinen Code nach ein paar Monaten wieder herauskramst, um ihn zu erweitern ;-) Beim C-Code besteht diese Gefahr nicht. - Die Entprellung der Tasten und die Ausführung der davon abhängigen Aktionen (key<i>Pressed und key<i>Released) erfolgt bei mir nicht in der Interruptroutine, sondern in der Hauptschleife des Programms (aber trotzdem interruptgetriggert). Dadurch werden – insbesondere bei etwas aufwendigeren Aktionen – weitere Interrupts, die vielleich später hinzukommen – nicht unnötig blockiert. - Zudem erlaubt es diese Ablaufstruktur der CPU, sich während des Nichtstuns zwischen zwei Timer-Interrupts schlafen zu legen und damit Strom zu sparen. Die Entprellroutine ist ganz klassisch, ohne jegliche Tricks und damit für jeden C-Programmierer (hoffentlich) leicht nachvollziehbar mit zwei Zählern (für die eigentliche Entprellung die Gedrücktzeitmessung) realisiert. Man könnte den Code mit Kniffen wie den vertikalen Zählern in Peter Danneggers Routine sicher noch straffen. Peters Routine ließe sich auch relativ problemlos auch auf 8 Abtastwerte erweitern. Allerdings wäre der Code dann nicht mehr so klar verständlich und man müsste Einschränkungen bzgl. der Erweiterbarkeit in Kauf nehmen (maximal 8 Tasten, die alle an denselben I/O-Port angeschlossen sein müssen). Trotz der höheren Flexibilität und der für die meisten sicher leichter verständlichen Programmlogik kann der C-Code größenmäßig gut mit deinem Assemblercode mithalten:
1 | Mobys Asm-Code Yalus C-Code |
2 | ————————————————————————————————————————————————— |
3 | Flash-Verbrauch 266 256 |
4 | RAM-Verbrauch¹ 6 + 1 GPIOR 9 |
5 | Stack-Verbrauch 2 4 |
6 | Quellcodezeilen² 143 91 |
7 | Quellcodezeichen³ 1614 1707 |
8 | ————————————————————————————————————————————————— |
9 | ¹) ohne Stack |
10 | ²) ohne Leer- und Kommentarzeilen |
11 | ³) ohne Kommentare, Leerraum und Zeilenvorschübe |
12 | |
13 | Compiler: GCC 4.7.4 |
14 | Assembler/Linker: Binutils 2.25.1 |
15 | C-Standardbibliothek: AVR-Libc 1.8.1 |
Die 26 Interruptvektoren und die Routine zur Initialisierung des genutzten RAM-Bereichs mit Nullen sind übrigens in den 256 Flash-Bytes enthalten, auch wenn sie nicht explizit im C-Quellcode auftauchen. Da übernimmt die C-Toolchain also netterweise eine weitere lästige Aufgabe. Die versteckte Startroutine initialisiert übrigens auch den Stackpointer und das Statusrgister, was beim ATmega88 nicht unbedingt erforderlich ist. Eine dahingehend optimierte Startroutine würde noch einmal 10 Bytes sparen. Wenn man die Startroutine aber sowieso anpasst, könnte man bei dieser Gelegenheit gleich noch den Aufruf des nie endenen Hauptprogramms optimieren, was weitere 6 Bytes Flash und 2 Bytes Stack spart. Damit läge der Flash-Verbrauch mit 240 Bytes fast 10% unter dem deines Assemblerprogramms. Die Quellcodegröße in Zeichen ist beim C-Code immerhin knapp 6% größer als beim Assemblercode. Mit kürzeren Variablennamen, die dann ähnlich nichtssagend wären wie die Registernamen R18, XL, ZH usw. n deinem Assemblerprogramm könnte auch dieses Manko behoben werden, aber das lasse ich besser bleiben ;-) Abschließende Anmerkungen: Den C-Code habe ich mangels einer Schaltung mit dem ATmega88, den Tastern und den LEDs nicht auf dem Zielsystem laufen lassen. Allerdings habe ich die Funktion debounce mit simulierten Eingaben auf dem PC getestet, so dass ich mit ziemlich sicher bin, dass diese Funktion korrekt ist. Eventuelle Fehler in anderen Programmteilen (Tasten lesen, Ergebnis von debounce abfragen, LEDs schalten usw.) sollten mit minimalen Änderungen und ohne Erhöhung des Flash- und RAM-Verbrauchs korrigiert werden können. Die Initialisierung des Timers habe ich ohne Prüfung von Mobys Code übernommen in der Hoffnung, dass sie fehlerfrei ist.
:
Bearbeitet durch Moderator
900ss D. schrieb: > wenn Johann mitmacht. Ich kenne den Source seiner Scopeuhr ;-) Weiter geht's da: Beitrag "Morpheus + Rudi"
Yalu X. schrieb: > "Angebot" angenommen ;-) Gut gemacht :-) Bin mal gespannt wie groß der Moby's Assemblercode denn wird wenn er all deine Features auch noch implementiert
Kommt, die Sache ist doch schon erledigt. Laut Moby: Moby A. schrieb: > Horst S. schrieb: >> Moby schrieb: >> Asm allein ist nun >> leider keine Garantie für guten Code, wie man beim TO-Programm schön >> sehen kann ;-) >> >> Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so >> vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne >> großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru, >> aber einfach abfrühstücken lasse ich mich auch nicht von Dir. >> >> Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung. > > Die Entschuldigung kannst Du Dir sparen. > Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das > jedenfalls nicht für Deinen Asm-Code. Da sich sein Asm-Code auch mit C locker unterbieten lässt, kann er selber laut seiner Argumentation keinen guten Code schreiben.