Forum: Offtopic C versus Assembler->Performance


von Ralf G. (ralg)


Lesenswert?

900ss D. schrieb:
> Danke.

Mach' einen Smiley dahinter. Er denkt noch, du meinst das ernst.

von Rea L. (realist)


Lesenswert?

Johann L. schrieb:
> avr-gcc: Braucht 40 Instruktionen für "adu", davon sind 5 32-Bit
> Instruktionen.
Bei welcher Optimierungsstufe?

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Ralf G. (ralg)


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

Moby A. schrieb:
> An dieser kryptischen Darstellung würd ich auch verzweifeln

Hatte gerade einen kleinen Brown-Out.

von (prx) A. K. (prx)


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

Moby A. schrieb:
> Gleiche Rechenorgie.

Ergänzung: Streng geheim!!

Ich kann nicht mehr. Ich bin weg. :-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

Besser Du verschwindest nun wirklich ;-)
Lerne C.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

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.)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Ralf G. (ralg)


Lesenswert?

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...)

von (prx) A. K. (prx)


Lesenswert?

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
von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Unbekannt U. (Gast)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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?

von Josef G. (bome) Benutzerseite


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von (prx) A. K. (prx)


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

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. ;-)

von (prx) A. K. (prx)


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
von Ralf G. (ralg)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von 900ss (900ss)


Lesenswert?

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?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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 :(

von Ralf G. (ralg)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Ralf G. (ralg)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

von Walter T. (nicolas)


Lesenswert?

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.

von Ralf G. (ralg)


Lesenswert?

A. K. schrieb:
> Nö. Ein Aphorismus ist
Johann L. schrieb:
> Nö, aber

Ich hätte wohl doch ein
1
;-)
hinmachen sollen?

von Ralf G. (ralg)


Lesenswert?

Walter T. schrieb:
> B-Forismen

Ich hätt's beinahe gegoogelt :-)

von 900ss (900ss)


Lesenswert?

Johann L. schrieb:
> Oder so: einfach genialst!
>
> Youtube-Video "Stoiber On Drums - Jonny König"

Sehr schön :-)

von Walter T. (nicolas)


Lesenswert?

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.

:-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
}

von Ralf G. (ralg)


Lesenswert?

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.

;-)

von Carl D. (jcw2)


Lesenswert?

> 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.

von Horst S. (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von 900ss (900ss)


Lesenswert?

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 ;-)

von (prx) A. K. (prx)


Lesenswert?

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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

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)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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
von Matthias L. (Gast)


Lesenswert?

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...

von Klaus W. (mfgkw)


Lesenswert?

Ist doch offensichtlich ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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
von Konrad S. (maybee)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Matthias L. (Gast)


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Matthias L. (Gast)


Lesenswert?

>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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
von Horst S. (Gast)


Lesenswert?

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.

von Carl D. (jcw2)


Lesenswert?

> 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
von Matthias L. (Gast)


Lesenswert?

>Das hatte eine Schweizer Firma

Ferag AG?

von Peter D. (peda)


Lesenswert?

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
von Carl D. (jcw2)


Lesenswert?

>Das hatte eine Schweizer Firma

Ferag AG?


Bobster, oder so. Das ist über 30 Jahre her!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
von Carl D. (jcw2)


Lesenswert?

>Das hatte eine Schweizer Firma

Ferag AG?

Gerade mal Google befragt:

Bobst, machen heute in Verpackungsmaschinen und nicht mehr in 
Druckmaschinenausrüstung.

von Horst S. (Gast)


Lesenswert?

Verdammt, wo soll ich denn dann mit meinen 8GB Ram und 1,3MHz hin? Nur 
Fickelfilme gucken?

von (prx) A. K. (prx)


Lesenswert?

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
von Carl D. (jcw2)


Lesenswert?

8Gb-RAM und nur 1,3MHz, da kann booten von Windows etwas dauern ;-)

von Matthias L. (Gast)


Lesenswert?

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...

von Horst S. (Gast)


Lesenswert?

Carl D. schrieb:
> 8Gb-RAM und nur 1,3MHz, da kann booten von Windows etwas dauern
> ;-)

Ich boote nicht, ich standbye. (Is'n Notebook.)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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...

von Ralf G. (ralg)


Lesenswert?

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? ;-(

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

Ich verweise auf die Universalantworten, auch zu diesem Thema

Beitrag "Re: 8bit-Computing mit FPGA"

Beitrag "Re: 8bit-Computing mit FPGA"

'Nuff said

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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!

von Ralf G. (ralg)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

Wie wärs Moby, könntest du deine Variante noch auf 32 Bits mit 
Vorzeichen ausdehnen?

von Ralf G. (ralg)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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. :-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Carl D. (jcw2)


Lesenswert?

>  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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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?

von Carl D. (jcw2)


Lesenswert?

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?

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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".

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Sheeva P. (sheevaplug)


Lesenswert?

Moby A. schrieb:
> Asm-Code ist selbsterklärend.

Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei 
einem "selbsterklärenden Code" passieren?

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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?

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

Moby A. schrieb:
> Asm-Code ist selbsterklärend.

So wie Josefs Krypto-Asm. Zusammen wärt ihr unschlagbar. ;-)

von Rea L. (realist)


Lesenswert?

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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?

von Icke ®. (49636b65)


Lesenswert?

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...

von Walter T. (nicolas)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Falk B. (falk)


Lesenswert?

@ 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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Matthias L. (Gast)


Lesenswert?

>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.

von Falk B. (falk)


Lesenswert?

@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!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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. :-))

von Karl H. (kbuchegg)


Lesenswert?

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
von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
von Falk B. (falk)


Lesenswert?

@ 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!

von Icke ®. (49636b65)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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"

von Horst S. (Gast)


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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!

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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".

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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 ;-)

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

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
von Klaus W. (mfgkw)


Lesenswert?

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.

von Ralf G. (ralg)


Lesenswert?

Na, Moby! Heute wieder nur Geisterfahrer unterwegs, was?

von (prx) A. K. (prx)


Lesenswert?

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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Carl D. (jcw2)


Lesenswert?

> 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)

von (prx) A. K. (prx)


Lesenswert?

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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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/ :)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

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
von Matthias L. (Gast)


Lesenswert?

Wie heisst es schön:

Wir leben zwar alle unter dem gleichen Himmel, haben aber nicht alle 
denselben Horizont.

von Karl H. (kbuchegg)


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

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
von Matthias L. (Gast)


Lesenswert?

> 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.

von (prx) A. K. (prx)


Lesenswert?

Also wenn ihr das wirklich ernst meint, dann nehmt ein Beispiel, das im 
Simulator gut getestet werden kann.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Sheeva P. (sheevaplug)


Lesenswert?

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ß.

von (prx) A. K. (prx)


Lesenswert?

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
von Sheeva P. (sheevaplug)


Lesenswert?

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.

von Dumdi D. (dumdidum)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
von Karl H. (kbuchegg)


Lesenswert?

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
von Dumdi D. (dumdidum)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?

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
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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
von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Karl H. (kbuchegg)


Lesenswert?

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?

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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
von Matthias L. (Gast)


Lesenswert?

Könnte man das dann gleich praktisch nutzen? Zb für gratis Bahnfahrten?

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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 :)

von (prx) A. K. (prx)


Lesenswert?

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. 
;-)

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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)

von Konrad S. (maybee)


Lesenswert?

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! ;-)

von Carl D. (jcw2)


Lesenswert?

> 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.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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 :-)

von Karl H. (kbuchegg)


Lesenswert?

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
von 900ss (900ss)


Lesenswert?

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
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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? :)

von Karl H. (kbuchegg)


Lesenswert?

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
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

von Yalu X. (yalu) (Moderator)


Angehängte Dateien:

Lesenswert?

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
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

900ss D. schrieb:
> wenn Johann mitmacht. Ich kenne den Source seiner Scopeuhr ;-)

Weiter geht's da:

Beitrag "Morpheus + Rudi"

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

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

von Dumdi D. (dumdidum)


Lesenswert?

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.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.