Hallihallo,
folgende Sachlage: Ich habe ein Programmchen für einen ATMega168 zuerst
auf Assemblerbasis erstellt und anschließend auf gcc portiert. Das
funktioniert auch alles (zumindest nicht schlechter als in Assembler),
was mich aber zur Zeit etwas die Augenbrauen hochziehen lässt:
Warum benötige ich im Assembler-Projekt "nur" 2910 Bytes, in C aber
"satte" 3278 Bytes?
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?
Was ich bisher gemacht habe:
- Ich habe mal alle Optimierungen durchprobiert. Die 3278 Bytes sind das
Beste, was ich mit meinem AVRStudio 4.10 herauskitzeln kann.
- Ich hab mir die eingebundenen Header mal angeschaut. Dabei habe ich
viele #defines, aber kein Grund für das absonderliche Wachstum gefunden.
Ich häng mal die Projekte als Zip an.
Zur Info:
- Die Projekte kommunizieren über zwei PortPins per PS/2 mit einem
Maussensor (SPCP168A). Empfangene Werte werden in DataRead.MouseBuffer
geschrieben. Der Wert von DataWrite.MouseCommand wird über PS/2 an den
Sensor übergeben.
DataRead und DataWrite werden mit einem PC über UART ausgetauscht. Zum
Austausch von Datenblöcken habe ich in UARTTelegramm.c für das C-Projekt
und rs232Telegram.asm für das Assemblerprojekt ein unverfängliches
Protokoll aufgesetzt. (Der PC liest zuerst die implementierte
Peripherie-Tabelle, um die Adressen der Datenblöcke zu lesen.
Anschließend kann er direkt auf Datenblöcke (hier DataRead und
DataWrite) über die vier implementierten Read-/Write-/-Device/-Mem
zugreifen.
Prinzipiell funktionieren sowohl der PS/2- als auch das UART-Protokoll
als Statemachines über Funktionspointer. In Assembler regeln das im
wesentlichen die Macros "PrepareJump" und "Jump".
Etwas Eigenartig vielleicht für den Außenstehenden das Mapping der
Register r16..r23 auf d0..d7 im Assembler(ich war mal
68000er-Fetischist).
Vielleicht fällt Euch ja ein, was ich in C noch optimieren könnte.
(und reißt mir nicht den Kopf ab, das ist mein Erstlingswerk mit gcc).
@ Horst S. (hdc)
>was mich aber zur Zeit etwas die Augenbrauen hochziehen lässt:>Warum benötige ich im Assembler-Projekt "nur" 2910 Bytes, in C aber>"satte" 3278 Bytes?
Wen interessieren diese läppischen 10% im Jahr 2015, wo selbst 32 Bit
CPUs für wenige Euros verkauft werden?
>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?
Nö, es ist erstmal nur 10% größer. Ob es auch 10% langsamer ist, ist
damit noch lange nicht gesagt. Du kämpfst gegen Windmühlen.
https://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Prinzipien_der_Optimierung
kannst man das nicht eine packen und mitgeben welches Byte man haben
will?
1
voidPS2ReceiveBit0();
2
voidPS2ReceiveBit1();
3
voidPS2ReceiveBit2();
4
voidPS2ReceiveBit3();
5
voidPS2ReceiveBit4();
6
voidPS2ReceiveBit5();
7
voidPS2ReceiveBit6();
8
voidPS2ReceiveBit7();
auch das sollte sich doch wohl über eine Funktion abbilden lassen.
Auch kommt mir volatile viel zu oft vor. sicher das die ganzen Variablen
in einer ISR und dem Hauptprogramm verwendet werden?
1
voidSetLED1()
2
{
3
asm("sbi _SFR_IO_ADDR(PORTB), LED1""\t\n");
4
//asm ("sbi PORTB, LED1" "\t\n");
5
}
warum hier noch asm? Das sollte sich mit Makros ohne Funktion machen
lassen.
1
for(inti=0;i<=255;i++)
2
DataRead.MouseBuffer[i]=0;
konstanten im code sind böse, was ist wenn die größe vom Puffer sich mal
ändert?
Peter II schrieb:> auch das sollte sich doch wohl über eine Funktion abbilden lassen.>> Auch kommt mir volatile viel zu oft vor. sicher das die ganzen Variablen> in einer ISR und dem Hauptprogramm verwendet werden?
Ich hab's so 1:1 aus Assembler umgesetzt. Wie gesagt, der
Funktionpointer wird aus der letzten aufgerufenen Funktion für den
nächsten Interrupt umgesetzt. Das war in Assembler eine super Sache, da
ich keinen Schleifenzähler zwischen den Interrupts puffern musste.
Wenn ich's ändere, wird der C-Code zwar kleiner, die Vergleichbarkeit
zum Assembler ist allerdings dann wech.
Die volatile-Variablen puffern Zustände für folgende ISR-Aufrufe. Wenn
ein Datenblock über WriteDevice beschrieben wird, bemisst das Protokoll
z.B. über den Zähler RxDDataLength, wann der PC fertig ist und wann das
Quittierungstelegramm zu starten ist.
Peter II schrieb:> konstanten im code sind böse, was ist wenn die größe vom Puffer sich mal> ändert?> memset( &DataRead, 0, sizeof(DataRead) );> würde ich hier vorschlagen.
guter Plan, das!
Peter II schrieb:> warum hier noch asm? Das sollte sich mit Makros ohne Funktion machen> lassen.
Das ist allerdings auch noch eine offene Frage für mich: Wie ist die
Umsetzung des sbi/cbi-Befehls in C?
Ist ein "PORTB |= 0x01" wirklich dann ein "sbi PORTB, 1"?
Oder baut mir der Compiler daraus ein:
in r16, PORTB
ori r16, 0x01
out PORPB, r16
Das wäre mir unangenehm!
Horst S. schrieb:> Ich hab's so 1:1 aus Assembler umgesetzt. Wie gesagt, der> Funktionpointer wird aus der letzten aufgerufenen Funktion für den> nächsten Interrupt umgesetzt. Das war in Assembler eine super Sache, da> ich keinen Schleifenzähler zwischen den Interrupts puffern musste.> Wenn ich's ändere, wird der C-Code zwar kleiner, die Vergleichbarkeit> zum Assembler ist allerdings dann wech.
macht für mich wenig sinn. C schreibt man um sich weniger arbeit zu
machen. Da überlässt man einige Details dem Compiler. So wie du es
gemacht hast, verhinderst du zum teil Optimierungen.
> Die volatile-Variablen puffern Zustände für folgende ISR-Aufrufe. Wenn> ein Datenblock über WriteDevice beschrieben wird, bemisst das Protokoll> z.B. über den Zähler RxDDataLength, wann der PC fertig ist und wann das> Quittierungstelegramm zu starten ist.
wenn sie NUR in der ISR genutzt werden, braucht man kein volatile.
> Das ist allerdings auch noch eine offene Frage für mich: Wie ist die> Umsetzung des sbi/cbi-Befehls in C?> Ist ein "PORTB |= 0x01" wirklich dann ein "sbi PORTB, 1"?
ja, zur Sicherheit schaut man einfach mal in den ASM code.
Das "PS2.c" ist aber wirklich von hinten durch die Brust ins Auge.
Funktionspointer sind da viel zu umständlich.
Alle Bit0..7-Funktionen machen doch dasselbe. Also wäre es viel
bequemer, eine Zählvariable zu benutzen, wann ein Byte um ist. Nimm
einfach ein switch/case, das ist dann auch viel besser lesbar.
Tom schrieb:> Weil die LED dann 1µs später angeht?
Eher, weil aus dem Vordergrund aufgerufen, ein zwischendurch im
Interrupt umgesetzter Pin auf dem gleichen Port im Zweifelsfall wieder
zurückgesetzt wird?
Peter II schrieb:> wenn sie NUR in der ISR genutzt werden, braucht man kein volatile.
Oh, ich seh's:
Umdeklariert zu static, kompiliert und siehe da, 3210 Bytes.
Nicht schlecht.
Nach Einfügen der String.h und dem MemSet-Aufruf wieder 3220 Bytes, aber
so viel Komfort muss wohl sein.
Horst S. schrieb:> Ist ein "PORTB |= 0x01" wirklich dann ein "sbi PORTB, 1"?
Nein, glücklicherweise nicht. Daraus wird
sbi PORTB, 0
Vorausgesetzt der PORT ist bitadressierbar. Andernfalls geht es in
Assembler auch nicht.
Falk B. schrieb:> Wen interessieren diese läppischen 10% im Jahr 2015
Interessant und gefragt war woher diese 10% stammen.
> wo selbst 32 Bit CPUs für wenige Euros verkauft werden?
Wen interessiert das wenn ein Easy AVR und kein 32-Bit Monstrum
Verwendung finden soll
Horst S. schrieb:> Warum benötige ich im Assembler-Projekt "nur" 2910 Bytes, in C aber> "satte" 3278 Bytes?
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.
Peter II schrieb:> So wie du es gemacht hast, verhinderst du zum teil Optimierungen.
Rücksichtnahmen, die sich mit Asm generell erübrigen.
Moby du hast keine Ahnung also lass gut sein!
Horst S. schrieb:> Peter II schrieb:>> auch das sollte sich doch wohl über eine Funktion abbilden lassen.>>>> Auch kommt mir volatile viel zu oft vor. sicher das die ganzen Variablen>> in einer ISR und dem Hauptprogramm verwendet werden?>> Ich hab's so 1:1 aus Assembler umgesetzt. Wie gesagt, der> Funktionpointer wird aus der letzten aufgerufenen Funktion für den> nächsten Interrupt umgesetzt. Das war in Assembler eine super Sache, da> ich keinen Schleifenzähler zwischen den Interrupts puffern musste.> Wenn ich's ändere, wird der C-Code zwar kleiner, die Vergleichbarkeit> zum Assembler ist allerdings dann wech.
Naja so must du einen Funktionspointer "puffern"
Mach doch einen static oder einen globalen counter, dann brauchst du
garnix puffern...
Damit sparst du dir dann nebenbei auch 1 byte ram weil aus dem 16-bit
pointer ein 8bit int wird :)
Wenn du nur 1:1 "übersetztst", dann wird C niemal kleiner als dein ASM
code werden.
Wenn du den compiler machen lasst und sauberen code schreibst, dann
sollte der compiler schon noch was rausholen.
73
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 :-)
Sebastian V. schrieb:> War ja nur eine Frage der Zeit bis Moby hier auftaucht... Jegliche> Argumente für Hochsprachen sind damit hinfällig.
Solche Untersuchungen sollte es hier noch viel häufiger geben, bis allen
Beteiligten die immergleichen Ergebnisse in Fleisch und Blut
übergegangen sind ;-)
müssen alle Register auf dem Stack gesichert werden, das man schon ein
paar Byte + performace aus. Da ist es viel sinnvoll darin auch gleich
den code auszuführen.
Horst S. schrieb:> Ich hab's so 1:1 aus Assembler umgesetzt. Wie gesagt, der> Funktionpointer wird aus der letzten aufgerufenen Funktion für den> nächsten Interrupt umgesetzt.
In Assembler kannst Du Dir Register reservieren, das ist in C tabu.
D.h. der Compiler spart für Funktionspointer in Interrupts nichts,
sondern das Gegenteil ist der Fall.
Obendrein weiß er nicht, was Du damit aufrufst, muß also alle
zerstörbaren Register sichern.
Hast Du Dir mal im Assemblerlisting angesehen, was für ein riesen Bohei
da generiert wird.
Und dazu noch der Mehrverbauch für 8 einzelne Funtionen statt für 0.
Naja lieber moby, ein geübter Hochsprachenprogrammierer wird versuchen
möglichst wenig code zu kopieren.
Daher wäre in dem Fall eine Zählervariable und keine Funktionspointer
die folge gewesen was schonmal 1 Byte weniger Ram bedeutet hätte.
Ganz nebenbei würde es auch kein copy-paste in den PS2 Files geben und
das würde nochmal einiges bringen (was oben ja schon steht).
73
Peter II schrieb:> Wegen deinem Aufruf in ISR(PCINT1_vect)> PS2JumpAddress();>> müssen alle Register auf dem Stack gesichert werden, das man schon ein> paar Byte + performace aus. Da ist es viel sinnvoll darin auch gleich> den code auszuführen.
Oh mann, ich seh's: Da ist das Assembler-Konzept nu' wirklich schlecht
übertragbar (obwohl ich auch im Assembler-Projekt nicht immer mit
Register--Pushen und -Poppen gegeizt habe).
- Was ich noch finde: Der Optimizer kotzt mir immer wieder in der
lss-Datei Fragmente der TxDSendByte-Routine vor die Füße. Mag der keine
call-Befehle?
Horst S. schrieb:> Was ich noch finde: Der Optimizer kotzt mir immer wieder in der> lss-Datei Fragmente der TxDSendByte-Routine vor die Füße. Mag der keine> call-Befehle?
vermutlich macht er den code inline, damit ist es etwas unüberschaubar.
gehe erst mal davon aus, das er es richtig macht.
Einzig interessant noch, wie lange der Code jetzt in der ISR "steht".
Zumindest bin ich jetzt im Verbrauch des Speichers mit 2648 Bytes klar
unterhalb der Assemblerversion.
Eigentich müsste der Compiler die beiden Funktionen automatisch inlinen.
Beim Switch/Case müsstest du im listing schaun was der compiler daraus
macht. Teilweise ist ein if-else-if kleiner... das hängt aber von der
architekur und dem jeweiligen anwendungsfall ab.
73
Oberflächlich mit dem Oszilloskop betrachtet (Messung der Länge von
PCInt1), sieht die Sache nicht soooo schlecht aus.
Bei laufend sendender Maus (da hängt ja der Maussensor an der
PS/2-Schnittstelle) habe ich während der Übertragung eine
Interruptauslastung von ca. 12..15%, und zwar in beiden Fällen, also
Assembler und C. (Bei C ist etwas mehr Jitter, was wohl die Switch
Sprunghierarchie als Ursache hat).
Etwas länger als gemessen, müsste der C-Interrupt noch dauern, da noch
der Push-Pop-Kram reinkompiliert wird, da kam ich mit dem Setzen des
Messpins im C-Code nicht zwischen (in Assembler kein Problem), aber ich
denke mal, nach den 16 Takten kräht der Hahn auch nicht mehr.
Horst S. schrieb:> Etwas länger als gemessen, müsste der C-Interrupt noch dauern, da noch> der Push-Pop-Kram reinkompiliert wird,
sollte aber nicht für alles Register sein, wenn es doch so ist stimmt
etwas nicht. Dann inlined er bestimmt eine Funktion nicht. Prüfe ob alle
Funktion in der ISR static sind.
Poste mal den ASM code
Hans schrieb:> Ich hoffe ich hab' mich nirgends vertippt
Ja, ich mag if-else Ketten nicht, das wird schnell unübersichtlich.
Der AVR-GCC mag switch-case und optimiert es recht gut.
Hans schrieb:> Eigentich müsste der Compiler die beiden Funktionen automatisch inlinen.
Macht er, wenn man sie ordentlich als "static" deklariert. Dann
weiß er, dass sie ohnehin niemand mehr von außerhalb aufrufen kann.
Oder einfach -flto.
Was auch kleineren Code machen kann sind: -fno-caller-saves sowie
-fno-tree-loop-optimize und / oder -fno-move-loop-invariants. Und
natürlich -mrelax --gc-sections und -ffunction-sections nicht vergessen.
Peter D. schrieb:> Hans schrieb:>> Ich hoffe ich hab' mich nirgends vertippt>> Ja, ich mag if-else Ketten nicht, das wird schnell unübersichtlich.> Der AVR-GCC mag switch-case und optimiert es recht gut.
stand ja noch ein "Nachdem der switch sehr "unbefüllt" ist würde ich das
sogar so machen:" drüber ;)
Hast aber natürlich recht. Von Fall zu Fall sollte man sich das trotzdem
anschauen was schneller/kleiner ist...
73
Horst S. schrieb:> - Was ich noch finde: Der Optimizer kotzt mir immer wieder in der> lss-Datei Fragmente der TxDSendByte-Routine vor die Füße. Mag der keine> call-Befehle?
Er versucht, kurze Funktionen inline umzusetzen, um damit den zeitlichen
Overhead der Calls zu sparen und den Inhalt der Funktion im Kontext
ihres Aufrufs besser zu optimieren.
Hans schrieb:> Beim Switch/Case müsstest du im listing schaun was der compiler daraus> macht. Teilweise ist ein if-else-if kleiner... das hängt aber von der> architekur und dem jeweiligen anwendungsfall ab.
Sollte an sich nicht passieren. Der Compiler ist normalerweise schon so
clever, bei einem switch/case zu erkennen, ob eine Sprungtabelle oder
eine Reihe von Vergleichen effizienter ist.
Johann L. schrieb:> Oder einfach -flto.>> Was auch kleineren Code machen kann sind: -fno-caller-saves sowie> -fno-tree-loop-optimize und / oder -fno-move-loop-invariants. Und> natürlich -mrelax --gc-sections und -ffunction-sections nicht vergessen.
Nicht zu vergessen -mcall_prologues, falls man viele (grössere)
Funktionen hat. Dann werden die Push-Pop-Orgien "an einer Stelle
gebündelt". Das hat beim Transistor-Tester schon mal geholfen rund 20%
Flash einzusparen.
Bei -flto ist zu beachten, daß fur bestes Ergebnis Compiler UND Linker
dieses Option brauchen UND beide die selbe Optimierungs-Option. z.B. -Os
haben sollten.
Hans schrieb:> Beim Switch/Case müsstest du im listing schaun was der compiler daraus> macht. Teilweise ist ein if-else-if kleiner... das hängt aber von der> architekur und dem jeweiligen anwendungsfall ab.
Überlass das ruhig dem Compiler. Der analysiert die Datenverteilung und
sucht sich dann unter den implementierten Varianten eine passende aus.
Darunter sind auch einfache aufeinander folgende Vergleiche oder
sukzessive Subtraktionen (bei AVR bringt das nichts, anderswo schon).
Bei einer nicht zu kleinen Anzahl numerisch verstreuter Fälle
implementiert er auch gerne einen Vergleichsbaum. Das ist eine Technik,
die praktisch nur ein Compiler zustande bringt.
A. K. schrieb:> Bei einer nicht zu kleinen Anzahl numerisch verstreuter Fälle> implementiert er auch gerne einen Vergleichsbaum. Das ist eine Technik,> die praktisch nur ein Compiler zustande bringt.
Und das macht avr-gcc besser als früher: https://gcc.gnu.org/PR49903
Ich hab's jetzt mal mit einem Watchdog versehen, der bei fehlenden
Flanken den State zurücksetzt. Dazu habe ich den leidigen state aus der
Funktion allerdings zur Modulvariable deklarieren müssen.
Zum Switch fiel mir dann noch ein: "Wozu gibt's den Default-Zweig?"
(Hilft gegen Augenkrebs).
Nachdem ich die LED-Funktionen als "extern Inline" im Header-File habe,
sieht auch die Rettungsaktion auf dem Stack wieder übersichtlich aus:
Listing .lss:
1
//++++++++++++++++++++++++++++++++++++++++++
2
//External PCINT PinChange Interrupt
3
//++++++++++++++++++++++++++++++++++++++++++
4
ISR(PCINT1_vect)
5
{
6
866:1f92pushr1
7
868:0f92pushr0
8
86a:0fb6inr0,0x3f;63
9
86c:0f92pushr0
10
86e:1124eorr1,r1
11
870:2f93pushr18
12
872:8f93pushr24
13
874:9f93pushr25
14
876:ef93pushr30
15
878:ff93pushr31
16
}
17
18
19
externinlinevoidSetLED3()
20
{
21
PORTD|=(1<<LED3);
22
87a:5e9asbi0x0b,6;11
23
.
24
.
25
.
26
.
Modul PS2 (V3)
1
#include"structs.h"
2
#include"Ports.h"
3
#include"LED.h"
4
#include<inttypes.h>
5
#include<avr/interrupt.h>
6
#include<string.h>
7
8
9
staticuint8_tPS2Byte;
10
staticuint8_tPS2Checksum;
11
staticuint8_tPS2Watchdog=0;
12
staticuint8_tPS2State=0;//Listen
13
#define MSK_PS2Listen 0x00
14
#define MSK_PS2BitCounter 0x0F
15
#define MSK_PS2SendStart 0x10
16
#define MSK_PS2Send 0x30
17
18
19
20
21
voidPS2Init()
22
{
23
PCMSK1=(1<<PCINT11);//Enable Pin change inerrupt on PC3 ()PCINT11)
24
PCICR=(1<<PCIE1);//Enable external interrupt for PCINT14:8
25
26
//Reset variables
27
DataRead.LastOffset=0;
28
DataWrite.MouseCommand=0;
29
PS2Byte=0;
30
memset(&DataRead,0,sizeof(DataRead));
31
}
32
33
34
35
voidPS2TestWatchdog()
36
{
37
if(PS2Watchdog==0)return;
38
39
PS2Watchdog--;
40
if(PS2Watchdog==0)
41
PS2State=0;
42
}
43
44
staticvoidRetriggerPS2Watchdog()
45
{
46
PS2Watchdog=4;
47
}
48
49
//Basic Port functions
50
staticvoidPS2PullDownClock()
51
{
52
PORTC&=~(1<<PS2Clock);
53
DDRC|=(1<<PS2Clock);
54
}
55
56
staticvoidPS2ReleaseClock()
57
{
58
DDRC&=~(1<<PS2Clock);
59
}
60
61
staticvoidPS2PullDownData()
62
{
63
PORTC&=~(1<<PS2Data);
64
DDRC|=(1<<PS2Data);
65
}
66
67
68
staticvoidPS2ReleaseData()
69
{
70
DDRC&=~(1<<PS2Data);
71
}
72
73
74
75
76
voidPS2Send(uint8_tbt)
77
{
78
79
// set a save state
80
PS2State=MSK_PS2SendStart;
81
//Prepare checksum
82
83
PS2Checksum=MakeChecksumOfByte(bt);
84
85
// pull down Clock for 100u
86
PS2PullDownClock();
87
Wait100u();
88
PS2Byte=bt;
89
90
91
92
// pulldown data and release clock
93
PS2PullDownData();
94
PS2ReleaseClock();
95
PS2State=MSK_PS2Send;
96
}
97
98
99
//++++++++++++++++++++++++++++++++++++++++++
100
//External PCINT PinChange Interrupt
101
//++++++++++++++++++++++++++++++++++++++++++
102
ISR(PCINT1_vect)
103
{
104
SetLED3();
105
if((PINC&(1<<PS2Clock))==0)// Do something,while clock is low
106
{
107
switch(PS2State)
108
{
109
case0://Receive Startbit
110
SetLED2();
111
PS2Byte=0;
112
PS2State++;
113
break;
114
115
case0x09://Recieve PS2ReceiveParity
116
PS2State++;
117
break;
118
119
case0x0A://Receive complete-> Transfer byte to target
Horst S. schrieb:> "Wozu gibt's den Default-Zweig?"> (Hilft gegen Augenkrebs).
naja, übersichtlicher finde ich das nicht wirklich. So mal dann dort
wieder nach senden und empfangen unterschieden wird.
Peter II schrieb:> naja, übersichtlicher finde ich das nicht wirklich. So mal dann dort> wieder nach senden und empfangen unterschieden wird.
Hehe, da hat Basic die Nase vorn. Da kann man auch
@ Horst S. (hdc)
>Das ist ja lustig:>Mit dem Default-Zweig bin ich bei 2528 Bytes.>Wenn ich die case-Bereiche verwende, spare ich noch 4 Bytes.
Damit wirst du die Welt retten . . .
Falk B. schrieb:> Damit wirst du die Welt retten . . .
Zumindest nicht Mobys Welt, denn sein C-Programm ist ja nun schon
mehr als 10 % kleiner als sein altes Assemblerprogramm. :)
Jörg W. schrieb:> Zumindest nicht Mobys Welt, denn sein C-Programm ist ja nun schon> mehr als 10 % kleiner als sein altes Assemblerprogramm. :)
und wir sind erst in der ps2 quelle - das ist noch einige zu machen.
Kleiner Hinweis an den C-Lernenden.
Wenn du versucht bist, solche Kommentare zu schreiben
1
switch(PS2State)
2
{
3
case0://Receive Startbit
dann solltest du dir überlegen, ob du nicht für deine magischen
Konstanten benannte Bezeichner einführen willst. Im einfachsten Fall
sind das einfach nur ein paar #define, mit denen du den Zahlen im Code
'einen Namen' gibst. Für den Compiler kommt das auf dasselbe heraus,
denn der sieht letzt Endes ohnehin wieder die Zahl, nachdem der
Präprozessor die Textersetzung durchgeführt hat. Aber für dich als
Programmierer macht es einen Unterschied. Vor allen Dingen in ein paar
Wochen bzw. Monaten, wenn du noch Erweiterungen am Programm vornehmen
willst. Denn irgendwas willst du ja jetzt mit dem freigespielten
Speicher machen :-)
Ein
1
PS2State=WAIT_FOR_STARTBIT;
liest sich viel besser und erzählt mir in der Anweisung alles was ich
wissen muss. Auf jeden Fall mehr als ein
1
PS2State=0;//Fallback to listen
Zudem hab ich durch die Bezeichnung einen Begriff, nach dem ich im Code
suchen kann und der mich dann eben direkt zu
1
switch(PS2State)
2
{
3
caseWAIT_FOR_STARTBIT:
4
...
bringt, ohne dass ich erst mal alle Stellen, an denen 0 vorkommt beim
Suchen überspringen muss.
Alles was du dazu brauchst, ist ein
1
#define WAIT_FOR_STARTBIT 0
und die Sache ist geritzt (selbiges natürlich auch für die anderen
States bzw. die anderen magischen Konstanten).
Darauf solltest du dein Augenmerk legen und nicht darauf, ob du deinen
Prozessor nun zu 17.6% oder doch zu 18.5% ausnutzt. Das interessiert
nämlich niemanden. Was aber interessiert, das ist dass dein Programm
auch in Zukunft noch wartbar bleibt.
Du setzt im Moment die falschen Prioritäten. Hast du ein Problem damit,
dass dein Programm zu groß werden würde um ins Flash zu passen? Nein?
Dann interessiert das momentan auch nicht. Kümmere dich lieber erst mal
um die wirklich wichtigen Dinge und nicht um solche Kinkerlitzchen.
Alternativ: einen enum einführen. Ist für Zustandsautomaten fast
immer sinnvoll. Man muss auch nicht zwanghaft alle Zustände
benennen, auch sowas geht:
1
enumps2_state{
2
PS2ReceiveStartBit=0,
3
PS2ReceiveParity=9,
4
PS2ReceiveComplete=10,
5
};
Ein enum ist in C nichts anderes als ein paar Namen für einen "int"
(in C++ ist es viel stärker ein eigenständiger Datentyp als in C).
ist auch schlecht. Wähle Bezeichnungen nach ihrer Funktion und nicht
nach technischen Begebenheiten (zumindest nicht im Normalfall). Die LED
erfüllt eine Funktion. Das mag zb die LED sein, die einen Fehler
anzeigt. Dann nenn das auch so. Ein
1
TurnOnErrorLED();
erzählt mir an dieser Stelle im Code viel mehr als dein profanes
SetLED2. Heute magst du noch wissen, dass die LED 2 die Fehlerled ist.
Aber in 3 Monaten sieht das alles ganz anders aus. Denn da muss ich erst
mal in der Funktion nachsehen, ob
* mit 'Set' gemeint ist, dass die LED eingeschaltet wird. Oder doch
ausgeschaltet?
* ich nachsehen muss, was denn die Bedeutung der LED 2 war. Denn genau
die interessiert mich, wenn ich nachvollziehen will oder muss, was denn
eigentlich hier
1
if((PINC&(1<<PS2Data))!=0)
2
SetLED2();
3
else
4
ClearLED2();
passiert.
(Und nein, du brauchst mir jetzt nicht erklären was hier passiert. Darum
geht es nicht. Es geht darum, dass ich als Code-Lesender hier mir die
Dinge zusammensuchen muss und das man das mit den richtigen Bezeichnern
auch vermeiden kann. Zudem sinkt die Fehlerchance, weil einem der Code
schon beim Durchlesen seltsam vorkommt, weil das Niedergeschriebene
keinen Sinn ergibt.
Ein
1
x=x1+x2;
kann richtig oder falsch sein. Mann weiss es nicht. Aber das bei
1
NrCars=PriceBrutto+TimeToPack;
irgendwas nicht stimmen kann, ist unmmittelbar ersichtlich. Die 3
Begriffe, die hier verwendet werden, können in keinen irgendwie
sinnvollen Zusammenhang gebracht werden. Dass die alle gemeinsam in
einer Anweisung in dieser Form auftauchen ist sehr wahrscheinlich
falsch. Dazu brauch ich vom Rest des Programms nichts wissen.
Und noch was: In 3 Monaten ist dein Vorteil des Entwicklers fast auf 0
zusammengeschmolzen. Wenn du in 3 Monaten wieder an den Code rann gehst,
dann geht es dir nicht besser als jemandem, der von diesem Code noch nie
etwas gesehen hat. D.h. du musst heute den Code so schreiben, dass du
ihn in 3 Monaten auch noch nachvollziehen kannst. Das ist eine der
Bedeutungen von 'wartbarem Code'.
Das ist auch einer der Gründe warum man überhaupt 'Hochsprachen'
verwendet. Weil man sich auf die Verfahren konzentrieren kann ohne sich
um den technischen Kleinkram kümmern zu müssen.
)
was ganz gerne auch was bringt, sind structs statt globale.
Damit "erzwingt" man quasi indirekten zugriff und spart sich das 16-bit
pointer-laden hin und wieder.
also aus
1
staticuint8_tPS2Byte;
2
staticuint8_tPS2Checksum;
3
staticuint8_tPS2Watchdog=0;
4
staticuint8_tPS2State=0;//Listen
1
structPS2VariableStruct{
2
uint8_tPS2Byte;
3
uint8_tPS2Checksum;
4
uint8_tPS2Watchdog=0;
5
uint8_tPS2State=0;//Listen
6
}
7
8
staticPS2VariableStructPS2Variables;
Wobei ehrlich gesagt du eigentlich schon quasi objekt orientiert
unterwegs bist und sich C++ schon anbieten würde...
Karl H. schrieb:> Kleiner Hinweis an den C-Lernenden.
Der C-Lernende ist in diesem Fall äußerst verwöhnt (fast schon versaut,
weil ich kann mir Namen mittlerweile wirklich nur noch so lange merken,
bis sie aus dem Bildschirm raus sind)
In C# hätte ich's wegen IntelliSense benamt. Hier bin ich ehrlich gesagt
unentschlossen. Ich bin auch kein Fan von dem Gedanken, ein Protokoll
anhand von Quellcode zu studieren, da bin ich eher Dokumentöse:
Aber in der Realität hätte ich wahrscheinlich nur notiert, welche
State-Bereiche Empfang und Senden regeln und wo/warum das Sperren des
Empfangs über die 100us-Pause erfolgt.
Jörg W. schrieb:> Zumindest nicht Mobys Welt, denn sein C-Programm ist ja nun schon> mehr als 10 % kleiner als sein altes Assemblerprogramm. :)
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 ;-)
Aber nicht, daß ich die ehrlichen Optimierbemühungen hier ohne Sympathie
verfolgen würde. Ist nur blöd, wenn der Fehler am System liegt- zur
eigentlichen zu entwickelnden Programmlogik immer noch zusätzlich die
Suche nach dem besten der groben C-Bausteine samt passender
Verkettungsausdrücke
hinzukommt. Und als besonderes Extra schließlich die Code-Optimierung
anhand der Befindlichkeiten des verwendeten Compiler-Werkzeugs.
Schreibts im Klartext, dann brauchts keine Disassemblierung zum
Klarwerden darüber, was nun klarerweise geschieht.
Ingo schrieb:> Ich kann mich täuschen, aber ich habe noch nirgends ne Zeile ASM von> Moby gesehn...
Du täuscht Dich ;-)
Moby schrieb:> Aber nicht, daß ich die ehrlichen Optimierbemühungen hier ohne Sympathie> verfolgen würde. Ist nur blöd, wenn der Fehler am System liegt- zur> eigentlichen zu entwickelnden Programmlogik immer noch zusätzlich die> Suche nach dem besten der groben C-Bausteine samt passender> Verkettungsausdrücke> hinzukommt.
Ich schau hier auch nur das erste mal über meinen Tellerrand, allerdings
kann ich jetzt nach zwei Tagen Arbeit mit dem C-Gedöns sagen:
Den Kram, den der Optimierer da zusammenbaut, den hätte ich in Assembler
weder so optimiert hinbiegen können, noch hätte ich danach eine Chance
zu verstehen, was ich da warum programmiert habe.
Nachteil (ganz klar): Du lieferst Dich der Stabilität des Compilers aus.
Und wehe Dir, der baut Mist.
Aber so weit bin ich noch nicht gekommen...
@Horst S.:
Glückwunsch daß du den Tellerrand übersprungen hast. Ganz ehrlich
gemeint. Leider zeigen sich hier immer nur die, die den Tellerrand
nichtmal erahnen können.
Moby schrieb:> Immer wieder schön, wenn dann der nächstkleinere> Controller genügt ;-)
Den es in Wirklichkeit gar nicht gibt. Heutzutage ist die Diegröße und
damit der wirkliche Preis nur durch die Anzahl der IO-Pads bestimmt. Da
leere Flächen auf dem Die nicht wirklich Sinn machen, wird er mit Flash
und RAM gefüllt. Da manche Spezialisten immer noch glauben, größer
kostet mehr, kann man durch einfache Bondoptionen den Kleinkunden für
den gleichen Chip mit freigeschaltetem Speicher mehr abnehmen. Den
Einkäufern von Großabnehmern kann man das natürlich nicht erzählen, die
zahlen für den (in Wirklichkeit gar nicht) größeren Chip das Selbe.
Ist wie mit der Bandbreite bei manchen Scopes, die kleinere gibt es
technisch nicht wirklich. Und die Preisdifferenz verhandelt ein
erfahrener Einkäufer schnell weg.
Horst S. schrieb:> Nachteil (ganz klar): Du lieferst Dich der Stabilität des Compilers aus.> Und wehe Dir, der baut Mist.
Und der Vorteil, du lieferst dich der Qualität vieler Compilerentwickler
aus und bist nicht dem einen Assemblernerd ausgeliefert, der mit der
nächsten Chipgeneration schon nichts mehr anfangen kann. Und wehe, der
hat Mist gebaut.
MfG Klaus
Moby schrieb:> Immer wieder schön, wenn dann der nächstkleinere> Controller genügt ;-)
War das C-Programm hier nicht kleiner oder hab ich was verpasst?
> nächstkleinere Controller
Zu welchem Preis? Wenn ich für sagen wir mal 1€ mehr den µC mit Speicher
bekommen kann nutze ich gerne den Komfort einer Hochsprache.
(ASM-)Handoptimierung zahlt sich -wenn überhaupt- erst bei hohen
Stückzahlen aus..
Klaus schrieb:> Assemblernerd ... der mit der> nächsten Chipgeneration schon nichts mehr anfangen kann.
Und auch nicht muß, weil die AVRs schon lange Zeit und noch für lange
Zeit dicke reichen. C-Code bedeutet für eine neue Chipgeneration (z.B.
ARM) im übrigen auch nicht, unverändert übernommen werden zu können.
qwerty schrieb:> (ASM-)Handoptimierung
Die optimale Ausnutzung der Hardware ist aber gerade das was den Vorteil
von Asm ausmacht- ansonsten ist es auch nicht mehr als gewöhnliches
(zuweilen wesentlich weniger textlastiges) Codeschreiben.
Man kann drüber streiten, welche Programmierung im Bereich kleiner
Controller bequemer und zeitsparender ist (eine entsprechende
Softwarebasis vorausgesetzt). Man kann nicht darüber streiten, daß es
subjektive Vorlieben für das eine oder andere gibt.
Aber Hand aufs Herz- alles hat irgendwo seinen Preis. Der bedeutet im
Fall der (bequemeren?) Hochsprachenverwendung immer Platz-und
Performancenachteile. Ganz gleich, wie gut ein Compiler sein mag. Der
kann weder schlechte Programmierung ausgleichen noch überhaupt jede
konkrete Absicht des Programmierers erahnen. Erfordert um halbwegs
effizient zu werden viel Herumkonfiguriererei.
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.
> Dazu braucht es nur ein paar Dutzend
Asm-Anweisungen ...
Womit die Größenverhältnisse klar dargelegt wurden. Ja, auch so kleine
Programme kann man auf einem AVR laufen lassen. Sollte man aber keine
Sub-μs-Timing-Anforderungen haben und wo braucht man das schon, dann ist
Handoptimierung pure Verschwendung. Selbst wenn ich statt ein paar
Dutzend aller 256 Befehlsworte eines Tiny4 brauchen sollte, who cares.
Kleiner wird der nimmer. Und eins ist bei mir sehr knapp: Lebenszeit!
Die will ich nicht mit Register-Allokieren verbringen.
Aber das wird Troll-by wieder ganz anders sehen. Sein Erkenntnisgewinn
aus dem Thread, der die "entscheidende Frage" mal wirklich untersucht
und feststellt, daß die vermeintlichen Geisterfahrer doch in die
richtige Richtung fahren: exakt NULL!
Carl D. schrieb:> Sollte man aber keine> Sub-μs-Timinganforderungen haben und wo braucht man das schon, dann> Handoptimierung pure Verschwendung.
Ob nun ein konkretes Projekt von Asm-Platz- und Performanceersparnis
profitiert steht sicher auf einem anderen Blatt. Aber es könnte doch
größer werden (müssen). Es ist da sehr beruhigend mehr Reserven, wie
überhaupt die totale Kontrolle in der Hinterhand zu wissen und seinen
Controller im ungünstigen Falle nicht "auslöten" sprich wechseln zu
müssen...
Die wenigen dutzend simplen Asm-Instruktionen bedeuten aber auch, man
braucht nicht mehr zu seinem Glück, es vereinfacht und macht die Sache
transparent.
> Und eins ist bei mir sehr knapp: Lebenszeit!> Die will ich nicht
... mit Programmierung von Code und Werkzeug verschwenden und auch
nicht mit unnützen Controllerwechseln und mit stetig neuen Architekturen
und stetig neuen Werkzeugen und und und...
> Geisterfahrer
gibts nicht, solange man erfolgreich programmiert. Das allerdings geht
mehr oder weniger effizient und vorausschauend ;-)
Moby schrieb:> immer Platz- und Performancenachteile.
War das C-Programm hier nicht kleiner oder hab ich was verpasst?
> Ganz gleich, wie gut ein Compiler sein mag. Der> kann weder schlechte Programmierung ausgleichen noch überhaupt jede> konkrete Absicht des Programmierers erahnen.
Das kann ein Assembler noch weniger, der überetzt 1:1 ohne jegliche
Optimierung.
In Zeiten, in denen 32-Bitter inzwischen weniger kosten als 8-Bitter ist
es müßig, über die "bessere" Ausnutzung durch ASM zu reden.
Bei der Portierung 8-Bit zu 32-Bit macht es durchaus einen Unterschied,
ob man bei ASM 100% des Codes überarbeiten muss oder bei C nur die I/O
Bereiche - die in meinem Fall vielleicht 5-10% ausmachten.
Beispiel: Der STM32F030 kostet bei Farnell aktuell 1,10 Eur bei
Einzelabnahme. TSSOP20, 16KFlash, 4KRam, 12-Bit A/D, SPI/I2C/Uart, DMA,
16-Bit Timer. AVRs sind bei mir ausgelistet....
Moby schrieb:> Und auch nicht muß, weil die AVRs schon lange Zeit und noch für lange> Zeit dicke reichen.
Für dich vielleicht, es soll aber auch Leute geben die größeres vorhaben
als
> ein paar Dutzend Asm-Anweisungen> C-Code bedeutet für eine neue Chipgeneration (z.B.> ARM) im übrigen auch nicht, unverändert übernommen werden zu können.
Mit einer guten Abstraktion geht das. Arduino Code z.B. läuft
unverändert auf einem UNO (ATmega328) und einem DUE (SAM3X8E ARM
Cortex-M3).
> Die optimale Ausnutzung der Hardware ist aber gerade das was den> Vorteil von Asm ausmacht
Wozu einen alten AVR optimal ausnutzen wenn man für 1,10€ schon einen
STM32 haben kann?
Ich kann Mobys Freude am Register schieben und asm programmieren
verstehen. Total. Es ist ja anscheinend auch definitiv Hobby. Da kann
ich voll nachvollziehen, dass es ihm Spaß macht den alten dil Atmel in
der Lochrasterplatine ans Laufen zu bekommen. Das ist weder zynisch noch
sarkastisch gemeint.
Ebenso halte ich nicht besonders viel davon im Hobby aus Prinzip den
32-bitter zu benutzen. Das fordern jetzt Leute, die der Arduino Fraktion
im nächsten Thread vorwerfen planlos und resourcenverschwendend drauf
los zu programmieren.
Ich kann sogar Moby's Angst vorm Unbekannten und neuen Sachen in
gewisser Weise nachvollziehen.
Aber das bornierte Auftreten und völlige ignorieren von Argumenten und
Einwänden kann ich nicht nachvollziehen und auch nicht akzeptieren. So
disqualifiziert man sich für mich. Das kann ich mir allenfalls im
Alteheim in der Demenzabteilung vorstellen. Erschreckend, dass auch hier
die Leute nur und ausschließlich schwarz weiß denken können.
Was ist denn jetzt mit der Codegröße???
Christian F schrieb:> Ich kann Mobys Freude am Register schieben und asm programmieren> verstehen. Total. Es ist ja anscheinend auch definitiv Hobby.
Klar kann das Spaß machen. Ich hatte auch mal Spaß daran, Assemblercode
auf Papier zu schreiben, von Hand zu Assemblieren und das Ergebnis dann
in eine Hex-Tastatur einzutipppen. Ist doch vollkommen ok.
Aber Moby stellt es als das einzig wahre Allheilmittel dar, mit dem man
mit geringstem Aufwand µC-Projekte beliebigen Umfangs auf einem AVR ans
laufen bekommt und daß alles andere vollkommener Unsinn ist.
Das einzige Beispiel, das ich bisher mal von ihm gesehen habe - im
Rahmen eines Threads über C++ auf µC - war eine blinkende LED. Zu viel
mehr reicht die Vorstellungskraft offenbar nicht. Ich warte ja immer
noch auf seine FAT-Implementation oder den TCP/IP-Stack in Assembler.
> Ebenso halte ich nicht besonders viel davon im Hobby aus Prinzip den> 32-bitter zu benutzen.
Es kommt drauf an, was das Ziel ist. Wenn man Lust dazu hat, in ASM
jeden Taktzyklus einzeln rauszukitzeln und eine bestimmte Aufgabe auf
einem möglichst kleinen µC umzusetzen, ist es ja legitim, den AVR zu
nutzen.
Es gibt ja auch heute noch Leute, die Spiele für den C64 entwickeln, und
das finde ich duraus cool.
Wenn man dagegen ein größeres Projekt umsetzen und sich mehr auf die
eigentliche Funktion konzentrieren will, dann ist die Effizienz beim
Schreiben des Programms wichtiger als bei dessen Ausführung. Und wenn
man merkt, daß man doch noch eine größere Zusatzfunktion haben will, ist
auch die Option, mit vertretbarem Aufwand auf einen ganz anderen
Controller wechseln zu können, wichtig.
In beiden Fällen ist es unerheblich, ob der Controller nun einen Euro
mehr oder weniger kostet.
> Ich kann sogar Moby's Angst vorm Unbekannten und neuen Sachen in> gewisser Weise nachvollziehen.
Wenn man aber so die Klappe darüber aufreißt, wie er, sollte man es
zumindest mal richtig verstanden haben.
> Aber das bornierte Auftreten und völlige ignorieren von Argumenten und> Einwänden kann ich nicht nachvollziehen und auch nicht akzeptieren.
Moby kommt halt in jedem Thread, in dem es um [beliebige Hochsprache]
geht, zu irgendeinem Zeitpunkt daher und bringt dann immer und immer
wieder das gleiche an. In den meisten dieser Threads wurde nicht mal
nach Assembler gefragt. Das ist so, als ob im Heimwerker-Forum zu jedem
beliebigen Thread über Akkuschrauber (z.B. zum Vergleich zwischen
Hersteller X und Hersteller Y) einer reinkommt und empfielt, doch lieber
den klassischen Schraubenzieher zu nehmen, weil der die Fitness
verbessert und viel mehr Leistung hat (wenn man denn stark genug ist).
Diese übertriebene Vehemenz, die offenbar auch keinerlei Nutzen für
irgendwen bringt, hat dazu geführt, daß Moby von den meisten hier
belächelt und nicht mehr ernst genommen wird.
Rolf M. schrieb:> Diese übertriebene Vehemenz, die offenbar auch keinerlei Nutzen für> irgendwen bringt, hat dazu geführt, daß Moby von den meisten hier> belächelt und nicht mehr ernst genommen wird.
Früher™, im Usenet, hätte man bei Antwortbeiträgen auf ihn dann
entsprechend ein
Hans W. schrieb:> 73
Jetzt hab ich Dich: Was ist das? Dein Alter? Die Anzahl Deiner
Nachfahren?
Hat sich der Supercomputer doch mit 42 verrechnet?
(Wollte ich doch letztens schon fragen.)
Hallo Rolf,
Rolf M. schrieb:> Aber Moby stellt es als das einzig wahre Allheilmittel dar, mit dem man> mit geringstem Aufwand µC-Projekte beliebigen Umfangs auf einem AVR ans> laufen bekommt und daß alles andere vollkommener Unsinn ist.> Das einzige Beispiel, das ich bisher mal von ihm gesehen habe - im> Rahmen eines Threads über C++ auf µC - war eine blinkende LED. Zu viel> mehr reicht die Vorstellungskraft offenbar nicht.
Er kann eben einfach nicht mehr als eine LEDs blinken lassen, zu mehr
reicht es bei ihm mit seinem geliebten Assembler nicht. Deswegen faselt
er ja auch immer von "ein paar Dutzend Instruktionen", die angeblich
einfacher seien als die 32 Schlüsselworte in C, weil er von den ~ 130
Instruktionen, die so ein AVR kennt, eben nur gerade mal zwei Dutzend
beherrscht. Das ist schade, aber zum Glück ja nur für ihn. ;-)
Liebe Grüße,
Karl
Diese Entwicklung habe ich auch durchgemacht :-)
Horst S. schrieb:> Ich schau hier auch nur das erste mal über meinen Tellerrand, allerdings> kann ich jetzt nach zwei Tagen Arbeit mit dem C-Gedöns sagen:> Den Kram, den der Optimierer da zusammenbaut, den hätte ich in Assembler> weder so optimiert hinbiegen können, noch hätte ich danach eine Chance> zu verstehen, was ich da warum programmiert habe.
Ab einem gewissen Projektumfang muss man eben auch in Assembler 'ein
bisschen Struktur' reinbringen, um die Übersicht zu behalten. Allerdings
muss das den Compiler nicht interessieren...
> Ab einem gewissen Projektumfang muss man eben auch in Assembler 'ein
bisschen Struktur' reinbringen, um die Übersicht zu behalten.
Ich bevorzuge da eben eine Problembeschreibungssprache mit höherem
Abstraktionsgrad. Und überlasse die Transformation in HW-Befehle der
dafür spezialisierten Software. Diese optimiert im Übrigen nicht nur für
die Zielplattform, sondern schon vorher auf einem abstrakteren Level.
Programme werden nicht lesbarer, wenn man z.B. (ganz simples) bei
Schleifen die gemeinsamen Ausdrücke herauszieht. Man muß diese
(Knuth-Eval-)Optimierungschritte beim Lesen/Verstehen immer wieder
rückgängig machen. Schön wenn da welche ein Programm geschrieben habe,
das sowas kann. Und denen morgen ein noch besserer Kniff einfällt. Dann
einfach nochmal "Build". Die Abhängigkeit vom OS-Projekt GCC kann ich
verschmerzen, verglichen mit so Dingen wie BASCOM, AvrLuna, ... wo gerne
auch mal Einzelpersonen dahinterstehen.
qwerty schrieb:> War das C-Programm hier nicht kleiner oder hab ich was verpasst?
Na ja, wer aufmerksam gelesen hat wird diesen Umstand von mir schon mit
klaren Worten, aber ohne persönlich zu werden kommentiert sehen ;-)
qwerty schrieb:> Das kann ein Assembler noch weniger, der überetzt 1:1 ohne jegliche> Optimierung.
Die Unzulänglichkeiten grober C-Bausteine müssen hier auch nicht
optimiert werden. 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, wie man beim TO-Programm schön
sehen kann ;-)
Hans W. schrieb:> Interessanterweise habe ich übrigens noch keinen Thread gesehen wo Moby> ein ASM ergebnis geliefert hat das tatsächlich wesentlich kleiner ist...
Gelegenheiten gab es schon, mit C gegenzuhalten...
Aber natürlich ist es das keinem Hochsprachler wert.
Könnte ja dumm ausgehen. Es wird von mir weiter Code in der
Projekte-Abteilung geben. Versprochen. Jeder sei dann herzlichst
eingeladen, kürzere, schnellere C-Lösungen zu präsentieren! Passieren
wird aber nix vermute ich.
Marvin M schrieb:> In Zeiten, in denen 32-Bitter inzwischen weniger kosten als 8-Bitter ist> es müßig, über die "bessere" Ausnutzung durch ASM zu reden.Markus schrieb:> Wozu einen alten AVR optimal ausnutzen wenn man für 1,10€ schon einen> STM32 haben kann?
In Zeiten, in denen 8-Bitter sehr viele Aufgaben einfacher lösen sind
noch lang nicht vorbei. Das kann einem durchaus sogar der eine oder
andere Cent mehr wert sein.
Markus schrieb:> Für dich vielleicht, es soll aber auch Leute geben die größeres vorhaben
Absolut einverstanden. Den Code des TO würde ich aber noch lange nicht
dazuzählen.
Christian F schrieb:> dass es ihm Spaß macht den alten dil Atmel in> der Lochrasterplatine
Lochrasterplatine?
Na dann wär ein großer Vorteil kleinster AVRs aber hinfällig: Die
Baugröße! So eine winzige Platine wie ein kleines
Beitrag "Kleines Tiny13 Sensorboard"
zum Beispiel.
Christian F schrieb:> Ich kann sogar Moby's Angst vorm Unbekannten und neuen Sachen in> gewisser Weise nachvollziehen.
Warum den Angst? Die Dinge für Projekte möglichst einfach zu halten ist
kühle rationale Abwägung. Diese sollen möglichst schnell, möglichst
simpel ihren Zweck erfüllen. Es braucht diesbezüglich kein
zeitvernichtendes Hinterherhecheln hinter den neuesten Technologien und
Programmiermethoden- da würde man ja nie fertig. Wenn das jemand als
Schwarz-Weiß Denken bezeichnet kann ich damit leben. Ich nenn es
Konzentration auf das Wesentliche.
Jörg W. schrieb:> Followup-To: de.alt.gruppenkasper
Das mache ein User hier mal mit einem Mod.
Der wird dann aber sowas von schnell zum Lösch-Mod und verweist auf
Forenregeln ;-)
Karl Käfer schrieb:> Er kann eben einfach nicht mehr als eine LEDs blinken lassen, zu mehr> reicht es bei ihm mit seinem geliebten Assembler nicht.
Nun ja, ein Karl Käfer kennt sich da eben aus.
Für Dich steht da allerdings auch noch eine Aufgabe an:
Dem SerialComInstruments wirklich Paroli zu bieten ;-)
...Und wenn dein Projekt ebenfalls in c problemlos auf dem Tiny
umzusetzen wäre?
Der code ist händisch so optimiert, dass jedes Bit gesetzt ist und kein
Platz mehr da ist? Ram ist voll? Dann wäre das Projekt fragwürdig: null
Chance auf Erweiterung bzw. nötige Fehlerbehebung ist nicht unbedingt
eine gute Basis.
Moby schrieb:> Gelegenheiten gab es schon, mit C gegenzuhalten...> Aber natürlich ist es das keinem Hochsprachler wert.> Könnte ja dumm ausgehen. Es wird von mir weiter Code in der> Projekte-Abteilung geben.
Vielleicht mal ein-zwei Links auf diese Projekte? (Vielleicht auch nicht
gerade die kleinsten)
Christian F schrieb:> Der code ist händisch so optimiert, dass jedes Bit gesetzt ist und kein> Platz mehr da ist? Ram ist voll? Dann wäre das Projekt fragwürdig: null> Chance auf Erweiterung bzw. nötige Fehlerbehebung ist nicht unbedingt> eine gute Basis.
In dieser Situation wäre dann aber nicht Asm fragwürdig, sondern
wirklich die Controller-Auswahl. Gewisse Reserven sollten schon vorrätig
sein. Bei Asm mehr, bei Hochsprache noch viel mehr...
Dumdi D. schrieb:> Vielleicht mal ein-zwei Links auf diese Projekte?
Ja, wie gesagt ich werde nicht untätig bleiben.
> Vielleicht auch nicht gerade die kleinsten
Natürlich nur kleine.
Oder meinst Du, daß größere die Chance erhöhen, daß sich ein C-ler die
Arbeit macht?
Wenn man wirklich den kleinsten Code haben will, dann sollte man einen
8051 verwenden. Der hat einen so kompakten Befehlssatz, da kann der AVR
lange nicht mithalten.
Moby schrieb:> In dieser Situation wäre dann aber nicht Asm fragwürdig, sondern> wirklich die Controller-Auswahl. Gewisse Reserven sollten schon vorrätig> sein. Bei Asm mehr, bei Hochsprache noch viel mehr...
Bei Hochsprache eher weniger. Basisfunktionen sind ja schon mit drin.
Und wie Du siehst, ist das C-Programm jetzt schon kleiner als das
Assembler-Programm.
> Dumdi D. schrieb:>> Vielleicht mal ein-zwei Links auf diese Projekte?>> Ja, wie gesagt ich werde nicht untätig bleiben.
Und, wo sind sie? Ach, noch gar nicht veröffentlicht? Warum hast Du den
Leser hier darüber so lange im Irrtum gelassen? Du hast es nämlich so
dargestellt, als ob Deine Projekte schon seit einer Ewigkeit unter
"Projekte & Code" zu finden seien.
Darf ich Dich in die Kategorie "Blender" stecken?
> Natürlich nur kleine.> Oder meinst Du, daß größere die Chance erhöhen, daß sich ein C-ler die> Arbeit macht?LED-Blinken ist natürlich in Assembler kürzer. Das Projekt sollte schon
anspruchsvoller sein. Dann wirst Du sehen, dass ein adäquates Programm
in C insgesamt kürzer sein kann als in Assembler, wo der Programmierer
wegen Übersichtsverlust gar nicht mehr weiter optimieren kann.
Ich finde die Aufgabe hat sehr schön die Vorteile von C aufgezeigt.
Das Switch/Case ist nicht nur deutlich besser lesbar, als ein Wust von
vielen fast gleichen Funktionen + ICALL, sondern erzeugt auch viel
weniger Code.
Was will man mehr?
Moby schrieb:> Die wenigen dutzend simplen Asm-Instruktionen bedeuten aber auch, man> braucht nicht mehr zu seinem Glück, es vereinfacht und macht die Sache> transparent.
Tatsächlich? Vergleiche z.B. mal Assembler einer CISC und einer RISC
CPU. Auf dem ersten Blick mag RISC einfacher und übersichtlicher sein,
wenn man dann aber mal ein bisschen Code schreibt, merkt man schnell
dass RISC den Code ganz schön aufbläst (die ständigen LOAD- und
STORE-Instruktionen zum Beispiel). Die Übersicht leidet zunehmend auch
darunter etc. . Also doch nur täuschende Einfachheit, die dann ins
Gegenteil umschlägt?
Peter D. schrieb:> Wenn man wirklich den kleinsten Code haben will, dann sollte man> einen> 8051 verwenden. Der hat einen so kompakten Befehlssatz, da kann der AVR> lange nicht mithalten.
Mag ja sein. Der AVR ist aber ein Gesamtpaket vorteilhafter
Eigenschaften. Die simple Asm-Programmierbarkeit ist da nur ein
Argument.
Daß man im übrigen an der schönen Kombination AVR/ASM für einfache bis
mittlere Projekte schon so lange festhalten kann ist einer einfachen
Tatsache geschuldet: Größere 32-Bit (ARM) Chips machen es heute eben
noch nicht viel anders, nur viel komplizierter...
Moby schrieb:> Größere 32-Bit (ARM) Chips machen es heute eben> noch nicht viel anders, nur viel komplizierter...
Andere Umschreibung für "Moby hat keine Ahnung". Du machst Dich gerade
zum Brot, lass das lieber.
TriHexagon schrieb:> Moby schrieb:>> Die wenigen dutzend simplen Asm-Instruktionen bedeuten aber auch, man>> braucht nicht mehr zu seinem Glück, es vereinfacht und macht die Sache>> transparent.>> Tatsächlich? Vergleiche z.B. mal Assembler einer CISC und einer RISC> CPU. Auf dem ersten Blick mag RISC einfacher und übersichtlicher sein,> wenn man dann aber mal ein bisschen Code schreibt, merkt man schnell> dass RISC den Code ganz schön aufbläst (die ständigen LOAD- und> STORE-Instruktionen zum Beispiel). Die Übersicht leidet zunehmend auch> darunter etc. . Also doch nur täuschende Einfachheit, die dann ins> Gegenteil umschlägt?
Ja ich kann das nachvollziehen da ich wie viele auch aus der Z80-CISC
Welt komme. RISC und CISC haben aber beide ihre Vor-und Nachteile.
Load-Store Operationen im Speziellen kann man bei AVR aber recht
speichersparend über die Index-Befehle abwickeln...
Die Übersicht tät ich bei vielen komplexen C-Ausdrücken verlieren;-)
Frank M. schrieb:> Moby schrieb:>> Größere 32-Bit (ARM) Chips machen es heute eben>> noch nicht viel anders, nur viel komplizierter...>> Andere Umschreibung für "Moby hat keine Ahnung". Du machst Dich gerade> zum Brot, lass das lieber.
Na was machen sie den groß anders? Lass mal Deine Ahnung sprechen.
Steckt da etwa mehr Intelligenz drin die mir tatsächlich Arbeit
abnimmt oder läuft es nicht doch viel mehr nur auf eine Potenzierung von
Konfigurationsarbeiten hinaus? Falls Du bestreiten möchtest daß diese
Chips komplexer zu programmieren sind können wir an dieser Stelle gleich
abbrechen...
Moby schrieb:> Na was machen sie den groß anders?
Allein schon die 32-Bit lassen viele Barrieren fallen, mit denen Du auf
einem 8-bittgem AVR zu kämpfen hast.
> Lass mal Deine Ahnung sprechen.
Nö, googlen kannst Du selber. Stell Dich nicht blöder an als Du bist.
> Steckt da etwa mehr Intelligenz drin die mir tatsächlich Arbeit> abnimmt oder läuft es nicht doch viel mehr nur auf eine Potenzierung von> Konfigurationsarbeiten hinaus?
Unter Assembler ist es natürlich ein erheblicher Aufwand, einen
STM32-Pin auf Output zu programmieren. Kein Wunder, dass Du diese Arbeit
scheust und Dich auf Deiner kleinen AVR-Insel verkriechst.
Wenn ich an Moby denke, denke ich immer an einen Einsiedler, der schon
vor zwanzig Jahren auf einer einsamen Insel zusammen mit einem ATTiny
gestrandet ist und seitdem die weitere Entwicklung komplett verschlafen
hat.
> Falls Du bestreiten möchtest daß diese> Chips komplexer zu programmieren sind können wir an dieser Stelle gleich> abbrechen...
Da ist überhaupt nichts "komplexer". Man hat nur etwas mehr
Schreibarbeit. Aber das macht Komplexität bestimmt überhaupt nicht aus!
Wie wärs mit der Portierung von IRMP und IRSND in Assembler?
Du hast die Wahl zwischen AVR (ATTiny, ATmega, Xmega), PIC, STM32 und
diversen anderen ARM-Prozessoren. Da läuft nämlich ein und derselbe
IRMP-C-Code drauf. Du musst ja nicht direkt auf alle portieren.
ATTiny würde reichen.
Oder ist die Aufgabe für Dich zu "komplex"?
Frank M. schrieb:> Da ist überhaupt nichts "komplexer". Man hat nur etwas mehr> Schreibarbeit. Aber das macht Komplexität bestimmt überhaupt nicht aus!
Schön, damit hast Du Deine Ahnung gerade nett demonstriert.
Du machst Dich gerade zum Brot, also lass das lieber.
Schade eigentlich, denn IRMP ist eine interessante Software, bei der
auch mal wirklich der C-Portiervorteil zum Tragen kommt.
Horst S. schrieb:> ISR_OT_73:> push r16> in r16, SREG> push r16> call WinkeWinke> pop r16> out SREG, r16> pop r16> ISR_OT_73_End:> reti
Sagt mal, was ist an diesem Codeschnipsel eigentlich lesbar (für nicht
AVRer), wartbar (für nicht Assemblerfreaks), oder gar portabel (was ja
per Definition nur bedeutet das ganze auf eine andere Plattform zu
übertragen zu können)?
X4U schrieb:> Sagt mal, was ist an diesem Codeschnipsel eigentlich lesbar
call WinkeWinke
> wartbar (für nicht Assemblerfreaks)
call WinkeWinke
> oder gar portabel
call WinkeWinke
Das wars aber auch schon.
>merkt man schnell>dass RISC den Code ganz schön aufbläst (die ständigen LOAD- und>STORE-Instruktionen zum Beispiel).
Meine Erfahrung sagt genau das Gegenteil. Während des Studiums hatte ich
mit einem SAB80C85 (oder so ähnlich) und einem Motorola-uC zu tun.
Da diese beiden CISC Vertreter nur einen Akku und paar Spezialregister
hatten, musste dauernd gePUSHd und gePOPd werden. Denn alle Operationen
(Addition, Prüfung auf irgendwas) konnten nur mit dem AKKU durchgeführt
werden.
Bei einem AVR dagegen, hat man (fast) 32 gleichwertige Register. Da kann
man Operationen von jedem Register zu jedem Register durchführen...
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.
Was gibt es demgegenüber für herrlich komplexe C-Ausdrücke!
Um da durchzublicken brauchts schon etwas mehr.
Aber vermutlich ist es gerade das, auf das sich hier mancher C-Freak was
einbildet?
Moby schrieb:> Hätte er.
Ich bin auch nur auf dieses eine Projekt gestoßen. Fand es aber nicht
erwähnenswert.
> Aber das wird er nicht wollen ;-)
Aber du willst das doch nicht so stehenlassen? Mach' doch einfach mal
eine Linkliste für die Unwissenden. Dürfte doch kein großer Aufwand
sein.
>Alles, wenn Du das Datenblatt und die paar Instruktionen kennst.>Klartext- und jeder weiß was gespielt wird.>Was gibt es demgegenüber für herrlich komplexe C-Ausdrücke!
[asm]
> ISR_OT_73:> push r16> in r16, SREG> push r16> call WinkeWinke> pop r16> out SREG, r16> pop r16> ISR_OT_73_End:> reti
[/asm]
vs:
Ralf G. schrieb:> Moby schrieb:>> Hätte er.> Ich bin auch nur auf dieses eine Projekt gestoßen. Fand es aber nicht> erwähnenswert.
Musst Du auch nicht. Um hier für Vergleiche herzuhalten ists ohnehin zu
klein. Die Erwähnung durch den Mod folgte wahrscheinlich einer ganz
anderen Absicht.
> Aber du willst das doch nicht so stehenlassen? Mach' doch einfach mal> eine Linkliste für die Unwissenden. Dürfte doch kein großer Aufwand> sein.
Schau mal, ich veröffentliche hier wann und genau das was mir passt
und das wird auch weiter geschehen. Der Aufwand ist ja leider auch
meine Sache. Das wird mich nicht davon abhalten, hier meine
Meinung zu äußern auch wenn mancher, um diese ernstzunehmen, erst große
Vorzeigeprojekte braucht. Die brauch ich aber -hier- nicht.
Matthias L. schrieb:> [asm]>> ISR_OT_73:>> push r16>> in r16, SREG>> push r16>> call WinkeWinke>> pop r16>> out SREG, r16>> pop r16>> ISR_OT_73_End:>> reti> [/asm]>> vs:> ISR_OT_73> {> WinkeWinke();> }
Na sonderlich komplex ist der C-Ausdruck nun aber nicht gelungen.
Und was versteckt sich eigentlich hinter der C-Funktion???
Insofern ist das ein Vergleich von Äpfeln mit Birnen.
Das würde ich zum Punkt Hochsprachen-Intransparenz rechnen!
Warum WUSSTE ich, dass das wieder mal so ausgeht? Der allwöchentliche
"Assembler ist supertoll" Thread.
Ich verweise nur auf den nach dem selben Schema ebenfalls aus dem Ruder
gelaufenen Beitrag "Re: C-Code optimieren (passt nicht in Attiny2313) :("Dumdi D. schrieb:> Vielleicht mal ein-zwei Links auf diese Projekte?> (Vielleicht auch nicht gerade die kleinsten)
Würde mich auch interessieren. Ich hatte da im
Beitrag "Re: C-Code optimieren (passt nicht in Attiny2313) :(" schon mal was
angeregt...
Horst S. schrieb:> Ich habe ein Programmchen für einen ATMega168 zuerst auf Assemblerbasis> erstellt und anschließend auf gcc portiert. Das funktioniert auch alles> (zumindest nicht schlechter als in Assembler), was mich aber zur Zeit> etwas die Augenbrauen hochziehen lässt:> Warum benötige ich im Assembler-Projekt "nur" 2910 Bytes, in C aber> "satte" 3278 Bytes?
Dieser klitzekleine(!) Mehrpreis ist das, was du dafür bezahlst, dass du
dein Programm auch in 1 Jahr noch verstehst, erweitern und warten
kannst.
Oder andersrum: passt es noch in den Controller? Ist es schnell genug?
Gut. Fertig. Du bekommst die mit Assembler "eingesparten" 300 Bytes
nicht ausgezahlt...
Moby schrieb:> Alles, wenn Du das Datenblatt und die paar Instruktionen kennst.> Klartext- und jeder weiß was gespielt wird.
Nachdem ich das ganze gelernt und diverse Datenblätter gewälzt habe sehe
ich das ein paar Daten von Register X nach Speicher Y verschoben werden.
Unter "Klartext" verstehe ich etwas ganz anderes.
> Was gibt es demgegenüber für herrlich komplexe C-Ausdrücke!> Um da durchzublicken brauchts schon etwas mehr.
Man kann sich in jeder Sprache (auch einer natürlichen) so Ausdrücken
das keiner was versteht ;-).
> Aber vermutlich ist es gerade das, auf das sich hier mancher C-Freak was> einbildet?
Mir ist das egal. Hab mit Assembler, Basic Html C Pascal Lisp usw.
gearbeitet.
Mich interessiert das Ergebnis (ganz schmerzfrei).
Der sieht so aus:
Die "C_Freaks" haben die Codegröße 10% unter die des Assemblers
gedrückt, bei ähnlicher Performance. Dazu haben Sie nur wenige Postings
gebraucht.Die Assembler-Freaks haben dem bisher nichts entgegen zu
setzen.
Moby schrieb:> Na sonderlich komplex ist der C-Ausdruck nun aber nicht gelungen.
Da staunst du jetzt, was? So einfach ist 'C'!
> Und was versteckt sich eigentlich hinter der C-Funktion???
Gegenfrage(n):
Was versteckt sich eigentlich hinter der gleichnamigen ASM-Funktion? Das
hast du gleich rausgefunden? Oder hast du die gar überlesen? ASM ist
wohl doch nicht so übersichtlich... ^^
Hans schrieb:> was ganz gerne auch was bringt, sind structs statt globale.>> Damit "erzwingt" man quasi indirekten zugriff und spart sich das 16-bit> pointer-laden hin und wieder.
Der AVR-GCC ist nicht blöd, ihm ist das schnurz.
Er erkennt, daß die Struct global liegt und nimmt trotzdem LDS/STS.
Ist zwar etwas mehr Code (2Wort-Befehle), dafür aber 2 Zyklen für das
Pointer laden gespart.
Zum indirekten Zugriff kannst Du ihn nur zwingen, indem Du den Pointer
übergibst und das Inlinen verbietest.
Matthias L. schrieb:> Meine Erfahrung sagt genau das Gegenteil. Während des Studiums hatte ich> mit einem SAB80C85 (oder so ähnlich) und einem Motorola-uC zu tun.> Da diese beiden CISC Vertreter nur einen Akku und paar Spezialregister> hatten, musste dauernd gePUSHd und gePOPd werden. Denn alle Operationen> (Addition, Prüfung auf irgendwas) konnten nur mit dem AKKU durchgeführt> werden.>> Bei einem AVR dagegen, hat man (fast) 32 gleichwertige Register. Da kann> man Operationen von jedem Register zu jedem Register durchführen...
Stimmt, aber moderne CISC haben heutzutage auch eine Menge Register. Die
paar Transistoren mehr sind heute einfach kein Problem. Beim x86_64
wurden zum Beispiel auch mehr Allzweckregister hinzugefügt.
Lothar M. schrieb:> Dieser klitzekleine(!) Mehrpreis ist das, was du dafür bezahlst, dass du> dein Programm auch in 1 Jahr noch verstehst, erweitern und warten> kannst.>> Oder andersrum: passt es noch in den Controller? Ist es schnell genug?> Gut. Fertig. Du bekommst die mit Assembler "eingesparten" 300 Bytes> nicht ausgezahlt...
Nein, bekomme ich nicht. Allerdings war der Thread im ersten Drittel
auch noch als sachlich zu betiteln (und ich hab was dabei gelernt).
Lothar M. schrieb:> Dieser klitzekleine(!) Mehrpreis ist das, was du dafür bezahlst, dass du> dein Programm auch in 1 Jahr noch verstehst, erweitern und warten> kannst.
Nö, Lothar, inzwischen ist doch sein C-Programm sogar kleiner als die
ursprüngliche Assembler-Version. Insofern war der Thread ja für Horst
durchaus nützlich.
Jörg W. schrieb:> Nö, Lothar, inzwischen ist doch sein C-Programm sogar kleiner als die> ursprüngliche Assembler-Version.
Ach Mann, das habe ich im ganzen Gebashe übersehen... :-/
Aber es ist doch prinzipiell so schon beeindruckend, dass auch ohne
die ganzen Kniffe, Interna und Tricks der Code vom Compiler so klein
ist. Ich ziehe meinen Hut (ich habe wirklich einen) vor den
Compilerbauern.
Horst S. schrieb:> Allerdings war der Thread im ersten Drittel auch noch als sachlich zu> betiteln
Das ist der übliche Verlauf eines üblichen "C vs. Assembler" Threads.
> (und ich hab was dabei gelernt).
Na bitte, darum gehts.
Lothar M. schrieb:> Ach Mann, das habe ich im ganzen Gebashe übersehen... :-/
Das ist schade, dass immer nur maximal der TE den Inhalt mitbekommt. Wer
zu spät einsteigt, sieht immer zuerst die aufgestellten Stinkefinger und
fängt lieber neu bei 0 an.
TriHexagon schrieb:> Vergleiche z.B. mal Assembler einer CISC und einer RISC> CPU. Auf dem ersten Blick mag RISC einfacher und übersichtlicher sein,
Die RISC Philosophie adressierte von Anfang an ausdrücklich die Nutzung
von Compilern, nicht Assembler-Programmierung. Adressierung ist oft
umständlicher, weil von der Distanz abhängig. Konstanten kann man
abhängig vom Wert auf verschiedene Art laden, usw. Das ist zwar auch für
den Compilerbauer zusätzlicher Aufwand - aber nur einmal.
TriHexagon schrieb:> Stimmt, aber moderne CISC haben heutzutage auch eine Menge Register. Die> paar Transistoren mehr sind heute einfach kein Problem.
Im Kontext der von dir genannten AMD/Intel Architekturen gibt es kaum
noch einen Zusammenhang zwischen der Anzahl sichtbarer Register und der
Anzahl real intern vorhandener Register. Intern haben heutige
Implementierungen dank renaming eine dreistellige Anzahl Register.
So art viele moderne CISCs gibt es allerdings nicht, was die
Befehlssatzarchitektur angeht. Die meisten, soweit es noch aktuelle
Implementierungen gibt, stammen im Kern aus den 70/80ern und wurden
allenfalls mal modernisiert wie x86 oder Coldfire.
Peter D. schrieb:> Zum indirekten Zugriff kannst Du ihn nur zwingen, indem Du den Pointer> übergibst und das Inlinen verbietest.
Meiner Erfahrung nach nimmt er mal LDS/STS und mal LD/ST R+. Eine
einfach nachvollziehbare Regel habe ich noch nicht gefunden. Und nicht
immer ist die Wahl optimal.
A. K. schrieb:> So art viele moderne CISCs gibt es allerdings nicht, was die> Befehlssatzarchitektur angeht. Die meisten, soweit es noch aktuelle> Implementierungen gibt, stammen im Kern aus den 70/80ern und wurden> allenfalls mal modernisiert wie x86 oder Coldfire.
Mein Gefühl sagt mir ohnehin, dass heutzutage kaum noch reine CISC und
RISC Prozessoren entwickelt werden. Das sind irgendwie alles Hybriden,
welche versuchen die Vorteile beider Welten zu vereinen.
TriHexagon schrieb:> Mein Gefühl sagt mir ohnehin, dass heutzutage kaum noch reine CISC und> RISC Prozessoren entwickelt werden.
Eine der neuesten mir bekannten Architekturen ohne Vorgänger ist
MaxQ2000. Die ist noch deutlich weiter reduziert als Load/Store-RISC,
weil es noch nicht einmal klare Lade/Speicherbefehle gibt.
> Das sind irgendwie alles Hybriden,> welche versuchen die Vorteile beider Welten zu vereinen.
Was die Befehlssatzarchitektur angeht, also das, was der Programmierer
sieht? Was wären da solche neueren Entwicklungen?
A. K. schrieb:>> Das sind irgendwie alles Hybriden,>> welche versuchen die Vorteile beider Welten zu vereinen.>> Was die Befehlssatzarchitektur angeht, also das, was der Programmierer> sieht? Was wären da solche neueren Entwicklungen?
Das habe ich falsch formuliert, ganz vergessen dass sich RISC und CISC
nur an die Befehlssatzarchitektur bezieht. An die RISC/CISC Architektur
hält man sich heute noch strikt.
Was ich meinte war, dass Eigenschaften die früher RISC/CISC vorbehalten
waren, heutzutage bei beiden Arten zu finden sind. Also z.B. hatten
früher nur die RISC Prozessoren viele Register, im Gegensatz waren
Pipelinening und Sprungvorhersage (evtl. auch Caching) den CISC
Prozessoren vorbehalten. Heute muss man sich nur mal den ARM Cortex-M4
oder noch besser den M7 anschauen, der hat so einiges eingebaut.
Wobei das größtenteils die logische Konsequenz aus dem Verkleinern von
Strukturen etc. ist. Aber warum hatten die CISC früher dann so wenig
Register? Die paar Flip-Flops machen neben den vielen anderen
Transistoren auch nicht mehr viel aus.
A. K. schrieb:> Peter D. schrieb:>> Zum indirekten Zugriff kannst Du ihn nur zwingen, indem Du den Pointer>> übergibst und das Inlinen verbietest.>> Meiner Erfahrung nach nimmt er mal LDS/STS und mal LD/ST R+. Eine> einfach nachvollziehbare Regel habe ich noch nicht gefunden. Und nicht> immer ist die Wahl optimal.
Wer ne Idee hat, wie das besser get, bitte vortreten und erklären :-)
Als Preis gibt's dann mindestens Lothars Hochachtung und die der avr-gcc
Nutzer :-)
TriHexagon schrieb:> Also z.B. hatten> früher nur die RISC Prozessoren viele Register,
Immerhin 16 Stück bei VAX und IBM 360.
> im Gegensatz waren> Pipelinening und Sprungvorhersage (evtl. auch Caching) den CISC> Prozessoren vorbehalten.
Nein.
2208!
UART rennt jetzt mit zwei dicken Switches, allerdings wird's durch die
eingestellte Baudrate auch nicht schneller.
Ich vergleiche morgen noch die Längen der ISR (wenn ich Muße hab).
TriHexagon schrieb:> Aber warum hatten die CISC früher dann so wenig> Register?
In der Anfangsphase der 8-Bitter war die Anzahl Transistoren nicht ganz
so unerheblich. Der 6502 hatte grad mal 3500 Transistoren. Ausserdem war
der Prozessor damals nicht wesentlich schneller als der Speicher. Als
sich das änderte kamen Register auf.
> Die paar Flip-Flops machen neben den vielen anderen> Transistoren auch nicht mehr viel aus.
Die 256 Bits der 16 16-Bit-Register des RCA 1802 machen einen nicht
unerheblichen Teil des Dies aus. Ein statisches CMOS Flipflop hat 6-8
Transistoren.
http://www.visual6502.org/images/1802E/RCA_1802E_die_20x_top_p067152_1600w.jpg
@A. K. danke für die ganzen Hintergrundinformationen. Ich bin wohl etwas
zu jung um sowas zu wissen.
Wow gerade mal 3500 Transistoren, es hat sich einiges getan in der Zeit.
Rolf M. schrieb:> Ich warte ja immer> noch auf seine FAT-Implementation oder den TCP/IP-Stack in Assembler.
Oh ja, bitte Moby!
Ich verspreche, dass ich mir dann auch die Mühe mache und das ganze für
den gcc nutzbar zu machen, damit dann alle etwas von einer kleinen,
weitgehend fehlerfreien Implementierung haben, die dann auch noch keinen
einzigen Taktzyklus und kein einziges Byte im Flash herschenkt.
Das heisst: nachdem natürlich gegen einen der weiter verbreiteten
C-Versionen geprüft wurde, ob dem auch wirklich so ist.
Alles was ich von Moby's ASM-Künsten in den Projekten finden konnte,
sine 33 Maschinenbefehle, die irgendwie den ADC benutzen. Was sie genau
tun ist leider nicht dokumentiert, es scheint auch nur ein Fragment zu
sein und ich vermute in C wäre das sowas wie:
ADC_init() und ADC_read() wobei letzteres wohl in einem TimerInt
aufgerufen werden sollte. Zur Doku würden auch die benutzten Register
gehören, denn ein Sicher von solchen ist nicht Bestandteil der "Lib".
In dem Thread geht es übrigens hauptsächlich um einen
Meßbereicheumsetzer LM335 an 5V AVR-ADC. "Elektronische" verhält sich M.
dabei genau so wie "programmatisch".
Was jetzt noch zum aufhübschen fehlt:
- Vielleicht mal ein paar Konstanten für Baudrate,...
- Ich hab's noch nicht so ganz durchschaut: Bringt es etwas, wenn ich
aus einer Modulvariable eine statische Variable in der Funktion mache?
(Bis auf den Scope)
- Das mit der Zusammenfassung der Variablen zur Struktur wollte ich noch
ausprobieren.
Hmm, wenn ich mir jetzt den zeitlichen Verlauf meiner Code-Sparaktion
als Kurve weiter interpoliere, müsst ich doch in 4 oder 5 Tagen den
Speicher restlos von Code befreit haben. Ob das Programm dann wohl noch
läuft?
>müsst ich doch in 4 oder 5 Tagen den Speicher restlos von Code befreit >haben.
Wenn das so ist/wäre, hättest du durch >5Tage Arbeit jetzt den uC
eingespart. Also >5Tage Arbeit für (wieviel?) 10Euro oder weniger?
Wenn der Materialpreis des uC natürlich (drastisch) höher als dein
Gehalt für die Zeit ist, lohnt sich das ja auch ;-)
Falsch gerechnet! Er hat gelernt, wie er auch ohne ASM ans Ziel kommt,
was sich schon bei wenigen switch/case Optimierung, die der Compiler in
ms macht, auszahlt.
Horst S. schrieb:> 2032!> Die 2k-Grenze hab' ich geknackt.
Nur Pech für dich, dass es in der Serie keinen kleineren Controller
als einen ATmega48 gibt. :-)
> UARTTelegramV3.c
Bitte lieber als Anhang posten.
> - Vielleicht mal ein paar Konstanten für Baudrate,...> - Ich hab's noch nicht so ganz durchschaut: Bringt es etwas, wenn ich> aus einer Modulvariable eine statische Variable in der Funktion mache?> (Bis auf den Scope)
Nur den Scope, du kannst dir also sicher sein, dass die Daten niemand
von außen manipulieren kann.
Matthias L. schrieb:> Wenn der Materialpreis des uC natürlich (drastisch) höher als dein> Gehalt für die Zeit ist, lohnt sich das ja auch ;-)
Sorry, wenn ich das rechne, bekomme ich eine Nulldivision. Für's Proggen
zahl ich mir nix.
Jörg W. schrieb:> Bitte lieber als Anhang posten.Jörg W. schrieb:> Nur den Scope, du kannst dir also sicher sein, dass die Daten niemand> von außen manipulieren kann.
Werd's mir merken.
@Horst
welche Compileroptionen verwendest du?
Bei Projekten mit vielen Dateien hilft "-Os -flto -fuse-linker-plugin"
viel. Das muss in die CFLAGS und LDFLAGS. Ist erst ab gcc-4.9 wirklich
sinnvoll.
Hallo Moby,
Moby schrieb:> Für Dich steht da allerdings auch noch eine Aufgabe an:> Dem SerialComInstruments wirklich Paroli zu bieten ;-)
Lesen lernen: das hab' ich schon.
Liebe Grüße,
Karl
Lothar M. schrieb:> Horst S. schrieb:>> Warum benötige ich im Assembler-Projekt "nur" 2910 Bytes, in C aber>> "satte" 3278 Bytes?> Dieser klitzekleine(!) Mehrpreis ist das, was du dafür bezahlst, dass du> dein Programm auch in 1 Jahr noch verstehst, erweitern und warten> kannst.
Äh, Lothar (fast hätte ich Löthar geschrieben, das hätte aber wohl eher
in "Platinen" gepaßt ;-)), wir sind hier schon weiter. Mit ein paar
wenigen Handgriffen ist das C-Kompilat mittlerweise über 13% kleiner als
der von Horst gepostete Assembler-Code, und Horst hat in dankenswerter
Offenheit eingestanden, daß er selbst wohl nie auf die Optimierungen
gekommen wäre, die der C-Compiler vorgenommen hat. Deshalb sind Mobys
"Beiträge" diesmal noch lächerlicher und absurder als sonst. ;-)
Liebe Grüße,
Karl
avion23 schrieb:> Bei Projekten mit vielen Dateien hilft "-Os -flto -fuse-linker-plugin"> viel. Das muss in die CFLAGS und LDFLAGS. Ist erst ab gcc-4.9 wirklich> sinnvoll.
"-Os -flto" läuft auch schon in 4.7.2 sehr gut und spart jede Menge ein.
C hat den Charme, man kann sich voll auf den Algorithmus konzentrieren
und muß sich nicht durch LD,ST,PUSH,POP und weiteren Ballast unnötig
ablenken lassen.
Ich kenn das auch noch aus meiner Assemblerzeit, man war heilfroh,
überhaupt eine funktionierende Lösung gefunden zu haben und hatte wenig
Lust daran noch weiter zu feilen. Und man dachte, die CPU ackert zu 99%,
kann also nichts anderes mehr machen.
Aber später unter C nen anderen Algorithmus probiert und schwups waren
es nur noch 10% Auslastung. Und dann überlegt man, was mache ich bloß
für andere Tasks mit hinein, daß die CPU wieder gut zu tun hat?
Hallo Moby,
Moby schrieb:> Karl Käfer schrieb:>> Lesen lernen: das hab' ich schon.>> Verstehen lernen: Simpel geht anders.lol Für Könner ist das trivial. Kinder, Hausfrauen und Vorstände
können das natürlich nicht verstehen.
> Aber ich weiß ja, das kannst Du nicht ;-)
Solange es reicht, um Dich zu überfordern, ... :-)
Liebe Grüße,
Karl
Karl Käfer schrieb:>> Aber ich weiß ja, das kannst Du nicht ;-)>> Solange es reicht, um Dich zu überfordern, ... :-)
Könntet ihr diese Art von Plänkeleien bitte auf private Emails
verlagern? Danke.
Ich verstehe das ganze Geschreibe hier wieder einmal nicht so ganz. Es
geht wieder lediglich um diese Nerd typischen Kompetenz- und
Selbstdarstellungsspielchen . Jedem der halbwegs was vom Programmieren
versteht und mal einen Schritt zurück tritt und einen objektiven Blick
auf das ganze wirft, wird anerkennen müssen das natürlich Assembler
wenn's von einem programmiert wird der es kann den kompaktesten und
performensten Code erzeugen wird. Im Falle eines idealen Compilers -den
gibt es aber nicht- ist der Maschinencode gleich schnell und gleich
groß, aber niemals größer oder langsamer als der Compilercode. Nicht
einmal theoretisch ist das möglich. Klar das man in der Realität
komplexe Anwendungen nicht zur Gänze in Assembler schreiben wird, es sei
man hat zu viel Zeit oder ist Masochist. Meine persönliche Strategie mit
der ich bisher immer gut gefahren bin bezüglich Performance und Codesize
ist es C/C++ mit Assembler zu kombinieren. So habe ich im Laufe der Zeit
viele Funktionen aus der Standard Lib des GCC durch eigene, in Assembler
programmierte ersetzt. ISR's oder Funktionen zur direkten
HW-kommunikation mit Peripheriebausteinen werden ebenfalls in Ass
geschrieben. Jegliche Ablaufsteuerung geht in der Hochsprache auf. Für
mich ist es dass beste Konzept und erleichtert zudem in den meist
kritischen Bereichen des Programms das Debuggen ungemein. Ich werde dies
auch so weiter machen. Selbst nach dem umstieg auf IAR gibt es
Optimierungsmöglichkeiten an der Arbeit des Compilers.
Thomas H. schrieb:> Jedem der halbwegs was vom Programmieren> versteht und mal einen Schritt zurück tritt und einen objektiven Blick> auf das ganze wirft, wird anerkennen müssen das natürlich Assembler> wenn's von einem programmiert wird der es kann den kompaktesten und> performensten Code erzeugen wird.
Das habe ich auch mal gedacht, würde es aber inzwischen bestreiten.
Außer der Programmierer ist wirklich bereit unwartbaren Code zu
schreiben. Dazu sollte ein ernsthafter ASM-Programmierer aber nicht
bereit sein. Und selbst wenn behaupte ich auch mal gibt es nicht so
viele Programmierer die mit einem modernen Compiler mithalten können
(vielleicht gibt es sogar keinen?)
Dumdi D. schrieb:> Das habe ich auch mal gedacht, würde es aber inzwischen bestreiten.
Meine Betrachtung war technisch theoretisch. Daran gibts nichts zu
bestreiten. Ein Compiler ordnet und kombiniert letzten Endes
Assemblermakros. Die mal von einem Assemblerprogrammierer erstellt
wurden. Er kann also niemals kleinern Code ausspucken als ein
Assembler-Programmierer. Das keiner der noch alle Latten im Zaun hat
komplexe Programme zur Gänze händisch ohne das Hilfsmittel Compiler in
Assembler schreibt habe ich auch mehr als deutlich zum Ausdruck
gebracht.
Thomas H. schrieb:> Er kann also niemals kleinern Code ausspucken als ein> Assembler-Programmierer.
Sollte man etwas anders formulieren: Er kann also niemals kleinern Code
ausspucken als die weltbesten Assembler-Programmierer.
Bereiche in denen ASM die Nase vorn hat sind meiner Meinung nach bei
Instructions für die es in C so kein Ersatz gibt. Zum Beispiel Add with
Carry. In C kann man zwar auch rauskriegen ob eine Addition ein Carry
produziert und dann später auf die höherwertigen Bytes draufaddieren.
Ich habe es ehrlich gesagt noch nicht ausprobiert aber mich würde es
wundern wenn der Compiler das durchschaut und merkt, dass das ganze Zeug
eigentlich nur eine Instruction ist. Andere Beispiele sind
Multiplikationen bei denen man aus zwei n-Bit ints ein 2n-Bit Ergebnis
kriegt und Divisionen wo man den Rest auch gleich dazu kriegt. Für sowas
gibts immerhin Intrinsics die ich immer dann benutze wenns richtig
schnell werden muss (nicht AVR bezogen, sondern auf dem PC). Die
Autovectorizer von Compilern funktionieren auch nicht wirklich
zufriedenstellend. Da kann man auch besser direkt die SIMD Intrinsics
hinschreiben die man braucht.
Thomas H. schrieb:> Er kann also niemals kleinern Code ausspucken als ein> Assembler-Programmierer.
Das ist natürlich richtig. Aber es gibt Code, der sich mit vertretbarem
Aufwand nur automatisch erzeugen lässt.
Ich hatte oben einen binären Suchbaum aus Vergleichen erwähnt, als
Implementierung von switch. Sinngemässer als rekursiver Generator:
1
vergleiche X mit A
2
goto L1 wenn grösser
3
goto case(A) wenn gleich
4
betrachte auf die gleiche Weise alle Fälle von X < A
5
L1: betrachte auf die gleiche Weise alle Fälle von X > A
Nun ist so ein Code zwar länger als der kürzestmögliche, passt also
nicht exakt zum Thread, aber er ist bei zufällig verteilten switch-Daten
der schnellste Code für eine nichttriviale Anzahl Fälle, in denen eine
Sprungtabelle nicht einsetzbar ist.
Für einen Assembler-Programmierer ist das ein mittlerer Alptraum, denn
dazu müssen die Werte sortiert werden und ein Wert aus der Mitte des
jeweiligen Intervalls rausgepickt werden. Das ist hässlich viel Arbeit
und die fällt mit jeder Änderung der zu unterscheidenden Fälle
vollständig neu an.
Wenn man dann noch die Kosten von Sprungbefehlen und Sprungvorhersage
einfliessen lassen muss, um bestimmte Arten von Sprüngen zu bevorzugen,
dann ist die schon die Entscheidung arg schwierig, ob dieses Verfahren
sinnvoll ist oder nicht.
Addiere dann noch Profiling hinzu, also die Optimierung anhand von
Testläufen mit daraus resultierender realer Datenverteilung, und aus dem
mittleren Alptraum wird ein schwerer.
Es mag Makroassembler geben, mit denen dieser rekursive Ansatz eines
Vergleichsbaums prinzipiell implementierbar ist, aber mit klassischer
Assembler-Programmierung hat das dann nur noch wenig zu tun.
Ein weiteres Beispiel für Code, der einem Assembler-Programmierer
deutlich Kopfzerbrechen bereitet, ist Optimierung der Abhängigkeiten bei
Prozessoren mit ausgeprägtem Pipelining. Also wenn man drauf achten
sollte, dass je nach Art der Operation eine vom Ergebnis abhängige
Folgeoperation eine Mindestanzahl von Takten entfernt sein sollte.
Das ist sowieso schon nicht trivial und wird dadurch nicht besser, dass
jede neue Generation der Implementierung des Befehlssatzes neue Regeln
für eine solche und ähnliche Optimierung bringt. Da kann der gleiche
Code vorher wunderbar effizient sein, nur um dann aufgrund einer
bestimmten Eigenschaft der Implementierung des Cores bös auf die Nase zu
fallen (z.B. INC/DEC Befehle beim Pentium 4 gegenüber Pentium III).
Mit einem Compiler braucht man den Code bloss für den neuen Core neu
übersetzen.
Das ist zwar bei heutigen vollintegrierten Mikrocontrollern à la Cortex
Mx noch kaum relevant, aber warten wir mal ein paar Jährchen...
Thomas H. schrieb:
> Er kann also niemals kleinern Code ausspucken als ein> Assembler-Programmierer.
Das ist falsch!
Richtig wäre "als der ideale Code". Aber dazu braucht man für
nichttriviale Probleme den einen allerbesten Programmierer. Die Frage
ist eher, wieviel Prozent der ASM-Programmierer bekommen das besser hin,
als der Compiler, und in einem konkreten Fall, ist man selbst unter
diesen. Besonders in zweiten Punkt kann man sich massiv verschätzen.
Nichts spricht natürlich dagegen, die ISR, die nur ein GPOIR0-Bit
setzen soll, in (Inline-)Assembler hinzuschreiben. Wenn man sicher ist,
daß man da nichts mehr dran bauen will/muß.
Carl D. schrieb:>> Er kann also niemals kleinern Code ausspucken als ein>> Assembler-Programmierer.>> Das ist falsch!
Was ein Compiler erzeugen kann, das kann rein theoretisch betrachtet
auch ein Assembler-Programmierer erzeugen. Dem Prinzip nach.
Nur kann es sein, dass dafür der frisch von der Ausbildung weg
eingestelle Assembler-Programmierer vor Beendigung seiner Arbeit in
Rente geht. ;-)
Soll heissen: Was theoretisch zutrifft kann praktisch falsch sein, weil
nicht realistisch machbar.
A. K. schrieb:> Das ist natürlich richtig. Aber es gibt Code, der sich mit vertretbarem> Aufwand nur automatisch erzeugen lässt.
Na immerhin gibt es zumindest einen der es verstanden hat.
Wenn ich theoretisch Assembler mit C oder einer anderen Hochsprache
vergleiche, dann habe ich dabei keinen komplexen Algorithmus im Kopf
oder gar eine Komplexe Applikation, sondern ein einfaches Codesegment.
Das reicht mir aus um eine Aussage über den Vergleich Assembler vs
Compiler machen zu können. Denn komplexes Programm ist nichts anderes
als eine Aneinanderreihung einfacher codesegmente und letzen Endes
einfacher Instruktionen . Der Compiler macht nichts anderes als den
komplexen Code in einfache Teilaufgaben zu zerlegen. Um die Aussage zu
tätigen das dies theoretisch von einem Assemblerprogrammierer mit
gleichem oder im Falle aller real existierenden Compiler besser erledigt
werden könnte reicht der Vergleich einer so simplen Codesequenz. Weder
habe ich eine Aussage über die Zeit die der Programmierer dazu hat
gemacht noch über die Anzahl der Assemblerprogrammierer auf die Aufgabe
verteilt werden könnte. Auch habe ich klar -und ich sage es zum zweiten
male- zum Ausdruck gebracht das man in der Realität keine Komplexen
Aufgaben nur in Assembler lösen wird.
Carl D. schrieb:> Nichts spricht natürlich dagegen, die ISR, die nur ein GPOIR0-Bit> setzen soll, in (Inline-)Assembler hinzuschreiben. Wenn man sicher ist,> daß man da nichts mehr dran bauen will/muß.
Ich habe nach 36J Assemblerprogramierung schon die eine oder andere ISR
erstellt, die ein wenig mehr macht als lediglich einen Portbit zu
bedienen. Wer allerdings float Berechnungen oder anderen Aufgaben in
einer ISR erledigt von denen er denkt das ginge nur in einer
Hochsprache, der hat eh etwas essentielles nicht verstanden. Auch bin
ich in der Lage später noch etwas an meinem Code zu modifizieren. Von
inline Assembler wie er in GCC zelebriert wird lasse ich prinzipiell die
Finger.
Carl D. schrieb:> Und wir wollten ja mit dem Code fertig sein, bevor Atmel die> AVR-Vertigung einstellt, oder? ;-)
Ob Du weißt, welche Codemassen in Asm für AVR schon existieren? Warum
wohl? Und daß die 8-Bitter jemals obsolet werden wird wohl keiner hier
mehr erleben ;-)
A. K. schrieb:> Was ein Compiler erzeugen kann, das kann rein theoretisch betrachtet> auch ein Assembler-Programmierer erzeugen.
Genau das will er aber gar nicht.
Sondern es selbst in der Hand haben.
Mit all den vielen Vorteilen, die damit einhergehen.
Was den erhöhten Zeitbedarf anbetrifft machen sich viele hier falsche
Vorstellungen.
Der erste Trick ist, bei einer vielseitigen,
/hinreichend/leistungsstarken, typenreichen Architektur zu bleiben. Die
man dann gut kennt. Der zweite, sich universell einsetzbare Programm- &
Peripherie-Codebausteine und eine grundlegende immergleiche
Programmstruktur zuzulegen. Dann ist der Rest nicht viel mehr als
sinnvolle Verknüpfung.
Sicher gibt es programmierer- und projektabhängig irgendwo eine
sinnvolle Grenze, die höhere Sprachen erforderlich macht. Die sehe ich
bei den kleinen AVR Maschinen aber weit weit weg.
Durch Assembler beim assemblerfreundlichen AVR bleiben können- so wird
ein Schuh draus. Hochsprachenverwendung ist einer der wichtigsten
Treiber für permanente Controller-, Architektur- und Programmiermittel-
Wechsel.
Moby schrieb:> Genau das will er aber gar nicht.> Sondern es selbst in der Hand haben.
Du möchtest vielleicht alles selbst in der Hand haben. Das ist okay,
genauso wie Leute nur an einem Esstisch sitzen wollen, den sie höchst
persönlich mit dem Taschenmesser aus einem Baumstamm geschnitzt haben.
Professionelle Entwickler programmieren Lösungsorientiert. Da steht dann
sowohl Performance als auch Codegröße hinter effizienter, fehlerfreier
und langfristig wartbarer Entwicklung weit zurück.
Moby schrieb:> Der zweite, sich universell einsetzbare Programm- &> Peripherie-Codebausteine und eine grundlegende immergleiche> Programmstruktur zuzulegen. Dann ist der Rest nicht viel mehr als> sinnvolle Verknüpfung.
Oder man nimmt sich einen Compiler mit Standard Bibliotheken, der genau
das tut (Programm - und Codebausteine kombinieren und zu optimieren),
nur auf Basis der Erfahrung tausender Hochkarätiger Compilerentwickler.
Im übrigen widerspricht das deiner Forderung danach alles perfekt zu
optimieren. Das sah man dann deinem Tastenentprellen-Blinky Beispiel das
du vor einiger Zeit gepostet hast. Obwohl noch massig Register frei
waren, hat dein Programm völlig unnötig RAM genutzt. Eben weil du statt
komplett handoptimierten Assembler, fertige - selbstgeschriebene - Bibs
verwendet hast.
> Kompliment.> Das möchte ich auch noch erreichen.> Die Hälfte hab ich schon ;-)
ich denke ich mach mit dem GCC und meinen 6 Jahren C kleineren und
wartbareren Code als Du mit deinen 18 Jahren ASM ;)
#MalWiederHolzAuflegen
scelumbro schrieb:> Professionelle Entwickler programmieren Lösungsorientiert.
Ach?
Ich sollte meine vielen funktionierenden Ergebnisse nochmal danach
bewerten, ob es sich wirklich um Lösungen handelt ;-)
> nur auf Basis der Erfahrung tausender Hochkarätiger Compilerentwickler.
Die ist ja toll und die braucht es sicherlich auch- nur nicht bei den
simplen AVRs.
> Im übrigen widerspricht das deiner Forderung danach alles perfekt zu> optimieren.
Von Perfektion rede selbst ich nicht.
> Obwohl noch massig Register frei> waren, hat dein Programm völlig unnötig RAM genutzt.
Ob dahinter auch eine Absicht gesteckt haben könnte? Das war nämlich
eines von vielen kombinierbaren Modulen. Wenn da jedes eigene Register
beanspruchen würde... Hilfe! Nein, da hast Du nur das System nicht
verstanden...
Sich allein auf Register zu beschränken kann man bei ganz kleinen Sachen
machen bei denen sich absehen lässt, daß sie nicht mehr erweitert
werden.
Ingo schrieb:> wartbareren Code
Bildet Euch doch darauf nicht zuviel ein.
Alles eine Frage des Systems, der Doku und eben der Programmiersprache:
Asm als Klartext ist selbsterklärend.
Hallo Thomas,
Thomas H. schrieb:> Jedem der halbwegs was vom Programmieren> versteht und mal einen Schritt zurück tritt und einen objektiven Blick> auf das ganze wirft, wird anerkennen müssen das natürlich Assembler> wenn's von einem programmiert wird der es kann den kompaktesten und> performensten Code erzeugen wird. Im Falle eines idealen Compilers -den> gibt es aber nicht- ist der Maschinencode gleich schnell und gleich> groß, aber niemals größer oder langsamer als der Compilercode.
Dein Ansatz geht davon aus, daß es perfekte Assembler-Programmierer
gibt, solche also, die perfekten Code schreiben können. Das gibt es
tatsächlich aber nur bei den allertrivialsten Programmen.
Mit zunehmender Funktionalität, mithin Größe des Codes, wird die Sache
aber immer schwieriger. Irgendwann sind die Grenzen des menschlichen
Fassungsvermögens erreicht, auch des besten Programmierers aller Zeiten.
Spätestens da schlägt dann die Stunde der Compiler, die zwar weniger
kreativ sein mögen als ein menschlicher Programmierer und Optimierer,
die dafür aber ein schier unerschöpfliches Fassungsvermögen haben.
Der Punkt, auf den ich hinauswill, ist: im realen Leben gibt es leider
keinen perfekten Programmierer, und von daher ist die Annahme, daß ein
perfekter Programmierer den perfekten Code schreiben könnte, letztlich
schlicht unrealistisch. Wenn Du von dieser Prämisse ausgehen wolltest,
müßtest Du einen perfekten Programmierer mit einem perfekten Compiler
vergleichen, und am Ende würden beide genau denselben perfekten Code
hervorbringen.
Wenn man also etwas vom Programmieren versteht, einen Schitt zurück
tritt und einen objektiven Blick auf das Ganze werfen will, dann kommt
man nicht an der Erkenntnis vorbei, daß es so etwas wie perfekte
Programmierer oder perfekte Compiler in der realen Welt nicht gibt. Das
bedeutet, daß wir uns mit unseren eigenen Unzulänglichkeiten als
Menschen und auch mit jenen der Maschinen arrangieren müssen, und daß es
nunmal Tätigkeiten gibt, die eine Maschine besser, schneller und
fehlerärmer erledigen kann als wir. Sonst würden wir ja gar keine
Maschinen bauen und benutzen, oder?
Daher gilt für Compiler, daß sie auch bei nichttrivialen Programmen
immer noch alle Variablen und Verzweigungen quasi "im Kopf" behalten
können, wo unser Verstand schon längst mit einem Pufferüberlauf
ausgestiegen ist, so daß ein Compiler mit zunehmender Komplexität des
Programms immer bessere Ergebnisse erzielt als ein noch so guter
Programmierer.
Deswegen haben die Hochsprachen heute längst gewonnen, überall. Bei den
Atmel AVRs wurde sogar das Hardware-Design eigens für die Benutzung mit
Hochsprachen ausgelegt, so daß es etwas anachronistisch und ewiggestrig
erscheint, ausgerechnet diese Mikrocontroller vollständig mit Assembler
programmieren zu wollen. Die Daseinsberechtigung von Assembler auf AVRs
erschöpft sich daher heute in nur zwei Anwendungsfällen: für besonders
zeitkritische Programmteile, die mit in C eingebettetem Assembler-Code
eine bessere Kontrolle über das Timing ermöglichen, sowie zweitens als
Zwischenschritt der Kompilierung einer Hochsprache.
Liebe Grüße,
Karl
PS: Lieber Jörg, ich werde zu gerne darauf verzichten, Nickeligkeiten
mit diesem "Herrn" auszutauschen, sowohl hier, als auch per E-Mail. Ich
würde mich aber freuen, wenn ich nicht ständig grundlos von ihm
provoziert und beim ersten Gegenhalten meinerseits zurechtgewiesen
würde. Immerhin gibt es da ja so etwas wie Ursache und Wirkung. Nix für
ungut, danke.
Thomas H. schrieb:> Jedem der halbwegs was vom Programmieren versteht und mal> einen Schritt zurück tritt und einen objektiven Blick auf das> ganze wirft, wird anerkennen müssen das natürlich Assembler> wenn's von einem programmiert wird der es kann den kompaktesten> und performensten Code erzeugen wird.
Nicht selten ist das dann so wie mit physikalischen Theorien; zu einer
solchen meinte Hawking mal:
"That's nice. Too bad it's wrong".
Auf kiki Architekturen wir AVR ist es noch mehr oder weniger trivial,
effizienten und korrekten Assembler zu schreiben.
Aber auf einer multiskalaren Maschine mit 20-schrittigen Pipelines,
Caches, Prefetch-Buffers, oder netten "Features" wie exposed Pipeline,
Out-of-Order Execution etc.
Selbt ohne all diese Nettigkeiten ist die beste Codesequenz nicht
naheliegend. Instruktives Beispiel: Laden eines Immediate auf ARM:
Für den Fall, dass die Konstante besser direkt geladen wird (anstatt sie
in einem const-Pool abzulegen u vo ndort zu lagen) verwenden GCC über
1000 Zeilen seiner Quellen. Ich würd mal sagen, dass ein
Asm-Programmiere nicht ad hoc die beste Sequenz findet.
Übel wird es auch, wenn neue Konstanten zum const-Pool hinzugefügt
werden und Sprungbefehle eingefügt werden müssen um den Pool zu
umspringen. In Asm tut sich das doch niemand an, oder?
unbelegt und falsch schrieb:> Moby schrieb: Asm als Klartext ist selbsterklärend.>> Schon mal in das Programm eines anderen Programmieres gelinst?> Klingt nicht so.
Ja muß man das nun auch noch erklären?
Steht mit Asm nicht etwa genau das auf dem Papier was passiert? Eine
kurzer Kommentar zur Funktion noch und gut ist!
Zum Verständnis gehört im Falle des Falles aber immer das Datenblatt.
Was auch C-Programmierern keinesfalls schadet!
Moby schrieb:> scelumbro schrieb:>> Obwohl noch massig Register frei>> waren, hat dein Programm völlig unnötig RAM genutzt.>> Ob dahinter auch eine Absicht gesteckt haben könnte? Das war nämlich> eines von vielen kombinierbaren Modulen. Wenn da jedes eigene Register> beanspruchen würde... Hilfe! Nein, da hast Du nur das System nicht> verstanden...> Sich allein auf Register zu beschränken kann man bei ganz kleinen Sachen> machen bei denen sich absehen lässt, daß sie nicht mehr erweitert> werden.
Ich habe dein System sehr wohl verstanden. Dein genialer selbst
Entwickelter Ansatz ist der Hochsprachenwelt seit Jahrzehnten bekannt.
Es kommt ja auch kein C Programmierer auf die Idee, printf & Co selbst
zu implementieren.
Aber einerseits redest du andauernd vom Compiler bloat, andererseits
erzeugst du - auf dieses konkrete Projekt bezogen - ganz eindeutig
unnötigen Code Bloat mit der Verwendung eines handgebauten aber nicht
projektoptimierten Moduls. Ist Compiler generierter Bloat schlechter als
handgenerierter Bloat? Schau dir auch bitte mal die Geschichte der C
Compiler an, vielleicht wird dir dann klar das du ein uraltes Rad neu
erfindest - und dann auch noch viereckig.
Johann L. schrieb:> Auf kiki Architekturen wir AVR ist es noch mehr oder weniger trivial,> effizienten und korrekten Assembler zu schreiben.
Na also. Genauso ist es.
Und das Schönste: Mit kiki läßt sich immer noch jede Menge anstellen.
Und zwar kiki im Vergleich zu hochgezüchteten C auf ARM Lösungen...
scelumbro schrieb:> Moby schrieb:> scelumbro schrieb:> ganz eindeutig> unnötigen Code Bloat mit der Verwendung eines handgebauten aber nicht> projektoptimierten Moduls.
Na mein Eindruck ist ganz eindeutig,daß Du das System eben nicht
verstanden hast und auch nicht vorhast, es zu verstehen.
> vielleicht wird dir dann klar das du ein uraltes Rad neu> erfindest - und dann auch noch viereckig.
Auf das System als solches erhebe ich weißgott keine Urheberansprüche.
Ich weiß aber, daß es auf diese Weise recht schnell rund läuft und eben
nicht viereckig ;-)
Moby schrieb:> Na mein Eindruck ist ganz eindeutig,daß Du das System eben nicht> verstanden hast und auch nicht vorhast, es zu verstehen.
Erleuchte mich und die anderen Jünger des großen Compilers doch bitte.
scelumbro schrieb:> Erleuchte mich und die anderen Jünger des großen Compilers doch bitte.
Lies einfach noch mal meine Erklärung weiter oben warum ich im konkreten
Fall das heilige RAM anzapfe.
Und meinst Du wirklich, ich hätte den Anspruch zu "erleuchten" ?
Es kann ja sein daß Simplizität und Effizienz von Asm nicht in die
heutige Zeit passt wo es heisst: Komplex ist cool und macht Eindruck.
Trotzdem gebe ich meine Erfahrungen weiter, und die stehen unter der
Maxime: Keep it simple!
Karl Käfer schrieb:> Daher gilt für Compiler, daß sie auch bei nichttrivialen Programmen> immer noch alle Variablen und Verzweigungen quasi "im Kopf" behalten> können, wo unser Verstand schon längst mit einem Pufferüberlauf> ausgestiegen ist, so daß ein Compiler mit zunehmender Komplexität des> Programms immer bessere Ergebnisse erzielt als ein noch so guter> Programmierer.
Deshalb schrieb ich:
Thomas H. schrieb:> Wenn ich theoretisch Assembler mit C oder einer anderen Hochsprache> vergleiche, dann habe ich dabei keinen komplexen Algorithmus im Kopf> oder gar eine Komplexe Applikation, sondern ein einfaches Codesegment.> Das reicht mir aus um eine Aussage über den Vergleich Assembler vs> Compiler machen zu können. Denn komplexes Programm ist nichts anderes> als eine Aneinanderreihung einfacher codesegmente und letzen Endes> einfacher Instruktionen . Der Compiler macht nichts anderes als den> komplexen Code in einfache Teilaufgaben zu zerlegen. Um die Aussage zu> tätigen das dies theoretisch von einem Assemblerprogrammierer mit> gleichem oder im Falle aller real existierenden Compiler besser erledigt> werden könnte reicht der Vergleich einer so simplen Codesequenz. Weder> habe ich eine Aussage über die Zeit die der Programmierer dazu hat> gemacht noch über die Anzahl der Assemblerprogrammierer auf die Aufgabe> verteilt werden könnte. Auch habe ich klar -und ich sage es zum zweiten> male- zum Ausdruck gebracht das man in der Realität keine Komplexen> Aufgaben nur in Assembler lösen wird.Karl Käfer schrieb:> so daß es etwas anachronistisch und ewiggestrig> erscheint, ausgerechnet diese Mikrocontroller vollständig mit Assembler> programmieren zu wollen.
Exact was ich geschrieben habe.
Bastler schrieb:> Wenn 18 Jahre Assembler zu diesem Ergebnis führen:> Beitrag "Re: Analoger Sensor (LM355) mit Operationsverstärker (+AVR> Asm-Code)"> dann hätte man die Zeit besser in was anderes investiert.> (andere Beispiele für Code von unserem Freund sind leider nicht zu> finden)
Stell Dir vor, das Ding ist im Einsatz und es macht seine Sache gut.
Kann aber verstehen, wenn es mancher gern komplizierter gelöst hätte ;-)
Moby schrieb:> Bastler schrieb:>> Wenn 18 Jahre Assembler zu diesem Ergebnis führen:>> Beitrag "Re: Analoger Sensor (LM355) mit Operationsverstärker (+AVR>> Asm-Code)">> dann hätte man die Zeit besser in was anderes investiert.>> (andere Beispiele für Code von unserem Freund sind leider nicht zu>> finden)>> Stell Dir vor, das Ding ist im Einsatz und es macht seine Sache gut.> Kann aber verstehen, wenn es mancher gern komplizierter gelöst hätte ;-)
Eine Lösung dieses Problemchens in einer Hochsprach würde nur für
jemanden komplizierter Aussehen, der diese Hochsprache nicht verstünde.
Moby schrieb:> Stell Dir vor, das Ding ist im Einsatz und es macht seine Sache gut.
Die "Sache" ist so ein kleines Problem, wenn du da noch etwas verkehrt
gemacht hättest, dann stimme ich dem Vorposter 2x zu. So aber auf
jedenfall einmal.
Du machst deine Rolle als Gruppenkasper noch besser als
Assemblerprogrammierer ;-) Um Längen sogar.
Thomas H. schrieb:> Von inline Assembler wie er in GCC zelebriert wird lasse ich prinzipiell> die Finger.
GCCs Inline-Assembler ist einsame Spitze. Wenn du mal eine Krücke
wie den IAR da gesehen hast, bei dem du dich im Inline-Asm bestenfalls
auf globale Variablen verlassen kannst (alles andere könnte sich
bereits in der nächsten Compilerversion ja geändert haben, weil es
letztlich implementation defined ist), dann weißt du, warum die auf
den ersten Blick umständlich und kryptisch anmutende Variante des GCC
wirklich gut ist: sie gestattet es, dort, wo man es tatsächlich mal
braucht, handoptimierten Assemblercode einzuflechten, der auch über
ein paar Generationen des Compilers Bestand haben kann, ohne dabei
dem Compiler bei seinen Optimierungsstrategien im Weg herum zu stehen.
(Bezüglich der „Krücke“: der IAR ist sonst ein wirklich guter Compiler.
Aber an dieser Stelle ist er einfach nur <zensiert>.)
unbelegt und falsch schrieb:>> Moby schrieb: Asm als Klartext ist selbsterklärend.>> Schon mal in das Programm eines anderen Programmieres gelinst?
Das einzige Schnipsel Code, was wir von ihm hier bislang sehen durften,
führt seine Behauptung doch bereits komplett ad absurdum. Damit
erübrigt sich jegliche weitere Diskussion.
Jörg W. schrieb:>>> Moby schrieb: Asm als Klartext ist selbsterklärend.>>>> Schon mal in das Programm eines anderen Programmieres gelinst?>> Das einzige Schnipsel Code, was wir von ihm hier bislang sehen durften,> führt seine Behauptung doch bereits komplett ad absurdum. Damit> erübrigt sich jegliche weitere Diskussion.
Was ist an
Moby schrieb:> Steht mit Asm nicht etwa genau das auf dem Papier was passiert? Eine> kurzer Kommentar zur Funktion noch und gut ist!> Zum Verständnis gehört im Falle des Falles aber immer das Datenblatt.> Was auch C-Programmierern keinesfalls schadet!
absurd?
Absurd ist höchstens Dein Einwand...
Jörg W. schrieb
> Wenn du mal eine Krücke> wie den IAR da gesehen hast, bei dem du dich im Inline-Asm bestenfalls> auf globale Variablen verlassen kannst (alles andere könnte sich> bereits in der nächsten Compilerversion ja geändert haben, weil es> letztlich implementation defined ist), dann weißt du, warum die auf> den ersten Blick umständlich und kryptisch anmutende Variante des GCC> wirklich gut ist: sie gestattet es, dort, wo man es tatsächlich mal> braucht, handoptimierten Assemblercode einzuflechten, der auch über> ein paar Generationen des Compilers Bestand haben kann, ohne dabei> dem Compiler bei seinen Optimierungsstrategien im Weg herum zu stehen.
Probleme gibts...
Ich finde die Art der Assembler-Integration sehr gut. Sie ist zwar
gewöhnungsbedürftig, erlaubt aber eine sehr effiziente Integration
kleiner Assembler-Einsprengsel in C Code. Man muss wirklich nur das
absolute Minimum in Asm codieren. Das, was anders nicht geht.
Gleichzeitig behindern diese Sequenzen die Optimierung nicht, weil der
Compiler die dazu nötige Information erhält.
Jörg W. schrieb:> GCCs Inline-Assembler ist einsame Spitze
Spitze von unterirdisch vieleicht. Ich schreibe meinen Assemblercode
extern und linke zusammen.
Jörg W. schrieb:> Wenn du mal eine Krücke> wie den IAR da gesehen hast, bei dem du dich im Inline-Asm bestenfalls> auf globale Variablen verlassen kannst
Habe ich und dem stimme ich zu.
Jörg W. schrieb:> handoptimierten Assemblercode einzuflechten, der auch über> ein paar Generationen des Compilers Bestand haben kann
ein externenes .s File übersteht das hervorragend. Sowohl beim GCC als
auch beim IAR.
Jörg W. schrieb:> Bezüglich der „Krücke“: der IAR ist sonst ein wirklich guter Compiler
Der beste im Moment auf dem Markt.
Thomas H. schrieb:> Spitze von unterirdisch
vieleicht. Ich schreibe meinen Assemblercode
> extern und linke zusammen.
Beides ergibt Sinn, je nachdem um was es geht.
Wer einen kompletten Interrupt-Handler in Asm fomulieren will, der ist
mit einem separaten File besser bedient.
Wer einen einzelnen Befehl oder Sequenzen aus wenigen Befehlen
integrieren will, wie etwa Semaphor-Befehle oder Spezialbefehle für
Steuerregister, der ist mit inline-Asm wesentlich effizienter bedient.
In konventionellem Inline-Asm würde man die gesamten Semphor-Funktionen
von ARM als Asm implementieren. Im GCC Inline-Asm reicht es, die beiden
relevanten Befehle entsprechend zu definieren. Sie Semaphor-Sequenz kann
dann normal in C programmiert werden.
Hallo Thomas,
Thomas H. schrieb:> Exact was ich geschrieben habe.
Das hatte ich in Deinem ersten Beitrag anders verstanden. Mein Fehlerm
entschuldige bitte.
Liebe Grüße,
Karl
Thomas H. schrieb:> Ich schreibe meinen Assemblercode extern und linke zusammen.
Klar, aber das ist ja nicht das Zielgebiet des Inline-Assemblers.
Dort, wo man so hantieren kann, ist doch die Welt auf diese Weise
völlig in Ordnung, und das ist dann sicherlich der beste Weg.
Der Inline-Assembler des GCC ist dort gut, wo man eine möglichst
nahtlose inline Integration eines Stückchens Assemblercode braucht
(also alles, was man eher nicht als eigene Funktion implementieren
will). Dann muss ich mich eben nicht auf ein konkretes Register
festlegen (das der Compiler vielleicht an dieser Stelle lieber mit
etwas anderem belegen würde), sondern kann dem Compiler sagen: „ich
brauche hier irgendein Register“ oder „ich brauche hier eines der
Zeigerregister“.
avion23 schrieb:> @Horst> welche Compileroptionen verwendest du?> Bei Projekten mit vielen Dateien hilft "-Os -flto -fuse-linker-plugin"> viel. Das muss in die CFLAGS und LDFLAGS. Ist erst ab gcc-4.9 wirklich> sinnvoll.
Ich hab hier gcc 4.3.3 (stand zumindest in der html des WInAVR-Pakets).
Ich muss ehrlich gestehen, ich kann mich nicht mehr erinnern, wann ich
den mal installiert hatte und ob die Version an mein altes AVRStudio
(4.10) gebunden war.
Moby schrieb:> Durch Assembler beim assemblerfreundlichen AVR bleiben können- so wird> ein Schuh draus. Hochsprachenverwendung ist einer der wichtigsten> Treiber für permanente Controller-, Architektur- und Programmiermittel-> Wechsel.
Für mich war der Treiber zum Wechsel des Programmiermittels, dass ich
endlich auf den Fischen nicht nur Daten hin- und herschieben will,
sondern vielleicht auch gelegentlich mal etwas RECHNE.
Wenn Du also in Deiner Bastelkiste so was, wie die math.lib (mit den
trigonometrischen Funktionen) schon seit geraumer Zeit in optimierter
Performance in asm herumliegen hast - her damit - find ich gut. Die
gcc-Programmierer küssen Dir sicherlich auch die Füße, wenn Du Sinus und
ArcSin in weniger als 100us berechnen kannst (dann aber bitte ohne
Sprungtabelle, also code- UND performanceoptimiert).
Moby schrieb:> Und meinst Du wirklich, ich hätte den Anspruch zu "erleuchten" ?
warum tauchst du dann regelmaessig in threads zu hochsprachen auf und
zwingst deine missionierung auf? obwohl es die leute nervt?
> Es kann ja sein daß Simplizität und Effizienz von Asm nicht in die> heutige Zeit passt wo es heisst: Komplex ist cool und macht Eindruck.> Trotzdem gebe ich meine Erfahrungen weiter, und die stehen unter der> Maxime: Keep it simple!
asm ist nicht simpel und auch nicht effizient. es zwingt dazu, wie ein
prozessor zu denken statt wie ein mensch. das lenkt vom problem ab, das
man loesen will. das komplexe sieht man dem fertigen programm sowieso
nicht an. es waere dumm, etwas unnoetig komplex zu machen, wenn es
hinterher sowieso keiner bewundert.
Horst S. schrieb:> Für mich war der Treiber zum Wechsel des Programmiermittels, dass ich> endlich auf den Fischen nicht nur Daten hin- und herschieben will,> sondern vielleicht auch gelegentlich mal etwas RECHNE.
Stimmt. Erwischt. In meinen Projekten gibt es meist nur wenige
aufwendige Berechnungen. Wenn, dann bediene ich mich ausnahmsweise mal
an fremden Routinen, so wie sie zum Beispiel in den empfehlenswerten
Asm-Büchern von Manfred Schwabl-Schmidt oder im Netz zu finden sind.
Im Punkt Berechnungen ist man mit Hochsprache zugegebenermaßen bequemer
unterwegs. Das ist dann aber auch schon der einzige Moment, neidisch
hinüberzuschielen :-)
Klaus Peters schrieb:> warum tauchst du dann regelmaessig in threads zu hochsprachen auf und> zwingst deine missionierung auf? obwohl es die leute nervt?
Aufzwingen? Werd doch nicht albern. Und wer fragt denn was mich nervt?
Also das kann wirklich kein Kriterium sein. Wenn das Darstellen der
Vorteile von Asm missionierend wirkt, dann vielleicht wegen der Vorteile
von Asm ?
> asm ist nicht simpel und auch nicht effizient. es zwingt dazu, wie ein> prozessor zu denken statt wie ein mensch. das lenkt vom problem ab, das> man loesen will. das komplexe sieht man dem fertigen programm sowieso> nicht an. es waere dumm, etwas unnoetig komplex zu machen, wenn es> hinterher sowieso keiner bewundert.
In diesem Einwand kommt für mich nur mangelnde Erfahrung mit Asm zum
Ausdruck, sorry.
Das zunächst bequemer scheinende C bringt in der Folge nur mehr und mehr
künstliche Probleme mit sich, die man ohne nicht hat. C-Threads sind
voll davon... Ein AVR braucht i.d.R. keine Hochsprache. Asm passt
perfekt.
So, das Bullshit-Bingo ist ja jetzt schon mehr als voll...
Mit den ganzen Zeichen hier die nichts mit der Sache zu tun haben, hätte
man glaube ich schon ein Atomkraftwerk programmieren können ;-)
Moby schrieb:>> asm ist nicht simpel und auch nicht effizient. es zwingt dazu, wie ein>> prozessor zu denken statt wie ein mensch. das lenkt vom problem ab, das>> man loesen will. das komplexe sieht man dem fertigen programm sowieso>> nicht an. es waere dumm, etwas unnoetig komplex zu machen, wenn es>> hinterher sowieso keiner bewundert.>> In diesem Einwand kommt für mich nur mangelnde Erfahrung mit Asm zum> Ausdruck, sorry.
Du scheinst noch nie großartig pure Logik implementiert zu haben. Denn
wenn das Problem eben nicht technischer Art ist, sondern logischer, dann
ist eine "technische" Sprache (ASM) eben doch hinderlich und trägt nur
zur Verkomplizierung der Lösung bei. "Wer als Werkzeug nur einen Hammer
hat, sieht in jedem Problem einen Nagel." :P
Moby schrieb:> Ein AVR braucht i.d.R. keine Hochsprache. Asm passt> perfekt.
Nein danke, wenn ich mit einem AVR Dateien auf einer SD Karte lesen und
schreiben muss (FAT Dateisystem), kann ich gern auf Assembler
verzichten. Der Umgang mit "komplexeren" Datenstrukturen ist mit
Assembler ziemlich mühselig.
Moby schrieb:
> Aufzwingen? Werd doch nicht albern.
merkst du es nicht? sind die anderen die geisterfahrer? echt jetzt?
> Und wer fragt denn was mich> nervt?
niemand draengt sich dir auf. nur andersrum.
> Also das kann wirklich kein Kriterium sein. Wenn das Darstellen der> Vorteile von Asm missionierend wirkt, dann vielleicht wegen der> Vorteile> von Asm ?
wegen der penetranz, besserwisserei und unbelehrbarkeit, die du an den
tag legst. viele hier sind lange asm-progger und aus gutem grund zu den
hochsprachen gegangen.
du ignorierst alle argumente, die dir nicht in den kram passen, zeigst
nur kinderkrams und laberst die ganze zeit nur herum. sogar solche
fachleute wie peter danegger widersprechen dir und merkst nix.
>> asm ist nicht simpel und auch nicht effizient. es zwingt dazu, wie > ein>> prozessor zu denken statt wie ein mensch. das lenkt vom problem ab, > das>> man loesen will. das komplexe sieht man dem fertigen programm> sowieso>> nicht an. es waere dumm, etwas unnoetig komplex zu machen, wenn es>> hinterher sowieso keiner bewundert.>> In diesem Einwand kommt für mich nur mangelnde Erfahrung mit Asm zum> Ausdruck, sorry.
sorry es waren drei einwaende. 1. dass asm zum denken als prozessor
zwingt, 2. dass es deswegen vom problem ablenkt, 3. dass es bescheuert
waere dinge komplex zu machen wenn einen dafür keiner bewundern kann.
> Das zunächst bequemer scheinende C bringt in der Folge nur mehr und > mehr> künstliche Probleme mit sich, die man ohne nicht hat.
so ein quatsch. willst du etwa sagen, dass man asm nicht koennen muss?
oder laesst du das nur fuer was gelten, das du nicht kannst?
> C-Threads sind> voll davon...
cthreads sind voll davon, weil mehr leute c benutzen. sogar die meisten
anfaenger sind klug genug.
> Ein AVR braucht i.d.R. keine Hochsprache. Asm passt> perfekt.
er ist fuer die hochsprache c designt worden. sagt atmel selbst.
Klaus Peters schrieb:> Moby schrieb:>> Aufzwingen? Werd doch nicht albern.> merkst du es nicht? sind die anderen die geisterfahrer? echt jetzt?
Was soll die Übertreibung? Was soll dieses Entweder Oder?
Unfug. 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.
> er ist fuer die hochsprache c designt worden. sagt atmel selbst.
Ja das ist so. Die neueren XMegas sogar noch besser.
Daß schmälert umgekehrt aber seine Eignung für Asm in keinster Weise.
Asm ist da aus Prinzip nämlich sehr flexibel ;-)
TriHexagon schrieb:> Du scheinst noch nie großartig pure Logik implementiert zu haben. Denn> wenn das Problem eben nicht technischer Art ist, sondern logischer, dann> ist eine "technische" Sprache (ASM) eben doch hinderlich und trägt nur> zur Verkomplizierung der Lösung bei.
Nun, für viele viele MSR- und Steuerungsanwendungen brauchts das nicht.
Und stell Dir vor, für Logik gibts eigene Controller-Befehle!
Das muß man bei weitem nicht so hoch hängen...
> Nein danke, wenn ich mit einem AVR Dateien auf einer SD Karte lesen und> schreiben muss (FAT Dateisystem), kann ich gern auf Assembler> verzichten. Der Umgang mit "komplexeren" Datenstrukturen ist mit> Assembler ziemlich mühselig.
In diesem konkreten Fall magst Du Recht haben.
Diese Sorte Probleme kann man allerdings auch auf speziellere Hardware
auslagern. Schau, ich hab für solche Fälle ein einfach ansteuerbares
VDIP Modul im Einsatz. Was meinst Du wie das flutscht. Solcherlei
Zusatzhardware gibts in großer Fülle. Das muß man heute wirklich nicht
mehr selbst machen!
Klaus Peters schrieb:> du ignorierst alle argumente, die dir nicht in den kram passen
Den Eindruck hat man meistens von der Gegenseite ;-)
Zunächst sollte man die eigene Erfahrung nicht ignorieren.
> fachleute wie peter danegger widersprechen dir und merkst nix.
Die eigene Erfahrung zählt wiegesagt... Die spür ich zuallererst.
Darüber kann man sich doch ganz unaufgeregt austauschen- oder geht das
etwa nicht?
> sorry es waren drei einwaende. 1. dass asm zum denken als prozessor> zwingt, 2. dass es deswegen vom problem ablenkt, 3. dass es bescheuert> waere dinge komplex zu machen wenn einen dafür keiner bewundern kann.
Obwohl ohne Hoffnung, es einem Nicht-ASMler zu erklären dazu soviel:
Punkt1: Wie ein Controller zu denken spielt sich noch (mindestens) eine
Ebene tiefer ab. Asm zwingt in allererster Linie zur Kenntnis des
Controllers. Ermöglicht ja gerade dadurch die feinere Anpassung an den
Controller. Ermöglicht ja gerade dadurch jenes Plus an Performance und
Minus an Platzbedarf. Sicher ermöglicht Hochsprache, Probleme abstrakter
fassen zu können. Mit allen bekannten Nachteilen. Ich als ASMler bin
darauf nicht angewiesen. Und viele andere auch (Punkt2).
Punkt3: Kompliziert gehts prinzipiell in jeder Sprache. ASM vereinfacht
insofern, als daß die Dinge auf direkte Weise angepackt werden. Viele
viele künstliche Konstruktionen der Hochsprache überflüssig werden.
Nimm sowas dämliches wie einen Cast-Operator... Ein typisches
Kunstproblem, daß man sich mit erst mit dem Datentypkonzept einhandelt.
Und was die Bewunderung anbetrifft... Jo mei. Die notwendige Komplexität
meiner Haussteuerung zum Beispiel soll doch in erster Linie nur
funktionieren! Dann bin ich schon glücklich.
Moby schrieb:> Ermöglicht ja gerade dadurch jenes Plus an Performance und> Minus an Platzbedarf.
Schon wieder erzählst du uns von dem 'Plus an Performance und Minus and
Platzbedarf', veröffentlichst aber Code der offensichtlich noch nicht
optmiert ist. Ja was den nun?
> Nimm sowas dämliches wie einen Cast-Operator... Ein typisches> Kunstproblem, daß man sich mit erst mit dem Datentypkonzept einhandelt.
Glaubst du wirklich, der Compiler könnte nicht von alleine Casts setzen
wenn die Compilerprogrammierer es wollten? Explizite Casts sind dazu
da, Fehler zu vermeiden in dem sie den Programmierer zwingen 1. nochmal
darüber nachzudenken ob ein Cast zwischen inkompatiblen Datentypen an
dieser Stelle überhaupt richtig ist 2. Einen potentiell 'gefährlichen'
Cast durch explizites hinschreiben zu dokumentieren. Hier geht es also
allein darum Programmierfehler zu vermeiden. Im generierten
Maschinencode ist übrigens die Cast operation nicht mehr zu sehen,
kostet also weder Performance noch Platz. Und 'komplexer' wird der Code
nicht, im Gegenteil er wird besser lesbar - wenn man den C lesen kann.
Es sei den du misst Komplexität an der Anzahl der für den Programmcode
benötigten Zeichen.
Und spätestens wenn du mal statt 8-Bit Ints mit 32 Bit ints oder gar
floats rechnen darfst, ist das mit der 'Komplexität' sowieso ein anderes
Thema. Für den C Programmierer ist es nur ein anderer Datentyp.
> Und was die Bewunderung anbetrifft... Jo mei. Die notwendige Komplexität> meiner Haussteuerung zum Beispiel soll doch in erster Linie nur> funktionieren! Dann bin ich schon glücklich.
Publizier doch bitte mal deine Haussteuerung. Ein Haussteuerungsprojekt
komplett in ASM, wäre wirklich ein schönes Beispiel für ein großes
Projekt.
Scelumbro schrieb:> Schon wieder erzählst du uns von dem 'Plus an Performance und Minus and> Platzbedarf', veröffentlichst aber Code der offensichtlich noch nicht> optmiert ist. Ja was den nun?
Der ist für seine geplanete Anwendung sogar schon sehr gut optimiert.
So gut, daß sich bislang keiner getraut hat, mit mit C gegenzuhalten.
Den kann ich gern nochmal anhängen- allein, ich vermute, ein echtes
Interesse besteht da nicht. Hier gehts eher um Bashing gegen ASM...
> Explizite Casts sind dazu> da, Fehler zu vermeiden in dem sie den Programmierer zwingen 1. nochmal> darüber nachzudenken ob ein Cast zwischen inkompatiblen Datentypen an> dieser Stelle überhaupt richtig ist 2. Einen potentiell 'gefährlichen'> Cast durch explizites hinschreiben zu dokumentieren. Hier geht es also> allein darum Programmierfehler zu vermeiden.
Die man in ASM gar nicht erst macht ;-)
Da gibts kein "inkompatible Datentypen"-Wissenschaft.
> Im generierten> Maschinencode ist übrigens die Cast operation nicht mehr zu sehen,> kostet also weder Performance noch Platz.
Ach? Hatte ich das vermutet? Ich spiele auf sinnlos Verkomplizierung des
Quellcodes durch Konzepte/Konstruktionen aller Art an- war das nun nicht
eindeutig?
> Und spätestens wenn du mal statt 8-Bit Ints mit 32 Bit ints oder gar> floats rechnen darfst
Ja ja rechnen. Ist ja gut und schön. Braucht man für AVR-MSR aber nur
selten.
> Publizier doch bitte mal deine Haussteuerung. Ein Haussteuerungsprojekt> komplett in ASM, wäre wirklich ein schönes Beispiel für ein großes> Projekt.
Das könnte Dir so passen... Sonst noch Wünsche?
Und jetzt kommt die Frechheit: Trotzdem sag ich weiter meine Meinung ;-)
Ich kann die ganze Diskussion um Assembler <-> C überhaupt nicht
verstehen.
Wer sich einfach mal die letzten 20 Jahre anschaut, wird erkennen, dass
Hardware sich stetig weiterentwickelt. Dagegen sind Software-Algorithmen
in der Entwicklungsgeschwindigkeit lahme Schnecken.
Algorithmen, die man einmal programmiert hat, kann man auch 20 Jahre
später weiter verwenden. Die Hardware jedoch nicht, die bekommt man noch
nichtmals mehr zu kaufen.
Wer Assembler programmiert, denkt keine 5 Meter weit. Er schreibt ein
unportables Programm, dass bei einem Hardware-Wechsel komplett
weggeworfen und neu geschrieben werden muss. Ein C-Programmierer muss
sein Programm einfach an die neue Hardware anpassen - fertig.
Nicht portable Programme braucht kein Mensch. Denn sie sind morgen schon
tot.
Notiz an mich selbst: Nicht "mal eben" in der Frühstückspause µC.net
lesen. Man kommt nicht mehr davon los und die Kollegen wundern sich über
das laute lachen.
Frank M. schrieb:> Wer sich einfach mal die letzten 20 Jahre anschaut, wird erkennen, dass> Hardware sich stetig weiterentwickelt. Dagegen sind Software-Algorithmen> in der Entwicklungsgeschwindigkeit lahme Schnecken.>> Algorithmen, die man einmal programmiert hat, kann man auch 20 Jahre> später weiter verwenden. Die Hardware jedoch nicht, die bekommt man noch> nichtmals mehr zu kaufen.
Ach was. AVR gibts schon so lange und die langen noch für viele
weitere... Lasst Euch doch durch technische Entwicklungen nicht so unter
Druck setzen. Aber OK, als Hobbyist kann man das entspannter sehen.
> Wer Assembler programmiert, denkt keine 5 Meter weit. Er schreibt ein> unportables Programm, dass bei einem Hardware-Wechsel
Lies nochmal weiter oben zu den Treibern für Hardware-Wechsel...
> Nicht portable Programme braucht kein Mensch. Denn sie sind morgen schon> tot.
Also meine liebe 128erMega Haussteuerung läuft bald ein ganzes Jahrzehnt
:-)
Walter T. schrieb:> Notiz an mich selbst: Nicht "mal eben" in der Frühstückspause> µC.net> lesen. Man kommt nicht mehr davon los
Ja hast Recht. Kann süchtig machen. Deshalb werd ich mich jetzt auch
wieder anderen Dingen zuwenden und den Thread zur Ruhe kommen lassen ;-)
Einen schönen Tag allen Beteiligten!
Moby schrieb:> Also meine liebe 128erMega Haussteuerung läuft bald ein ganzes Jahrzehnt> :-)
Wie süß.
Ich verdiene mein Geld unter anderem mit C-Programmen. Eines davon, das
nach wie vor aktiv weiterentwickelt wird, gibt es seit Herbst 1992.
Das ist immer noch C, auch wenn der Compiler schon etliche Male durch
einen neuen, besseren ersetzt wurde, und das Betriebssystem, auf dem das
ganze läuft, natürlich auch schon diverse Iterationen und
Verschlimmbesserungen mitgemacht hat.
Und auch wenn die Zielarchitektur bislang immer x86 war, würde es mich
ein müdes Arschrunzeln kosten, mein Programm auf irgendwas anderem
laufen zu lassen, sofern es mindestens 32 Bit breit ist.
Moby schrieb:> Scelumbro schrieb:>> Schon wieder erzählst du uns von dem 'Plus an Performance und Minus and>> Platzbedarf', veröffentlichst aber Code der offensichtlich noch nicht>> optmiert ist. Ja was den nun?>> Der ist für seine geplanete Anwendung sogar schon sehr gut optimiert.> So gut, daß sich bislang keiner getraut hat, mit mit C gegenzuhalten.> Den kann ich gern nochmal anhängen- allein, ich vermute, ein echtes> Interesse besteht da nicht. Hier gehts eher um Bashing gegen ASM...
Ja, bitte, bitte einmal posten...
so das es kompilierfähig ist...idealerweise mit stats von dir
(ram/flash/eep verbrauch).
73
>Das ist dann aber auch schon der einzige Moment, neidisch>hinüberzuschielen :-)> Viele>viele künstliche Konstruktionen der Hochsprache überflüssig werden.
Ist das so?
Wie sieht denn der asm Code für folgendes künstliche Konstrukt aus:
Matthias L. schrieb:> Wie sieht denn der asm Code für folgendes künstliche Konstrukt aus:
Warum sieht das nur so aus, als wollte jemand auf biegen und brechen
einen objektorientierten Ansatz in C emulieren?
>Warum sieht das nur so aus, als wollte jemand auf biegen und brechen>einen objektorientierten Ansatz in C emulieren?
Weil es eben nur C ist. Oder fragst Du auch immer, wenn jemand über ein
Array iteriert:
"Warum sieht das nur so aus, als wollte jemand auf biegen und brechen
ein for each in C emulieren?"
Walter T. schrieb:> Warum sieht das nur so aus, als wollte jemand auf biegen und brechen> einen objektorientierten Ansatz in C emulieren?
Weil du das auf biegen und brechen darin siehst?
Ist ein ganz gewöhnliches Verfahren für Timer-Handler.
>>Warum sieht das nur so aus, als wollte jemand auf biegen und brechen>>einen objektorientierten Ansatz in C emulieren?
Aber indirekt sagst du es ja damit. Weil solche "Konstrukte" mühsam
selbst herzustellen sind, wurde die Sprache C in C++ erweitert, wo sowas
dann als Befehl verfügbar wurde.
Genauso entstand aus ASM mal C. Als man sich nicht mehr damit
beschäftigen wollte, mühsam Schleifen in asm zu schreiben. Das Ziel war
ja nicht die Schleife selbst, sondern das, was in der Schleife
abgearbeitet werden sollte...
A. K. schrieb:> Ist ein ganz gewöhnliches Verfahren für Timer-Handler.
Gibt es da eine Beschreibung zu? An "Good Practice"-Ansätzen bin ich
immer interessiert.
Klaus W. schrieb:> Ist doch einfach (ganz intuitiv runter geschrieben):
Reingefallen. ;-)
Das ist ein Interrupt-Handler, muss also prozessorspezifisch
entsprechend umgesetzt werden.
>Ist doch einfach (ganz intuitiv runter geschrieben):
Und Du meinst, das das leserlicher ist?
Immerhin hat ja
>Walter Tarpan (nicolas)>>Warum sieht das nur so aus, als wollte jemand auf biegen und brechen>>einen objektorientierten Ansatz in C emulieren?
sofort erkannt, was es macht.
Walter T. schrieb:> Gibt es da eine Beschreibung zu? An "Good Practice"-Ansätzen bin ich> immer interessiert.
Stimmt, eines hätte ich zum Thema "Good Practice" anzumerken: Da der
Code stark nach 32-Bit riecht, würde ich raten, lokale Variablen nicht
ohne Not als 8/16-Bit Typen zu deklarieren. GCC kriegt hier zwar spitz,
dass er dafür keine Verrenkungen machen muss, aber das schafft er nicht
immer.
Klaus W. schrieb:> Ist doch einfach (ganz intuitiv runter geschrieben):>> .ident "GCC: (GNU) 4.8.1"
Der war gut. :-)
Matthias L. schrieb:> Und Du meinst, das das leserlicher ist?
Der war nicht so gut. :-)
Horst S. schrieb:> ...nicht genau der, wo mir weiter oben nahegelegt wurde, ich solle das> wegen fehlender Inline-Möglichkeiten lassen?
So viel zum Prinzipienreiten. ;-)
Die codeseitig optimierte Version schreibt alle Aktionen direkt in die
ISR um beim AVR push/pop-Orgien zu reduzieren. Die modulare Version
macht das wie hier und nimmt einen grösseren Aufwand in Kauf.
Da der Code allerdings mit den Cortexen im Hinterkopf geschrieben wurde
ist das wieder fast egal. Da ist der Unterschied gering.
Das im Grunde die generelle Frage bei Optimierung: auf was man
optimiert. Soll der Prozessor schnellstmöglich fertig werden? Oder soll
der Programmierer schnellstmöglich fertig werden? Letzteres nimmt einen
bisweilen etwas höheren Resourcenverbrauch billigend in Kauf.
@Moby (falls du noch mitliest):
Etwas offtopic und nur aus Interesse:
In dem von Jörg verlinkten Beitrag mit dem ADC-Code für den LM335 kommen
folgende Programmzeilen vor, die mich etwas stutzig machen:
1
:
2
bst IC,7 ;IC7=0: 5V0, IC7=1: 1V1
3
:
4
bst IC,6
5
:
6
7
;In SRAM (Variablen)
8
;===================
9
10
.DSEG
11
12
IC: .BYTE 1 ;Interrupt Counter
13
:
BST erwartet normalerweise ein Register als erstes Argument. Bei dir
steht da aber ein Label (IC), das für eine 16-Bit-Datenadresse steht.
Beim GNU-Assembler führt dies zu einer Fehlermeldung, der Atmel-
Assembler hingegen scheint es zu akzeptieren. Ich frage mich nur,
welchen Binärcode er daraus generiert.
Wenn du nicht geschrieben hättest, dass der Code im Einsatz ist und
seine Sache gut macht, hätte ich das für einen Flüchtigkeitsfehler
angesehen.
Oder ist BST in Wirklichkeit ein Makro (sofern ein Makro überhaupt
gleich wie ein CPU-Befehl heißen darf), hinter dem sich etwas in der Art
verbirgt:
1
push r0
2
lds r0,<addr>
3
bst r0,<bitno>
4
pop r0
Ich habe kein Atmel-Studio installiert, sonst würde ich es schnell
ausprobieren.
Yalu,
der Assemblerprogrammierung in den meisten Fällen für sinnlos hält,
manchmal jedoch trotzdem einen Heidenspaß daran hat, den letzten
Taktzyklus aus dem Prozessor zu herausquetschen :)
Yalu X. schrieb:> BST erwartet normalerweise ein Register als erstes Argument. Bei dir> steht da aber ein Label (IC), das für eine 16-Bit-Datenadresse steht.
Möglicherweise haben die Register-Aliase in Atmels Assembler einen
eigenen Namespace und Moby hat der besseren Übersichtlichkeit zuliebe
den Namen doppelt verwendet.
A. K. schrieb:> So viel zum Prinzipienreiten. ;-)
Ich dachte nur: Wollt Ihr Moby jetzt 'ne Steilvorlage geben?
A. K. schrieb:> Soll der Prozessor schnellstmöglich fertig werden? Oder soll> der Programmierer schnellstmöglich fertig werden?
Der war gut, da hab ich mich echt schlapp drüber gelacht.
(Besser hätte man es wohl nicht ausdrücken können.)
> @Moby:
Zeig mal was du kannst:
Beitrag "Problem mit asm Routine"
Auf solche Fragen wie in dem Beitrag, hat noch keiner was von Moby
gehört. Das wäre ja viel zu konkret. Außerdem ganz ohne Hochsprache, die
man hassen könnte. ;-)
Carl D. schrieb:> Auf solche Fragen wie in dem Beitrag, hat noch keiner was von Moby> gehört. Das wäre ja viel zu konkret. Außerdem ganz ohne Hochsprache, die> man hassen könnte. ;-)
Solche Probleme hat er einfach nicht. Er kramt seine Standardroutinen
für UART raus und fertig. Ok, fast fertig, wäre es nicht genau dieser
eine µC, der die UART nur mit LDS/STS adressieren kann...
Yalu X. schrieb:> @Moby (falls du noch mitliest):>> Etwas offtopic und nur aus Interesse:>> bst IC,6> .DSEG> IC: .BYTE 1>> BST erwartet normalerweise ein Register als erstes Argument.> Bei dir steht da aber ein Label (IC), das für eine> 16-Bit-Datenadresse steht.> Beim GNU-Assembler führt dies zu einer Fehlermeldung,
Aber nur, wenn IC >= 32 ist. Ansonsten wird es als Registernummer
interpretiert. Anstatt ein AND "R0, R2" geht mit avr-as also auch "AND
0, 1+1". Das ist ok weil sich bei AVR die Typen der Operanden eindeutig
aus den Mnemonics ergeben.
> Yalu,> der Assemblerprogrammierung in den meisten Fällen für sinnlos hält,> manchmal jedoch trotzdem einen Heidenspaß daran hat, den letzten> Taktzyklus aus dem Prozessor zu herausquetschen :)
Bitte nicht weiter den Kopf zerbrechen, das ist ein Fehler. Das
Original, in dem IC ein Register ist, habe ich hier zur universellen
Verwendung als Modul mit IC im RAM (nicht ganz vollständig)
umformuliert.
Wird korrigiert. Etwas erschrocken bin ich freilich, daß es erst jetzt
jemandem auffällt... Verstehen hier wirklich so wenige noch Asm? Dann
wird mir allerdings mancher "kundige" Kommentar hier viel verständlicher
;-)
Carl D. schrieb:> @Moby:>> Zeig mal was du kannst:> Beitrag "Problem mit asm Routine">> Auf solche Fragen wie in dem Beitrag, hat noch keiner was von Moby> gehört.
Na ich fürchte von manchem anderen auch nicht. Wie schauts da mit Dir
aus?
Für Projekte aller Art hätte ich auch noch viel Arbeit zu vergeben ;-)
Und schon haben wir ein Datentypenproblem in ASM gefunden, nur wäre der
C Compiler so nett einen zu warnen wenn man einen Funktionspointer als
Datenpointer verwenden will, wodurch es erst Datentypenproblem auffällt.
Nur weil einen der Assembler nicht warnt/es verbietet heißt das noch
lange nicht dass es das nicht gibt.
A. K. schrieb:> Solche Probleme hat er einfach nicht. Er kramt seine Standardroutinen> für UART raus und fertig. Ok, fast fertig, wäre es nicht genau dieser> eine µC, der die UART nur mit LDS/STS adressieren kann...
Die sind einfach nur Teil fertiger, Controller-spezifischer Vorlagen.
Zugriff via In/Out, Lds/Sts oder ganz Xmega-modern als DMA Variante...
Tse schrieb:> Und schon haben wir ein Datentypenproblem in ASM gefunden, nur> wäre der C Compiler so nett einen zu warnen wenn man einen> Funktionspointer als Datenpointer verwenden will, wodurch es erst> Datentypenproblem auffällt.
Haben wir nicht.
BLD/BST sollten schlicht nur mit Registern bewaffnet als OK durchgehen,
so schlau sollte der Assembler dann schon sein.
Moby schrieb:> BLD/BST sollten schlicht nur mit Registern bewaffnet als OK durchgehen,> so schlau sollte der Assembler dann schon sein.
Das macht es im Prinzip auch. Nur du solltest dich mal schlau machen,
was die 'Spezialbezeichnung' Register überhaupt bedeutet.
Moby schrieb:> so schlau sollte der Assembler dann schon sein.
Ach? Nun auf einmal doch? ;-)
Assembler ist GIGO-Programmierung.
Garbage In, Garbage Out.
Johann L. schrieb:> Yalu X. schrieb:>> BST erwartet normalerweise ein Register als erstes Argument.>> Bei dir steht da aber ein Label (IC), das für eine>> 16-Bit-Datenadresse steht.>> Beim GNU-Assembler führt dies zu einer Fehlermeldung,>> Aber nur, wenn IC >= 32 ist. Ansonsten wird es als Registernummer> interpretiert.
Aber nur, wenn IC konstant und dem Assembler bekannt ist. In diesem Fall
ist IC aber eine Adresse, die sich erst der Linker ausdenkt. Deswegen
meint der Assembler:
1
Error: constant value required
Moby schrieb:> Bitte nicht weiter den Kopf zerbrechen, das ist ein Fehler. Das> Original, in dem IC ein Register ist, habe ich hier zur universellen> Verwendung als Modul mit IC im RAM (nicht ganz vollständig)> umformuliert.
Ok, aber warum schreibst du dann, der Code sei bereits im Einsatz, wenn
er quasi neu und wahrscheinlich noch nicht einmal durch den Assembler
gelaufen ist?
> Etwas erschrocken bin ich freilich, daß es erst jetzt jemandem> auffällt... Verstehen hier wirklich so wenige noch Asm?
Na, wenn der Fehler sogar dir als Assembler-Gott passiert ist, was
erwartest du dann von den anderen? ;-)
TriHexagon schrieb:> "Wer als Werkzeug nur einen Hammer> hat, sieht in jedem Problem einen Nagel." :P
Oder: "Wer bis jetzt nur Nägel als Problem hatte, sieht in einem Hammer
das einzig wahre Werkzeug."
Moby schrieb:> BLD/BST sollten schlicht nur mit Registern bewaffnet als OK durchgehen,> so schlau sollte der Assembler dann schon sein.
Wäre der Assembler in Assembler geschrieben, wäre das natürlich nicht
passiert!
Moby schrieb:> [...], das ist ein Fehler. [...] Etwas erschrocken bin ich freilich,> daß es erst jetzt jemandem auffällt...
Weil keiner deinen grottogen Code liest.
> Verstehen hier wirklich so wenige noch Asm? Dann wird mir> allerdings mancher "kundige" Kommentar hier viel verständlicher
Kier können viele Asm. Aber dier gezeigte Code wäre in einer
Hochsprache genauso Sch.... weil deine Code-"Kommentare" vermutlich
genauso Sch.... wären.
Moby schrieb:> Etwas erschrocken bin ich freilich, daß es erst jetzt jemandem> auffällt...
Daran kannst du sofort erkennen, dass keiner deinen Code benutzt.
Jörg W. schrieb:> Daran kannst du sofort erkennen, dass keiner deinen Code benutzt.
Nicht mal er selber :-)
Johann L. schrieb:> Wäre der Assembler in Assembler geschrieben, wäre das natürlich nicht> passiert!
Aber es wäre viel schneller nicht passiert!
Jörg W. schrieb:> Moby schrieb:> Etwas erschrocken bin ich freilich, daß es erst jetzt jemandem> auffällt...>> Daran kannst du sofort erkennen, dass keiner deinen Code benutzt.
Vor dem Benutzen kommt aber schon Lesen und Verstehen ;-)
Ralf G. schrieb:> selbsternannter Assembler-Papst
Nur weil ich von Asm überzeugt bin ?
Daran ändern auch Fehler (die natürlich sonst niemand macht) kein Jota.
Yalu X. schrieb:> Ok, aber warum schreibst du dann, der Code sei bereits im Einsatz.
Na ja,bis auf Kleinigkeiten ;-)
Johann L. schrieb:> weil deine Code-"Kommentare" vermutlich> genauso Sch.... wären.
Die haben auch nicht den Anspruch jemandem Asm beizubringen. Auch nicht,
das Datenblatt zu ersetzen.
Gönne jedem Hochsprachler ja die Genugtuung, auf den Fehler eines
ASMlers mit dem Finger zu zeigen.
Wenn die Absicht der abwertenden Kommentare nur nicht so eindeutig
wäre...
Moby schrieb:> Die haben auch nicht den Anspruch jemandem Asm beizubringen.
Das wäre auch nicht nötig. Aber wenn man beim Draufgucken auf den
Code weder sieht, was da wirklich passiert (geht bei Assembler
nicht so einfach, viele Zwischenschritte) noch es passend in
Kommentaren erklärt wird, was glaubst du, wer dann noch gewillt ist,
eine weitere Minute darin zu verschwenden, das auch zu benutzen?
Gerade Assemblercode muss ordentlich kommentiert sein, damit jemand
anders überhaupt eine Idee hat, nicht was du da treibst (das kann
man im Referenzhandbuch der CPU nachlesen), sondern warum du es
genau so gemacht hast.
Um dir mal eine Idee zu geben (Funktion strlen_P() der avr-libc,
Autor ist Marek Michalkiewicz):
Dazu gehört allerdings noch die Beschreibung der eigentlichen
Funktionalität:
1
/** \ingroup avr_pgmspace
2
\fn size_t strlen_P(PGM_P src)
3
4
The strlen_P() function is similar to strlen(), except that src is a
5
pointer to a string in program space.
6
7
\returns The strlen_P() function returns the number of characters in src.
8
*/
Das das ein C-artiger Kommentar ist, hängt damit zusammen, dass er
von Doxygen dann eingesammelt wird und zum Nutzerhandbuch verarbeitet.
Das ist das, weshalb die Nutzer die Funktion am Ende auch benutzen,
nicht weil sie irgendwie cool implementiert ist, sondern weil sie
eine brauchbare Beschreibung ihrer Funktionalität bekommen.
So, der kleine Fehler ist korrigiert!
Lenkt Eure Aufregung nun wieder in produktive Bahnen:
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 ;-)
Zu deiner Info, falls es dir immer noch niemand erzählt hat:
Eine LED blinken zu lassen, ist das dämlichste Beispiel, um zu
entscheiden, welche Sprache sinnvoll ist.
Einfach, weil man das einmal am Anfang macht (normale Leute zumindest)
und dann richtige Programme kommen.
Inzwischen nervt es wirklich...
Jörg W. schrieb:> Gerade Assemblercode muss ordentlich kommentiert sein, damit jemand> anders überhaupt eine Idee hat, nicht was du da treibst (das kann> man im Referenzhandbuch der CPU nachlesen), sondern warum du es> genau so gemacht hast.
Die Art zu kommentieren mag ich nun ganz und gar nicht diskutieren, weil
ich die zu großen Teilen für wenig objektiv begründbar halte.
Entsprechend variabel sind auch die Kommentierungen, die man so sieht.
In Asm muss man nicht jede Zeile kommentieren weil schlicht da steht was
los ist. Kleinere Unterprogrammeinheiten bekommen dann ihre Funktion
bzw. ggf. ihr Interface kommentiert- und gut ist.
Schau mal Deine .define's zum Beispiel. In größeren Programmen kannst Du
oft keine feste namensgebundene Register Zuordnung machen wenn diese
mehrfach sehr verschiede Verwendung finden sollen.
Schön, daß Du eine sachliche Meinung äußerst; die Art der Kommentierung
mag in Hochsprache ja gebräuchlich sein. Mit Datenblatt und der Kenntnis
der wenigen Dutzend Asm-Instruktionen bewaffnet stellt die Doku in Asm
andere Anforderungen bis hin zur bloßen Geschmackssache.
Generell gilt für Doku glaub ich keine Mengenbeschränkung. Viel hilft
viel (oder manchmal weniger); Absicht (Produktiv, Archiv, Lehre) und
Übersicht des Codes spielen dabei die entscheidende Rolle.
Klaus W. schrieb:> Inzwischen nervt es wirklich...
Fangen wir doch einfach mal klein an.
@Moby
hast du schon gelesen?
Jörg W. schrieb:> Dazu gehört allerdings noch die Beschreibung der eigentlichen> Funktionalität:
Klaus W. schrieb:> Zu deiner Info, falls es dir immer noch niemand erzählt hat:> Eine LED blinken zu lassen, ist das dämlichste Beispiel, um zu> entscheiden, welche Sprache sinnvoll ist.
Zu Deine Info: Ergründe besser erstmal richtig Sinn und Zweck des
Programms.
Klaus W. schrieb:> Inzwischen nervt es wirklich...
... etwa ASM- Programme nicht lesen zu können ???
Ja. Denn wie soll man sonst viele Punkte pro Asm auch nachvollziehen
können (wollen)...
Ralf G. schrieb:> @Moby> hast du schon gelesen?> Jörg W. schrieb:>> Dazu gehört allerdings noch die Beschreibung der eigentlichen>> Funktionalität:
@Ralf G.
Hast Du schon gelesen?
Also - ich bin jetzt weder C- noch Assembler-Profi. Ich kann von beidem
etwas, aber nicht viel. Programmiert habe ich Cobol, PL/1, Pascal und
ABAP/4 (nicht gerade technisch :-) ), Basic und Assembler (C64).
Ich bin der Meinung, dass die verwendete Programmiersprache der
gewünschten Anwendung angepasst sein muss. Ich würde niemals Assembler
(habe ich schon gesehen) für eine reine Datenbank-Auswertung in
List-Form einsetzen. Genau so wenig ist der Einsatz von Lisp für eine
Funkuhr (mir fällt nichts besseres ein) sinnvoll.
Je nach ANWENDUNG macht der Einsatz einer Programmiersprache Sinn.
Assembler - wer es kann, warum nicht - mit Makro-Einsatz auf dem AVR ist
sehr nah an der CPU und vermittelt wahrscheinlich eher ein Gefühl und
Verständnis für die Hardware. Schneller ist es möglicherweise auch - in
einigen Fällen. Anfangs habe ich damit programmiert - bin aber
irgendwann zu C gewechselt, weil es "universeller" - und leichter
verständlich (aus meiner sehr eigenen Sicht) ist.
Beruflich würde ich den effizientesten - und zwar primär vom
Entwicklungsaufwand her - Ansatz wählen. Bei extrem zeitkritischen
Anwendungen (damit habe ich aktuell nicht zu tun) würde ich natürlich
die Ausführungsgeschwindigkeit in den Vordergrund stellen.
Also immer zweckgebunden - und nicht programmatisch ...
Gruß
Dieter
Moby A. schrieb:> In Asm muss man nicht jede Zeile kommentieren weil schlicht da steht was> los ist.
Grad bei 8-Bittern finden sich sehr oft zusammengesetzte Operationen.
Und da ist es doch manchmal nützlich, dem Leser das Leben etwas zu
erleichtern. Nicht zuletzt bei AVRs, bei denen man manchmal das
Gegenteil von dem hinschreibt was man im Sinn hat. Also subtrahiert wo
man eigentlich addieren will, weil es den Additionsbefehl nicht gibt.
Moby A. schrieb:> Mit Datenblatt und der Kenntnis> der wenigen Dutzend Asm-Instruktionen bewaffnet stellt die Doku in Asm> andere Anforderungen bis hin zur bloßen Geschmackssache.
Das ist aber eigentlich nicht der Sinn einer ordentlichen Dokumentation.
Man sollte den Geedanken des Porgrammierers erkennen können ohne lang
Befehle und Datenblätter zu studieren.
A. K. schrieb:> Grad bei 8-Bittern finden sich sehr oft zusammengesetzte Operationen.> Und da ist es doch manchmal nützlich, dem Leser das Leben etwas zu> erleichtern.
Zum Verstehen ist das Datenblatt und meinetwegen noch das dokumentierte
Instruction-Set da. Klar ist dies und jenes mehr oder weniger nützlich-
so wie die Ansprüche individuell unterschiedlich sind.
Obiges Beispiel hab ich für meine Verhältnisse schon reichhaltigst
kommentiert.
A. K. schrieb:> Nicht zuletzt bei AVRs, bei denen man manchmal das> Gegenteil von dem hinschreibt was man im Sinn hat. Also subtrahiert wo> man eigentlich addieren will, weil es den Additionsbefehl nicht gibt.
Na danke. Da wird man echt nicht fertig. Der ASM Kenner (und dazu gehört
im Gegensatz zum C-Universum nicht viel dazu) weiß was gespielt wird.
Für jeden anderen spiele ich als Programmierer nicht den
Schulungsonkel. Ganz anders bei Code zur Lehre- den didaktischenAnspruch
hab ich nicht.
Moby A. schrieb:> Zu Deine Info: Ergründe besser erstmal richtig Sinn und Zweck des> Programms.
Genau da liegt das Problem: es macht so gut wie nichts.
Das kann man ja sogar diskret aufbauen.
Wozu dann noch Assembler? Nur weil man es kann?
Mit ein paar Gattern sparst du sogar noch die letzten Byte gegnüber
deiner Lösung.
Bei Programmen mit einer halbwegs realistischen Komplexität können wir
und gerne wieder unterhalten.
Ich habe irgendwie keine Lust, nach Jahren immer noch über Taste drücken
+ oh, es leuchtet was zu philosophieren.
;[A] LED0 = KEY0.state; // an solange Taste gedrückt
4
;[B] LED1.toggle = KEY1.press // wechsel bei jeder Drückflanke
5
;[C] LED2.off = KEY2.press_short; // kurz drücken - aus
6
;[D] LED2.on = KEY2.press_long; // lang drücken - an
7
;alle 3 Tasten entprellt und mit Zeiterfassung(Pressed-Status)
8
;auf bis zu 8 erweiterbar
... das?
Ich dachte, du bist auf dem richtigen Weg.
In beiden Fällen hast du leider gezeigt, dass du nicht begriffen hast,
worum es überhaupt geht:
- Was kann die Funktion/ das Programm?
- Welche Parameter muss ich übergeben, welche Werte erhalte ich zurück/
Was muss wo an welchen µC angeschlossen werden
Daraus folgt:
(1) kann ich nicht verwenden :-(
oder (2) Juhu, genau das habe ich gesucht. Das nehme ich.
Es geht nicht darum den Code zu entschlüsseln oder zu verstehen.
Tse schrieb:> Man sollte den Geedanken des Porgrammierers erkennen können ohne lang> Befehle und Datenblätter zu studieren.
Befehle und Datenblätter sind in Assembler durch nichts, aber auch gar
nichts zu ersetzen!
>Zeigt mal, wie sich die Funktionalität in höchstens gleicher C -Codegröße >umsetzen lässt.
Zeigt doch mal eine textuelle Beschreibung, oder ein Signalfluss oder
Ablaufplan oder sonstwas um zu sagen, was das Programm machen soll.
Ich zumindest, habe keine Lust, den asm-Code zurück zu interpretieren,
und den Programmablauf zu erraten...
Moby A. schrieb:> Befehle und Datenblätter sind in Assembler durch nichts, aber auch gar> nichts zu ersetzen!
Beim Schreiben hast du recht, beim lesen sollte man aber wenigstens den
zu Grunde liegenden Algorithmus verstehen können ohne alle paar Zeilen
ein Reister/Befehl nachschlagen zu müssen.
Oder man macht es sich einfach und gibt zu, dass der Code schlecht
dokumentiert ist.
Klaus W. schrieb:> Genau da liegt das Problem: es macht so gut wie nichts.
Du verstehst es nicht. Sag es doch so wie es ist ;-)
Aber tröste Dich mit dem Gedanken, mit C mag ich auch nichts anfangen.
Ein C-Programm für die PC- Kommandozeile hab ich mal verbrochen- dann
hatte ich echt genug von diesem sperrigen, umständlichen, langzeiligen,
kryptischen Zeug (war mein Empfinden).
Moby A. schrieb:> Na danke. Da wird man echt nicht fertig. Der ASM Kenner (und dazu gehört> im Gegensatz zum C-Universum nicht viel dazu) weiß was gespielt wird.
Nun habe ich schon mit recht vielen Assemblern zu tun gehabt, nicht
selten praktisch gleichzeitig, und da gibt es die ulkigsten
Kombinationen, wie man Dinge schreiben kann.
So gibt es in Assembler mal die rechts-nach-links Konvention, also
add dest, source
und man die links-nach-rechts Konvention
add source, dest
und manchmal bei der gleichen Maschine beide, je nach Assembler.
Besonders originell stellt sich das bei Vergleichsbefehlen dar, weil in
cmp x, y
bgt l1
nicht sofort klar ist, ob bei x>y oder x<y gesprungen wird. Nicht einmal
dann, wenn die Architektur üblicherweise links-nach-rechts vorgibt. Weil
es welche gibt, die eben deshalb Vergleichsbefehle nochmal umdrehen, so
dass am Ende Vergleichsbefehle genau andersrum arbeiten als die
Subtraktionsbefehle. also
cmp x,y
und
sub y,x
in den Flags das gleiche Ergebnis hinterlassen.
Ähnliche Effekte kriegt man beim Carry-Flag nach der Subtraktion. Manche
implementieren es als echtes Borrow. Andere addieren das
Einerkomplement, was zu inversem Carry-Flag führt.
Wenn man also nicht permanent nur ein einer Architektur drin steckt,
oder auch mal jemand anders den Code lesen können soll, dann kann es
nicht schaden, bei solchen Feinheiten Tipps zu geben.
Moby A. schrieb:> Entsprechend variabel sind auch die Kommentierungen, die man so sieht.
Wenn ich das so richtig verstehe, verbrennst Du im Interrupt die
Register r9..r15. Das schließt also in allen anderen Interrupts gleicher
Bauart den sei-Befehl aus.
Zumindest solche Einschränkungen sollten meiner Meinung nach
dokumentiert sein. Ansonsten liegt die Wiederverwertbarkeit Deiner
Module bei null.
(73 vom Assemblerdilletant)
Matthias L. schrieb:> Zeigt doch mal eine textuelle Beschreibung, oder ein Signalfluss oder> Ablaufplan oder sonstwas um zu sagen, was das Programm machen soll.
Na ist denn die umzusetzende Funktionalität nicht eindeutigst
beschrieben?
Das Ganze bitteschön entprellt, mit mindestens 3 beliebigen IO-Pins
und hinterher ausgefülltem Daten-RAM so wie beschrieben. Bin gespannt...
Moby schrieb:> Johann L. schrieb:>> weil deine Code-"Kommentare" vermutlich genauso Sch.... wären.>> Die haben auch nicht den Anspruch jemandem Asm beizubringen.
Lass die Nebelkerze mach stecken. C-Kommentare haben auch nicht zum
Ziel, jemandem C beizubringen.
Dein Code ist echt Hack vom feinsten: Kein Funtionskopf, der erklärt,
was die FuUnktion macht, welche Register sie verwendet, zerstört, oder
ändert, welche Rückgabewerte sie hat, welche Hardware sie anfasst, etc.
Ob Code Code ist oder Hack, entscheidet sich zu 5% am Code und zu 95% an
Kommentaren und Dokumentation.
> Gönne jedem Hochsprachler
Woher bitte nimmst du diese Schublade?
Ein nicht unwesentlicher Teil der AVR-Entwickler, die sich hier tummeln,
verwendet ASSEMBLER-Code aus meiner Feder.
> die Genugtuung, auf den Fehler
Um den Fehler ging es garnicht, s.o. Mit Verlaub, der Stil von
"adu.asm" ist einfach mies.
Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein
einen 32-Bit Wert kleiner als 1000000 ist?
Moby A. schrieb:> Na ist denn die umzusetzende Funktionalität nicht eindeutigst> beschrieben?> Das Ganze bitteschön entprellt, mit mindestens 3 beliebigen IO-Pins> und hinterher ausgefülltem Daten-RAM so wie beschrieben. Bin gespannt...
Was bist du denn für ein Wicht??
Horst S. schrieb:> verbrennst Du im Interrupt die> Register r9..r15.
Registerverwendung = Verbrennung, was?
Den schnellen, kurzen Sicherungsstandard hab ich in vielen Programmen.
Kann man natürlich auch mit langwierigem Push/Pop machen ;-)
Horst S. schrieb:> Zumindest solche Einschränkungen sollten meiner Meinung nach> dokumentiert sein.
Das zeigt das kurze Programm. Bei längeren darf die Registerverwendung
am Anfang dokumentiert sein, da geb ich Dir recht.
Horst S. schrieb:> Ansonsten liegt die Wiederverwertbarkeit Deiner> Module bei null.
Toll wie Du das in so kurzer Zeit herausgefunden hast.
Bin beeindruckt ;-)
Hallo
Also ich mach mir jetzt mal nicht die Mühe, alle Artikel durchzulesen...
Zu faul bin.
Im meinem Gedächtnis finde ich jedoch zum Microsoft Assembler für PC
(MASM),
da war eine (durchaus sachliche) Werbeaussage der etwa 2 fachen
Geschwindigkeit von Assemblerprogrammen gegenüber C(+?).
Auch andere Optimierungen wie Echtzeitprogrammierung oder
Speicherplatzminimierung sind gut in Assembler möglich.
Ich finde auch, alle Betriebssyteme sollten in Assembler geschrieben und
optimiert werden, damit der Computer nicht dauernd für C läuft.
Gibt es bei C die Verwendung vom Stapel? Das kann man zum Beispiel auch
beim Assembler minimieren.
Die ganzen neuen Anwendungen wie z.B. digitale Signalverarbeitung sind
auch sehr CPU-Takt abhängig.
Ich kann aber den längeren Zeitaufwand beim Programmieren (liegt
angeblich auch etwa beim Faktor 2) nicht ignorieren und so empfehle ich,
zuerst nur zeitlich wichtige Programmteile in Assembler zu
programmieren, also Programmteile, die Zeit brauchen.
MfG
Matthias
Johann L. schrieb:> Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein> (einen) 32-Bit Wert kleiner als 1000000 ist?
(Nur mal unter uns, es liest ja keiner mit: Du denkst, daran scheitert
er schon?)
Horst S. schrieb:> Wenn ich das so richtig verstehe, verbrennst Du im Interrupt die> Register r9..r15. Das schließt also in allen anderen Interrupts gleicher> Bauart den sei-Befehl aus.
Ist bei Assemblerprogrammierung in AVRs nicht unüblich. Man hat genug.
Genau da liegt auch ein klarer Vorteil von Assembler gegenüber C bei
AVRs. Nur gibts dabei nach oben einen Deckel, das ist nur in kleinem
Umfang sinnvoll möglich.
> Zumindest solche Einschränkungen sollten meiner Meinung nach> dokumentiert sein. Ansonsten liegt die Wiederverwertbarkeit Deiner> Module bei null.
Die Nutzung von Registern sollte bei Assembler generell en detail
dokumentiert werden, wenn man keine einheitliche Registerkonvention hat,
oder mit global zugewiesenen Registern arbeitet.
Moby A. schrieb:> Du verstehst es nicht. Sag es doch so wie es ist ;-)
Wenn es drum geht, möglichst kryptischen Code zu erzeugen, bei dem
der geneigte Leser garantiert nicht vom bloßen Draufgucken erkennen
kann, was der Code denn eigentlich macht: glaub' uns, Moby, in
dieser Wettbewerbskategorie wirst du C kaum schlagen können. :-))
Nur, dass du mal eine Idee bekommst, hier einer der Gewinner des
diesjährigen IOCCC:
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.
Johann L. schrieb:> Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein> einen 32-Bit Wert kleiner als 1000000 ist?
Einen 32-Bit Wert so zu prüfen hat ich in meiner Praxis noch nicht.
Ich tät mir spontan die 3 Bytes einzeln vornehmen, kann mir aber gut
vorstellen daß Du einen Trick auf Lager hast ;-)
Johann L. schrieb:> Mit Verlaub, der Stil von> "adu.asm" ist einfach mies.
Mit Verlaub- Deine Meinung.
Ralf G. schrieb:> Was bist du denn für ein Wicht??
Wo ist denn Dein Problem?
Könnte auch gehen, aber es steht mir natürlich nicht zu, fremden Code
hier modifiziert wiederzugeben. ;-)
(Es war übrigens der Eintrag maffiodo2, um dem Autor noch die nötige
Ehre zu erweisen.)
Jörg W. schrieb:> Wenn es drum geht, möglichst kryptischen Code zu erzeugen, bei dem> der geneigte Leser garantiert nicht vom bloßen Draufgucken erkennen> kann, was der Code denn eigentlich macht: glaub' uns, Moby, in> dieser Wettbewerbskategorie wirst du C kaum schlagen können. :-))
Hey ich weiß doch, daß komplexe, kryptische Ausdrücke die Stärke von C
sind... Deshalb ist Asm ja auch so erfrischend einfach und übersichtlich
;-)
So, ich muß mich für heute entschuldigen,
ich hoffe irgend jemand überzeugt mich bald in Sachen C-Codegröße,
Übersichtlichkeit, Einfachheit, Performance ...
Gute Nacht.
Matthias K. schrieb:> Im meinem Gedächtnis finde ich jedoch zum Microsoft Assembler für PC> da war eine (durchaus sachliche) Werbeaussage der etwa 2 fachen> Geschwindigkeit von Assemblerprogrammen gegenüber C(+?).
Von wann ist die Aussage? Bei heutigen x86er kann das ebensogut
andersrum ausgehen, zumal wenn der Optimizer den relevanten Optimization
Guide besser kennt als der Programmierer. Schon mal in ein solches Werk
reingesehen? Das sind ziemliche Schwarten.
> Ich finde auch, alle Betriebssyteme sollten in Assembler geschrieben und> optimiert werden, damit der Computer nicht dauernd für C läuft.
Um das Betriebssystem mit jeder erheblich geänderten Prozessorgeneration
neu zu schreiben? Beim Übergang von Pentium Pro/II/III zum Pentium 4
hätte man den Code komplett überarbeiten müssen.
> Die ganzen neuen Anwendungen wie z.B. digitale Signalverarbeitung sind> auch sehr CPU-Takt abhängig.
Ja, natürlich. Wenn du Echtzeitanforderungen auf den einzelnen Takt
runtergebrochen hast, dann geht das nicht anders als direkt.
Moby A. schrieb:>> Ein nicht unwesentlicher Teil der AVR-Entwickler, die sich hier tummeln,>> verwendet ASSEMBLER-Code aus meiner Feder.>> Find ich gut.
Ich dachte, du magst keine Compiler?
Jörg W. schrieb:> kann, was der Code denn eigentlich macht: glaub' uns, Moby, in> dieser Wettbewerbskategorie wirst du C kaum schlagen können. :-))
Er vielleicht nicht, aber gegenüber Perl ist C harmlos. ;-)
Im Anhang mal der komplette Code.
Was tut er? Wirst Du ja auf einen Blick sehen. Übrigens scheine ich
damals mehr Kommentare geschreieben zu haben, als Du.
Johann L. schrieb:> Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein> einen 32-Bit Wert kleiner als 1000000 ist?
AAhh, verstehe... :-)
Aber sowas macht man doch nicht in einem Assemblerprogramm?
Irgendwann stellt sich dann heraus, das der Moby auch nur so ein
Kunstprojekt gelangweilter Informatiker ist, um euch so richtig auf die
Palme zu bringen.
Ralf G. schrieb:> Johann L. schrieb:>> Mal ne ganz konkrete Frage: Wie testest du in AVR-Assembler, ob ein>> (einen) 32-Bit Wert kleiner als 1000000 ist?>> Nur mal unter uns, es liest ja keiner mit: Du denkst, daran scheitert> er schon?
Das werden wir wissen falls er sich nicht um eine konkrete Antwort
drückt.
Ralf G. schrieb:> Johann L. schrieb:>> Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein>> (einen) 32-Bit Wert kleiner als 1000000 ist?>> (Nur mal unter uns, es liest ja keiner mit: Du denkst, daran scheitert> er schon?)
Interessanter ist doch ob die Antwort 'komplexer' ist als
scelumbro schrieb:> Interessanter ist doch ob die Antwort 'komplexer' ist als
Wobei Vergleiche von Multibyte/Multiword-Typen auf AVRs schon deutlich
einfacher sind als auf diversen anderen Prozessoren. Atmels sehr
hilfeiche Handhabung des Z-Flags bei den CPC/SBC Befehlen kenne ich
sonst nur von Zilogs Z8. Auch relativ moderne 8-Bitter wie STM8 kennen
diese Methode nicht.
Jörg W. schrieb:> Nur, dass du mal eine Idee bekommst, hier einer der Gewinner des> diesjährigen IOCCC:> d=80,e,j;g(){j+=getchar();}main(a,b)char**b;{for(;;){j=0;g();if(j<0)> break;g(g());putchar(b[1][j/3*strlen(b[1])>>8]);if(!(++e%d))puts("");}}
Für Mobys ADC-Code habe ich deutlich länger gebraucht, um ihn zu
verstehen. Ernsthaft!
Und das, obwohl Mobys Code Kommentare enthält und es vorab bekannt war,
wozu er gut ist.
Der IOCCC-Code ist zwar schön kurz, aber für IOCCC-Verhältnisse nur
mäßig kryptisch.
Am schwierigsten fand ich übrigens nicht herauszufinden, was der
IOCCC-Code tut, sondern wozu er nützlich sein soll, also das, was bei
Mobys Code schon vorab bekannt war. Hätte diese Information bei Moby
gefehlt, wäre der Unterschied in der Verständlichkeit noch größer
gewesen.
Johann L. schrieb:> Ralf G. schrieb:>> Johann L. schrieb:>>> Mal ne ganz konkrete Frage: Wie testest du in AVR-Assembler, ob ein>>> (einen) 32-Bit Wert kleiner als 1000000 ist?> Das werden wir wissen falls er sich nicht um eine konkrete Antwort> drückt.
Die Frage habe ich doch beantwortet, warte aber noch auf den "Trick" des
Fragestellers... Wenn der in der Benutzung eines C-Compilers bestehen
soll dann dankeschön ;-)
Drückt Euch mal lieber nicht um eine C-Fassung meines simplen kleinen
Asm-Progs weiter oben. Ich warte immer noch auf den Beweis der
Überlegenheit des C-Compilers... Also, bitte nicht an der Kommentierung
festkrallen sondern nur mal eine Lösung. Experten die beides beherrschen
sind ja hier offensichtlich genügend versammelt ;-)
Bob schrieb:> Irgendwann stellt sich dann heraus, das der Moby auch nur so ein> Kunstprojekt gelangweilter Informatiker ist, um euch so richtig auf die> Palme zu bringen.
Da mach Dir mal keine Sorgen.
Bin am Thema schon ernsthaft interessiert und programmiere auch nicht
erst seit gestern.
Bastler schrieb:> oder um's mal mit Baumann zu sagen:>> schlicht: ein armer Wicht
Ja Bastler, Du magst mich auf die Palme bringen...
Aber weißt Du, wenn das meiste meiner Werke schön funktioniert, nützlich
ist und Freude macht ist das nicht ganz so einfach. Ich weiß ja nicht
was Du so zusammenbastelst... Hoffentlich sind das nicht nur
beleidigende Floskeln hier ;-(
Moby schrieb:> Die Frage habe ich doch beantwortet, warte aber noch auf den "Trick" des> Fragestellers... Wenn der in der Benutzung eines C-Compilers bestehen> soll dann dankeschön ;-)Moby A. schrieb:>> Ich tät mir spontan die 3 Bytes einzeln vornehmen,>> 4 Stück sinds natürlich ;-)
War das deine Antwort? Die Erkenntnis das 32 Bit aus 3 - 4 Bytes
bestehen, je nach Uhrzeit und man diese auf einer 8-Bit Maschine einzeln
bearbeitet? Ein bisschen konkreter geht es nicht?
Hier nochmal die vollständige Implementation dieses Problems in C:
Hmm.... ich habe heute morgen 69 Emails bekommen. Davon der Großteil
Benachrichtigungen für diesen Thread, der nur noch darin besteht, einem
Unbelehrbaren zu belehren. Dabei ist doch schon an den
Assembler-Kommentaren ersichtlich, daß er keinerlei Empathie besitzt,
was der Leser erwartet. (Insbesondere der effiziente Leser, der bei
einem Text/Quelltext nicht Zeile für Zeile durchgehen will, sondern sich
erst einmal den Überblick verschaffen will, ob er überhaupt an der
richtigen Stelle sucht.) Das ist Verschwendung. (Tut mir leid Moby, aber
so sieht es anhand Deines Quelltextes aus. Deine Schreibweise ist
perfekt für jemanden, der niemals Sachen weitergeben will und an seinen
Projekten alleine werkelt - aber das ist OK. Nicht jeder hat in jedem
Bereich etwas, was er sinnvoll teilen kann.)
Dabei sind hier ja durchaus auch noch interessante Fragen offen:
- Mein persönliches Interesse: Wo man einen solchen
"objektbasiert"-ähnlichen Ansatz für ISRs lernt.
- Für den Umbau der obigen ASM-Routinen in C wurde die Struktur des
Programms geändert, weil sie der C-Denkweise entgegenkommt. Wäre die
diese neue Struktur in ASM sinnvoll implementierbar oder wird das eher
unübersichtlich?
Ralf G. schrieb:> Ich lach' mich tot.
Dann verstehst Du womöglich die Antwort nicht ;-)
scelumbro schrieb:> War das deine Antwort? Die Erkenntnis das 32 Bit aus 3 - 4 Bytes> bestehen,
Nun, 1000000 dezimal sind [0F 42 40] Hex. Einen 32-Bit Wert kann man
doch nun Byte für Byte abklappern ob er kleiner ist. Stellt Euch doch
nicht so dämlich.
Ich würd mich totlachen wenn das in ASM sogar schneller ginge!
Wenn nun noch das Argument mit dem bequemer Rechnen in C kommt- Ja. Das
ist so. Wie schon ausdrücklich erwähnt. Bei kleineren und mittleren MSR
Projekten spielen solche Berechnungen meist eine sehr untergeordnete
Rolle. Als Motivation zum Umstieg auf Hochsprache? Keine Chance...
Walter T. schrieb:> einem> Unbelehrbaren zu belehren
Na ja der Eindruck ist oft gegenseitig.
Und die eigentliche Absicht manchen Schreibers zu eindeutig ;-)
Walter T. schrieb:> Deine Schreibweise ist> perfekt für jemanden, der niemals Sachen weitergeben will und an seinen> Projekten alleine werkelt
Ach was. Wer Asm versteht kann das samt Datenblatt problemlos.
Mit der Aufgabe einem C-ler ASM zu erklären beschäftige ich mich nicht.
Und lenkt doch nicht ständig mit der Schreibweise, die gerade schön kurz
und knapp und gerade nicht so romanfüllend wie Hochsprachencodes
daherkommt, vom eigentlichen Problem ab: C ist einfach mehr sprachlicher
Aufwand für größere, langsamere Ergebnisse.
Rufus Τ. F. schrieb:> Moby schrieb:>> Also meine liebe 128erMega Haussteuerung läuft bald ein ganzes Jahrzehnt>> :-)>> Wie süß.
Nö. Wie nützlich und doch so einfach.
Rufus Τ. F. schrieb:> würde es mich> ein müdes Arschrunzeln kosten, mein Programm auf irgendwas anderem> laufen zu lassen, sofern es mindestens 32 Bit breit ist.
Ja bitteschön, wenns Spaß macht.
Mir wärs den Aufwand nicht wert.
Moby A. schrieb:> Ich würd mich totlachen wenn das in ASM sogar schneller ginge!
Keine Sorge, dein Leben ist nicht in Gefahr.
Aber auf die konkreten Befehle warten wir immer noch. ;-)
A. K. schrieb:> Keine Sorge, dein Leben ist nicht in Gefahr.
Das glaub ich erst wenn mir jemand sagt, was die entsprechende
C-Konstruktion exakt an Takten frisst ;-)
32-Bit Berechnungen sind auf einem 8-Bitter einfach beschwerlich-
und werden bei 8-Bit Projekten selten gebraucht...
> Aber auf die konkreten Befehle warten wir immer noch. ;-)
Glaub ich ehrlich gesagt weniger ;-)
Moby A. schrieb:> Schreibweise, die gerade schön kurz> und knapp und gerade nicht so romanfüllend wie Hochsprachencodes> daherkommt
P.S. damit meinte ich den Code aus meinem kleinen LM335 Projekt.
Beim weiter oben publizierten hab ich bzgl. Kommentierung fast schon arg
übertrieben ;-)
Moby A. schrieb:> Und lenkt doch nicht ständig mit der Schreibweise, die gerade schön kurz> und knapp und gerade nicht so romanfüllend wie Hochsprachencodes> daherkommt, vom eigentlichen Problem ab: C ist einfach mehr sprachlicher> Aufwand für größere, langsamere Ergebnisse.
Ein Traum... :-)
Schreib' doch einfach mal deinen Assemblercode für den Vergleich! Gerne
auch als Funktion zur universellen Verwendung.
1
uint8_tTest_Mio(uint32_tval)
2
{
3
returnval<1000000UL;
4
};
Und das machst du mit weniger Schreibaufwand? Und der Speicherverbrauch
ist auch noch geringer? Und die Geschwindigkeit erst!?
Ralf G. schrieb:> Und das machst du mit weniger Schreibaufwand? Und der Speicherverbrauch> ist auch noch geringer? Und die Geschwindigkeit erst!?
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. Soll ichs für
Dich noch 10 mal wiederholen?
Moby A. schrieb:> Ausgeschlossen. Falls Du nicht AVR32 meinst.
Nö. 8-Bit AVR. Beim Cortex-M3 sind es 4-5, hätte aber in Schleife Luft
für Optimierung.
Wie schon gesagt, es geht nur um das if(...), nicht um die ganze
Funktion oder den Aufruf von g().
Moby A. schrieb:> Ausgeschlossen.
:-)
In Assembler ist's (als Funktion) möglicherweise sogar länger! Außer du
hast die Registerorganistion/ -verwendung vom gcc abgekupfert.
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.
Zwei typische Beispiele:
Bei meinen Anwendungen gibts sehr oft einen Timer-Tick, der eine 32-Bit
Variable hochzählt. Ist ganz praktisch für programmierte Wartezeiten und
Timeouts. Weniger Bits wär zu wenig.
Nicht selten gibts auch Datum/Uhrzeit in 32 Bits. Mal in
Unix-Konvention, mal in FAT-Konvention.
Moby A. schrieb:> Falls Du darauf abzielst
Nein.
> 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.
Kann schon sein. Nur: wenn's doch mal vorkommt, musst du da gleich die
Segel streichen!?
>Soll ichs für Dich noch 10 mal wiederholen?
Wenn du willst...
A. K. schrieb:> if (x < 1000000) + Sprung
... machst Du in mit C auf einem 8-Bit AVR nicht in 5-6 Takten.
Allein ein RJMP nimmt 2...
Heute zu Scherzen aufgelegt?
Zugegeben, diesen kannte ich noch nicht.
A. K. schrieb:> Bei meinen Anwendungen gibts sehr oft einen Timer-Tick, der eine 32-Bit> Variable hochzählt. Ist ganz praktisch für programmierte Wartezeiten und> Timeouts. Weniger Bits wär zu wenig.
Kann ich so nicht bestätigen.
In typischen 8-Bit Anwendungen langen auch 8-Bit.
Für viel mehr noch als nur Timing-Aufgeben...
Ein Beispiel geb ich demnächst bei meiner kleinen Tiny-Platine in der
Projektesammlung.
Ralf G. schrieb:> Kanst du nicht, kannst du nicht, kannst du nicht... ;-)Moby A. schrieb:> Und die eigentliche Absicht manchen Schreibers zu eindeutig ;-)
Moby A. schrieb:> ... machst Du in mit C auf einem 8-Bit AVR nicht in 5-6 Takten.> Allein ein RJMP nimmt 2...
Stimmt, nur ist da aber keiner drin. ;-)
Und der bedingte Sprung darin braucht nur 2 wenn er springt.
Daher kommt das "5-6".
Moby A. schrieb:> In typischen 8-Bit Anwendungen langen auch 8-Bit.
Oder andersrum formuliert: Wenn es mehr als 8 Bits werden, weil die
Zeiten mal ein paar Millisekunden und mal einige Sekunden sind, dann
schmeisst du den 8-Bitter weg, weil du keine entsprechende Codesequenz
gebacken bekommst? ;-)
Mir ist das wurscht. Der zählt die Ticks ab Start in 32 Bits hoch. Das
gibt (bei meinen(!) Anwendungen) ausreichend Zeit um mich weder mit dem
Überlauf rumärgern noch das Verfahren jedesmal anwendungsspezifisch neu
überlegen zu müssen. Ist nicht der einzige Weg zur Lösung, sicherlich
nicht der effizienteste hinsichtlich Laufzeit, aber dafür recht simpel.
Ist mir dann auch egal, ob da ein 8-Bitter drunter steckt oder ein
32-Bitter.
Moby A. schrieb:> Ralf G. schrieb:>> welchen RJMP???????>> Ein bedingter Sprung im True-Fall auch.
Nö, im False-Fall. Im True-Fall ist es nur einer.
True 5, False 6.
A. K. schrieb:> Moby A. schrieb:>> In typischen 8-Bit Anwendungen langen auch 8-Bit.>> Oder andersrum formuliert: Wenn es mehr als 8 Bits werden, weil die> Zeiten mal ein paar Millisekunden und mal einige Sekunden sind, dann> schmeisst du den 8-Bitter weg, weil du keine entsprechende Codesequenz> gebacken bekommst? ;-)
Oh je oh je. Dann führe ich den Zähler meinetwegen auch 128-bittig aus.
Was ist den das für eine Herausforderung...
> Mir ist das wurscht. Der zählt die Ticks ab Start in 32 Bits hoch. Das> gibt (bei meinen(!) Anwendungen) ausreichend Zeit um mich weder mit dem> Überlauf rumärgern noch das Verfahren jedesmal anwendungsspezifisch neu> überlegen zu müssen. Ist nicht der einzige Weg zur Lösung, sicherlich> nicht der effizienteste hinsichtlich Laufzeit, aber dafür recht simpel.>
Überlaufrumärgern ist mir bislang fremd. Was ist denn das?
> Ist mir dann auch egal, ob da ein 8-Bitter drunter steckt oder ein> 32-Bitter.
Mir nicht. Ein solider AVR solls schon sein ;-)
Meine Zusammenfassung;
C oder Assembler ist klar beantwortet. Das was hier an ASM Code
präsentiert macht jeder C- Compiler nicht schlechter. In Sachen Doku ist
sogar von C generierter Assembler besser nachvollziehbar. Vor Menschen
die ihre Position gegen alle anderen verteidigen habe ich aber Respekt,
ist nicht einfach. Sie könnten ja richtig liegen, wenn auch nicht in
diesem Fall. Die Masse zählt nicht, nur Argumente.
ASM ist für mich ein Tool der letzten Hoffnung. Wenn es um
zeitkritisches geht oder man der Meinung ist selber dichteren Code
produzieren zu können. Trügerisch da in den Compilern 100e von
Mannjahren stecken, man selber aber nur ein Leben hat.
Etwas untergegangen ist die Portierbarkeit. Wie man hier sehen kann
haben die unterschiedlichsten Leute zum C-Code beigetragen. Code und
dessen Funktionen auch ich verstehe obwohl ich den GCC noch nie gesehen
habe. Dafür habe ich weder Datenblätter gewälzt noch die Abgründe
irgendeiner Maschinensprache reingezogen. Es ist schlicht so zu
verstehen.
Ansonsten ist ein Tool ein Tool. Es schreibt doch wohl kaum jemand
seinen eigenen USB-Stack, weder in C noch in ASM oder sonstwas. Da nehme
ich jedenfalls eine lib. Auch ein Bild male ich nicht in C oder ASM
sondern mit Pinsel und Farbe oder Gimp, Photshop Paint etc.
Moby A. schrieb:> Tja A.K., du machst mich leider nicht neugierig auf die Lösung...
Nein? Klang bisher irgendwie anders. ;-)
Aber einfach wärs schon, sie auch ohne mich zu kriegen.
Brauchst nur einen AVR-GCC dazu. In Linux trivial. ;-)
A. K. schrieb:> Moby A. schrieb:>> Ralf G. schrieb:>>> welchen RJMP???????>>>> Ein bedingter Sprung im True-Fall auch.>> Nö, im False-Fall. Im True-Fall ist es nur einer.> True 5, False 6.
Irrtum. Der True-Fall braucht zwei...
Was sollte aber nun diese Vergleich 1000000-Spinnerei ????
Moby A. schrieb:> Oh je oh je. Dann führe ich den Zähler meinetwegen auch 128-bittig aus.> Was ist den das für eine Herausforderung...
Bring erst einmal deine Lösung für 32 Bits, bevor du dich ans 128 Bits
ranwagst. ;-)
> Überlaufrumärgern ist mir bislang fremd.
Ja, den Eindruck kann man kriegen.
Moby A. schrieb:> Irrtum. Der True-Fall braucht zwei...
Irrtum. Er springt im False-Fall. Im True-Fall fällt er durch. Da ist
bei if() meistens so, es sei denn der Compiler entscheidet, dass es
aufgrund der zu erwartenden Werte anders effizienter ist.
> Was sollte aber nun diese Vergleich 1000000-Spinnerei ????
Ok, jetzt kommt also die nächste Stufe. Hast du das schon mal in einer
mündlichen Prüfung versucht? Also statt der erwarteten Antwort: "Herr
Soundso, was soll diese Spinnerei, das muss doch niemand wissen!" ;-)
X4U schrieb:> Meine Zusammenfassung;>> C oder Assembler ist klar beantwortet. Das was hier an ASM Code> präsentiert macht jeder C- Compiler nicht schlechter.
w.z.b.w.
Dein Beitrag enthält auch sonst nur Punkte, deren Relevanz für typische
8-Bit AVR Projekte hinreichend zweifelhaft ist.
Du hast aber Recht, jeder wie er mag. Menschliche Entscheidungen sind so
vielschichtig wie individuell.
Was die objektiven Vorteile in Asm in keiner Weise schmälert.
A. K. schrieb:> Moby A. schrieb:>> Irrtum. Der True-Fall braucht zwei...>> Irrtum. Er springt im False-Fall. Im True-Fall fällt er durch. Da ist> bei if() meistens so, es sei denn der Compiler entscheidet, dass es> aufgrund der zu erwartenden Werte anders effizienter ist.
Ich merk schon, mit den bedingten ASM-Befehlen hast Du's nicht so ;-)
> Ok, jetzt kommt also die nächste Stufe.
Oh nein oh nein. Obiges Beispiel bleibt trotzdem eine ebensolche ;-)
Ralf G. schrieb:> @Moby> Lass erstmal die Vergleich-1000000-Spinnerei liegen. Es gibt> Wichtigeres:> Beitrag "LCD Assembler">> Da braucht jemand dringend deine Hilfe!
Dann mal ran, Ralf. Aber ich weiß schon, Dir ist es lieber hier
rumzustänkern ;-)
Moby A. schrieb:> Dann mal ran, Ralf. Aber ich weiß schon, Dir ist es lieber hier> rumzustänkern ;-)
Da ist was Wahres dran ;-)
Ich muss allerdings erstmal weg. Also: übernimmst du mal ausnahmsweise
für mich?
Moby A. schrieb:> Nö. Jetzt heißt es: Mahlzeit!
Aber das wäre was für dich.
Das ist eine deiner typischen AVR-Anwendungen, wo man nicht mehr als
ganze Byte braucht.
Nö. Jetzt heißt es: Mahlzeit!
A. K. schrieb:> Moby A. schrieb:>> Oh je oh je. Dann führe ich den Zähler meinetwegen auch 128-bittig aus.>> Was ist den das für eine Herausforderung...>> Bring erst einmal deine Lösung für 32 Bits, bevor du dich ans 128 Bits> ranwagst. ;-)
Es ist auch sehr gewagt, etwas als "Lösung" zu bezeichnen, was Du im
Falle Deines Vergleichs nur hinschreibst, um es von C für Dich
übersetzen zu lassen ;-)
Ich mag jetzt gar keinen x-bittigen Counter in Asm für Dich hinschreiben
weil ich nicht glaube, daß Du damit was anfangen kannst.
Moby A. schrieb:> Ich merk schon, mit den bedingten ASM-Befehlen hast Du's nicht so ;-)
Die Frage dabei ist, worauf man das True/False bezieht. Da hier stets
von C Code ausgegangen wird, ist das natürlich die im if(...) genannte
Bedingung. Nicht die im bedingten Sprung genannte Bedingung.
Weshalb if(cond)block meist so implementiert wird:
if cond false goto L1
block
L1:
Er springt also, wenn die if-Bedingung falsch ist.
Du hast das dann im Geist rumgedreht und auf den Sprungbefehl bezogen.
Klaus W. schrieb:> Moby A. schrieb:>> Nö. Jetzt heißt es: Mahlzeit!>> Aber das wäre was für dich.> Das ist eine deiner typischen AVR-Anwendungen, wo man nicht mehr als> ganze Byte braucht.
Der lustige Klaus wieder...
Völlig untypisch für jemanden der eigentlich permanent genervt ist.
Iß auch erst mal was ;-)
Moby A. schrieb:> Es ist auch sehr gewagt, etwas als "Lösung" zu bezeichnen, was Du im> Falle Deines Vergleichs nur hinschreibst, um es von C für Dich> übersetzen zu lassen ;-)
Ich nehme an, dass du in deinem nächsten Urlaub nach Malle schwimmst,
statt für die Lösung des Problems "wie komme ich da hin" Werkzeuge
anderer Leute zu nutzen.
A. K. schrieb:> Moby A. schrieb:> Du hast das dann im Geist rumgedreht und auf den Sprungbefehl bezogen.
Ok A.K., sei es wie es sei, die 5-6 Takte für den Vergleich von einer
32- mit einer 24-Bit Konstante samt Sprung sind für 8-Bit AVR utopisch.
Moby A. schrieb:> Ok A.K., sei es wie es sei, die 5-6 Takte für den Vergleich von einer> 32- mit einer 24-Bit Konstante samt Sprung sind für 8-Bit AVR utopisch.
Nicht utopisch, sondern viel zu viel. Dieser Vergleich braucht 0
Takte, denn den optimiert der Compiler komplett weg. ;-)
Moby A. schrieb:> Ok A.K., sei es wie es sei, die 5-6 Takte für den Vergleich von einer> 32- mit einer 24-Bit Konstante samt Sprung sind für 8-Bit AVR utopisch.
Gibs einfach zu, dass du es in ASM nicht so schnell hinkriegst wie der
C-Compiler...
Tse schrieb:> Moby A. schrieb:>> Ok A.K., sei es wie es sei, die 5-6 Takte für den Vergleich von einer>> 32- mit einer 24-Bit Konstante samt Sprung sind für 8-Bit AVR utopisch.> Gibs einfach zu, dass du es in ASM nicht so schnell hinkriegst wie der> C-Compiler...
Ich fürchte Dir fehlen da gewisse Kenntnisse, was mit 8-Bit AVR möglich
ist und was nicht.
Tse schrieb:> Gibs einfach zu, dass du es in ASM nicht so schnell hinkriegst wie der> C-Compiler...
Ich würde es ja liebend gerne mit deiner Asm-Version vergleichen. Deinen
erstaunten und ungläubigen Beträgen zufolge scheint die aber wesentlich
langsamer zu sein als die C Version.
Moby A. schrieb:> Und die eigentliche Absicht manchen Schreibers zu eindeutig ;-)
Stimmt. Ich bin immer noch daran interessiert, "best practices" für
Embedded-Programmierung zu lernen. Genau aus dem Grund, weil ich noch
nie in ein großes Projekt mit anderen eingebunden war und solche Sachen
eben aus irgendwelchen Internet-Threads und -Blogs herauslesen muß, weil
es die passenden Bücher nicht gibt.
Diese Diskussion um ASM nervt da nur. Zumal sie zu keinem Ergebnis
kommen wird. Also: mich nervt sie. Ich gönne euch aber auch euren
Spaß.
Moby A. schrieb:> Ich fürchte Dir fehlen da gewisse Kenntnisse, was mit 8-Bit AVR möglich> ist und was nicht.
Dann zeig uns was deiner Meinung nach möglich ist (ASM-Code) und wir
vergleichen es mit dem Code des Compilers...
Moby A. schrieb:> Ich fürchte Dir fehlen da gewisse Kenntnisse, was mit 8-Bit AVR möglich> ist und was nicht.
Bestimmt. Aber dafür habe ich Kenntnisse, was mit C Compilern möglich
ist, und in letzten Fall, also für dein if(const32<const24) reichen die
aus, denn das Ergebnis davon ist völlig unabhängig vom Prozessor.
A. K. schrieb:> Ich würde es ja liebend gerne mit deiner Asm-Version vergleichen. Deinen> erstaunten und ungläubigen Beträgen zufolge scheint die aber wesentlich> langsamer zu sein als die C Version.
Erstaunt?
Ungläubig?
Belustigt triffts eher.
Da wär ich fast vorsichtig, daß Dir der C-Compiler nicht gleich alles
wegoptimiert und Du dann ohne Lösung dastehst.
Moby A. schrieb:> Da wär ich fast vorsichtig, daß Dir der C-Compiler nicht gleich alles> wegoptimiert und Du dann ohne Lösung dastehst.
Jau, das ist manchen her im Forum auch schon passiert. Beispielsweise
weil sie es nun mit eigenen Delayloops probierten, die auf mysteriöse
Art völlig verschwanden, oder sie erst lernen mussten, wozu "volatile"
da ist.
Aber zwei Konstanten selber miteinander zu vergleichen, statt dafür Code
zu erzeugen, ist nun wirklich kein Hexenwerk für einen Compiler. Nur war
das nicht die eigentliche Aufgabe, sondern (hoffentlich) bloss eine
etwas verunglückte Formulierung von dir.
A. K. schrieb:> Moby A. schrieb:>> Ich fürchte Dir fehlen da gewisse Kenntnisse, was mit 8-Bit AVR möglich>> ist und was nicht.>> Bestimmt. Aber dafür habe ich Kenntnisse, was mit C Compilern möglich> ist, und in letzten Fall, also für dein if(const32<const24) reichen die> aus, denn das Ergebnis davon ist völlig unabhängig vom Prozessor.
Vergleich von Konstanten?
Was belegt das nun die Überlegenheit von C ?
Der Scherz ist ja noch dümmer als ich dachte.
Schau mal ich möchte mich hier verzweifelt von den Codesize- und
Performance-Vorteilen von C überzeugen lassen !!!! ;-)
Moby A. schrieb:> Vergleich von Konstanten?
Wie soll ich deinen Text ...
Moby A. schrieb:> für den Vergleich von einer 32- mit einer 24-Bit Konstante
... denn sonst verstehen?
Moby A. schrieb:> Schau mal ich möchte mich hier verzweifelt von den Codesize- und> Performance-Vorteilen von C überzeugen lassen !!!! ;-)
Ich umgekehrt auch. Aber dafür fehlt mir deine Asm-Version.
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
Beide Methoden haben vollig verschiedenes Zeitverhalten.
Wenn ich Assembler verwende, habe ich die Kontrolle darüber.
Wenn ich Hochsprache verwende, habe ich diese Kontrolle nicht.
Moby A. schrieb:> deren Relevanz für typische> 8-Bit AVR Projekte hinreichend zweifelhaft ist.
Heißt das so viel wie dass ein AVR, für Projekte wo man Zahlen >8bit hat
eh nicht hergenoimmen wird weil es bessrees git?
Josef G. schrieb:> Beide Methoden haben vollig verschiedenes Zeitverhalten.> Wenn ich Assembler verwende, habe ich die Kontrolle darüber.> Wenn ich Hochsprache verwende, habe ich diese Kontrolle nicht.
Korrekt. Wo eine taktgenaue Reproduzierbarkeit des Zeitverhaltens
gefordert ist, da ist an dieser Stelle eine Hochsprache nicht
zuverlässig einsetzbar (VHDL&Co sind hier wohl nicht gemeint).
Glücklicherweise ist das nicht oft der Fall.
Moby A. schrieb:> Schau mal ich möchte mich hier verzweifelt von den Codesize- und> Performance-Vorteilen von C überzeugen lassen !!!! ;-)
Ohne dem Augenzwinkern am Ende, hätte ich jetzt gesagt: Hatten wir doch
schon. 5-6 Takte.
Nur, wieso meinst du das ironisch?
Glaubst du nicht dran? Interessiert es dich eigentlich gar nicht, weil
du von deinem ASM-Code so überzeugt bist? Willst du die Leute zum
ASM-Masochismus erziehen?
Schreib' doch einfach die paar Zeilen. Hinterher wirst du
auseinandergenommen, weil's viel zu lang ist. Und du kannst sagen, ich
mach's trotzdem so. Vielleicht ist der Code aber gar nicht so schlecht
und kann mit dem Compiler mithalten. Ja dann..., dann steht's
Unentschieden und es geht in die nächste Runde.
Josef G. schrieb:> Beide Methoden haben vollig verschiedenes Zeitverhalten.> Wenn ich Assembler verwende, habe ich die Kontrolle darüber.> Wenn ich Hochsprache verwende, habe ich diese Kontrolle nicht.
NB: Oberhalb von relativ einfachen Mikrocontrollern, also bei
schnelleren Prozessoren wie x86 oder Cortex-A (RasPi), hast du auch in
Assembler keine wirkliche Kontrolle mehr darüber.
Josef G. schrieb:> Berechne B0 - A0 mit Carry
ohne Carry (in)
> Berechne B1 - A1 mit Carry> Berechne B2 - A2 mit Carry> Berechne B3 - A3 mit Carry> Sprung falls Carry gesetzt
je nach Prozessor falls Carry nicht gesetzt
Ralf G. schrieb:> Was interessiert, ist ja allerdings: Wie macht's Moby?
Wenn ich den Thread hier so verfolge:
Gar nicht. Denn so eine Fragestellung ergibt sich für ihn nicht, das ist
ja auch völlig unrealistisch.
Wäre ich nicht so boshaft, wie ich bin, würde ich jetzt nicht den
Verdacht äußern, daß er ein Programmieranfänger ist, der für sich das
große Feld der Assemblerprogrammierung entdeckt hat ... d.h. er weiß
jetzt, wo das Feld ist, und hat sich vorgenommen, es nächste
Woche/nächsten Monat/nächstes Jahr ganz sicher auch mal oberflächlich zu
erkunden.
Ralf G. schrieb:> Was interessiert, ist ja allerdings: Wie macht's Moby?
Mir schwant, er hatte bisher so etwas wie die korrigierte Version von
Josefs 1. Variante im Auge und hat nun die bessere und auch vom Compiler
genutzte 2. Variante auf dem Tablett serviert bekommen. ;-)
A. K. schrieb:> Moby A. schrieb:> für den Vergleich von einer 32- mit einer 24-Bit Konstante>> ... denn sonst verstehen?>A. K. schrieb:> Moby A. schrieb:> Vergleich von Konstanten?>> Wie soll ich deinen Text ...>> Moby A. schrieb:> für den Vergleich von einer 32- mit einer 24-Bit Konstante>> ... denn sonst verstehen?>> Moby A. schrieb:> Schau mal ich möchte mich hier verzweifelt von den Codesize- und> Performance-Vorteilen von C überzeugen lassen !!!! ;-)>> Ich umgekehrt auch. Aber dafür fehlt mir deine Asm-Version.
Da gibts schon Angebote hier...
Man muß sie nur nutzen.
Dein Beispiel beweist gar nichts.
Ob mit Konstanten oder Variablen ;-)
Ralf G. schrieb:> du von deinem ASM-Code so überzeugt bist? Willst du die Leute zum> ASM-Masochismus erziehen?
Ich bin nicht von meinem Code überzeugt sondern kenne die Vorteile von
ASM.
Wenn Du damit nicht klarkommst (oder nicht damit befassen willst) bleib
doch bei C.
Moby schrieb:> Da gibts schon Angebote hier...
Klar, mittlerweile von Josef. Hast du da mal die Takte gezählt?
> Ich bin nicht von meinem Code überzeugt
Wär ich auch nicht, wenn ich keinen hätte.
Vielleicht überlegt er ja noch angestrengt (Moby, Anm. der Red.), ob er
das Ergebnis des heimlich besorgten gcc hier als sein Eigenes
präsentiert...
Nee, nee. Es kommt noch was. Es soll (diesmal) eben ordentlich werden.
So mit Kommentaren und 'Doku'. Wie hier...
Beitrag "Re: C versus Assembler->Performance"
... vorgemacht.
Rufus Τ. F. schrieb:> Wäre ich nicht so boshaft, wie ich bin, würde ich jetzt nicht den> Verdacht äußern, daß er ein Programmieranfänger ist, der für sich das> große Feld der Assemblerprogrammierung entdeckt hat ... d.h. er weiß> jetzt, wo das Feld ist, und hat sich vorgenommen, es nächste> Woche/nächsten Monat/nächstes Jahr ganz sicher auch mal oberflächlich zu> erkunden.
Da diktiert auch wieder eher eine bestimmte Absicht und Wunschdenken den
Text als denn reales Wissen...
Bist Du fähig mein obiges Beispiel als gleichlange C-Version zu liefern?
Nein?
Anfänger. Hauptsache große Klappe.
Moby schrieb:> Wenn Du damit nicht klarkommst (oder nicht damit befassen willst) bleib> doch bei C.
Ich bin aus der ASM-Masochisten-Phase raus. Hatte ich aber weiter oben
schon geschrieben.
A. K. schrieb:> Moby schrieb:> Da gibts schon Angebote hier...>> Klar, mittlerweile von Josef. Hast du da mal die Takte gezählt?>> Ich bin nicht von meinem Code überzeugt>> Wär ich auch nicht, wenn ich keinen hätte.
Und Du hast nur schlechtes Scherze...
Ralf G. schrieb:> Moby schrieb:> ...an Rufus...> Anfänger. Hauptsache große Klappe.>> Guck' an! Der Assembler-Papst! Jetzt wird er auch noch größenwahnsinnig!
Am Moderator zweifeln in Größenwahnsinn?
Das spräche eher für den Größenwahnsinn der Gegenseite.
Hat C-Papst Ralf hier noch was beizutragen um für seine Sprache zu
werben. Nimm meinen Code Stück für Stück auseinander. Lass Deinen
Compiler beim Optimieren heißlaufen! Doch da Du bei ASM nur Bahnhof
verstehst... Schaaaade.
Moby schrieb:> Dir bleibt nichts, die Vorteile von ASM zu bestreiten ;-)
Klar hat ASM, wie auch C/C++, Vor- und Nachteile. Ein fähiger Entwickler
wird diese abwiegen und für jedes Projekt die am besten geeignete
wählen.
Mehr gibts zu C(++) vs. ASM eigentlich nicht zu sagen.
Realist schrieb:> für jedes Projekt die am besten geeignete> wählen.
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.
Moby schrieb:> Hat C-Papst Ralf hier noch was beizutragen um für seine Sprache zu> werben.
Den Titel hab' ich wirklich nicht verdient! Ich mach' das nur aus Spaß.
Aber ich kenne (von Können bin ich weit weg, sag' ich jetzt mal) beides.
Bin nur bei C hängengeblieben. Du kannst da gerne drüber lächeln (von
mir aus auch lachen), so wie der eine oder andere C-Programmierer
vielleicht über BASCOM grinst.
Wenn du nach diesem
(Beitrag "Re: C versus Assembler->Performance") Post
ein Ergebnis präsentiert hättest, wärst du der Chef gewesen. Niemand
hätte das erwartet. Alle hätten sich vor dir verneigt. Aber du windest
dich wie ein Aal. Tja, warum nur?
(Nicht mal jetzt kommt eine Lösung, obwohl feststeht, dass es nur ein
Assembler-5-Zeiler ist.)
Moby schrieb:> Das heißt (zumindest) für viele 8-Bit Projekte: Assembler.
Wenn man Entwichlungsaufwand, Wartbarkeit und Portierbarket mal weglässt
könntest du recht haben. Zuden ist die schnellst- (Ausführzeit) und
kleinstmögliche (RAM, Flash) Lösung oft nicht notwendig und einfach nur
overkill.
@Ralf G.
Ich mag hier eigentlich über nichts anderes reden als es das Threadthema
nahelegt: Wie nah vermag C an die mit ASM möglichen Ergebnisse in
Codesize und Performance herankommen? Welchen Aufwand erfordert das?
Scherzhaft würde ich die Verhältnisse so beschreiben: Ist wie mit dem
Stück Masse (C) daß nur mit immer mehr Energieaufwand hin zur
Lichtgeschwindigkeit (ASM) beschleunigen kann und sie doch nie erreicht
;-)
Wer irgendwo der Chef ist kannst Du ja gern mit anderen diskutieren.
Moby, es interessiert mich wirklich den von A.K.oben genannten Vergleich
von dir zu sehen. Ich lerne gerne dazu und würde mich über eine Lösung
von einen ASM-Verfechter freuen. Bitte in übersetzbarer Form schreiben
und keinen Pseudocode.
Danke dir.
Gruß 900ss
Moby schrieb:> Ist wie mit dem> Stück Masse (C) daß nur mit immer mehr Energieaufwand hin zur> Lichtgeschwindigkeit (ASM) beschleunigen kann und sie doch nie erreicht> ;-)
Jetzt verstehe ich: Du hast keinen blassen Schimmer, um was es hier
geht!
Schade.
Die Frage...
Ralf G. schrieb:> Johann L. schrieb:>> Mal ne kanz konkrete Frage: Wie testest du in AVR-Assembler, ob ein>> (einen) 32-Bit Wert kleiner als 1000000 ist?>> (Nur mal unter uns, es liest ja keiner mit: Du denkst, daran scheitert> er schon?)
... war eher ironisch gemeint, sollte ein bisschen povozieren.
Ich bin fix und fertig. So ein Blender, Schaumschläger... Ich hätte nie
gedacht, dass es sooo schlimm steht.
Moby schrieb:> Realist schrieb:>> einfach nur>> overkill.>> Bei sowas kommen mir immer gleich die dicken C-Bücher
<300 Seite C&R für eine universal einsetzbare Sprache vs. 152 Seiten
Atmel AVR 8-bit Instruction Set ist jetzt nciht soo dich.
> Konfiguritis der Compiler
Muss man nicht machen, wenn aber optimierten Code haben will muss man
sich -wie in ASM*- "anstrengen". Nur dass es in C nur ein Compilerflag
ist.
*Und nein, ASM Code ist nicht optimiert nur weil er in ASM geschrieben
wurde, man muss ich auch anstrengen.
-----------
Das Problem von Horst S. ist gelöst. Der Gegenbeweis wird ausbleiben.
Ich würd's wieder nach 'Compiler & IDEs' zurückschieben und ein Schloss
dranhängen.
900ss D. schrieb:> Moby, es interessiert mich wirklich den von A.K.oben genannten> Vergleich von dir zu sehen.
Das ist ja toll.
Wir reden vom Vergleich einer 32-Bit Variablen mit einer Konstanten, ja?
Die Lösung (Varbytes nacheinander abklappern) hatte ich schon
angedeutet, A.K. hat den Ablauf präzisiert. Ich denke das ist das was
maximal möglich ist. Selbst wenn ein Compiler das mit gleicher Codesize
umsetzen würde (was ich nicht weiß) hätte das für /mich/ keine
Bedeutung, da ich bzw. typische 8-Bit Apps solche hochbittigen
Operationen selten benötige(n).
Sofern Dein Interesse hier zwischenzeitig nicht noch irgendwo befriedigt
wird hole ich das gern später nach. Die von A.K. skizzierte
Vergleichsfolge ist nun allerdings alles andere als interessant bzw. von
besonderem Genie durchtränkt- aber das Optimum.
Ralf G. schrieb:> Ich bin fix und fertig. So ein Blender, Schaumschläger... Ich hätte nie> gedacht, dass es sooo schlimm steht.
Wirklich schade das es nur noch zu diesem Niveau reicht... Ist aber auch
heiß heute...
Rea L. schrieb
> Atmel AVR 8-bit Instruction Set
Das merkt man sich besser und besser. Sind ja nur vergleichsweise simple
Anweidungen. Bei Flagauswirkungen einzelner Befehle schau ich manchmal
auch noch rein.
> *Und nein, ASM Code ist nicht optimiert nur weil er in ASM geschrieben> wurde, man muss ich auch anstrengen.
Absolut. Vom Selbstläufer zum effizienten Werk hat niemand gesprochen.
Aber von allen Möglichkeiten dazu.
Ralf G. schrieb:> Ich würd's wieder nach 'Compiler & IDEs' zurückschieben und ein Schloss> dranhängen.
Schon klar. Wenn man nichts mehr beizutragen hat ...
Moby schrieb:> Ich mag hier eigentlich über nichts anderes reden als es das Threadthema> nahelegt: Wie nah vermag C an die mit ASM möglichen Ergebnisse in> Codesize und Performance herankommen?
BTW: Wo wir jetzt im Offtopic sind. Nach den zig Texten, die Du jetzt
hier abgelassen hast:
Der Chefarzt nebst Assistent, drei Schwestern und dem Anästesist stehen
im OP über 'ner Bypass-Operation gebeugt. Da geht die Schiebetür auf,
'nen Dackel spaziert herein und pisst dem Chefarzt ans Bein.
Du, da ist kein Witz dabei und es wird nicht witzig dadurch, dass der
Dackel mit dem Schwanz wedelnd rausspaziert oder eine Schwester
hysterisch anfängt zu kichern.
Es ist ganz einfach: Der Dackel gehört da nicht hin (und ich darf Dich
zitieren: Du hast bis auf einen Versuch niemals eine Hochsprache
bedient), es stinkt danach erbärmlich nach Pisse (wir landen im OT) und
bis auf die Befriedigung des Dackels (Blasenentleerung) hat keiner was
von der Geschichte.
Kannst Du Dein Geschäft das nächste mal bitte an 'nem Baum erledigen?
DANKE
Moby A. schrieb:> Immer dann wenn die Argumente ausgehen ;-)
Ich brauche keine Argumente. Ich hab als TE um Hilfe gebeten. Du hast
sie nicht erbracht. Stattdessen hast Du Dich in das kleine Wort
"Assembler" im Titel verkeilt, völlig missverstanden und Dein eigenes
Ding gedreht, während sich die Welt im Thread für mich von anderer Seite
angestubbst ein Stückchen weiter gedreht hat.
Was hast Du gelernt - NIX.
Was hast Du mir beigebracht - NIX.
Was hab ich gelernt - EINIGES, ABER NICHT VON DIR.
Ich wollte was über C wissen, dazu bist Du nicht qualifiziert.
Ob Du für Assembler qualifiziert bist? Nach dem Bohei, den Du
veranstaltet hast, ist es mir ehrlich gesagt, egal, ICH würde DICH nicht
mehr konsultieren.
@TO
In einem öffentlichen wie diesem Thread musst Du mit den Antworten
leben, die sich wie in diesem Fall um Dein Thema "C
vs.Assembler->Performance" drehen- und die sich entwickelnde Diskussion
akzeptieren die ich natürlich nicht allein gestalte. Wenn Du mehr
Einfluß möchtest, mußt Du Dich auf Gespräche im Bekanntenkreis
beschränken. Denen wünsche ich nicht, jemals so übel beleidigt zu
werden.
Wollt ihr WIKLICH Fundamantalisten überzeugen? Gibt's keine besseren
Wege zum Zeit totschlagen? Z.B. Wind um die Ecke schaufen?
Jeder, der halbwegs clevver ist nutz das Werkzeug, dass im
Gesamtzusammenhang am ökonomischsten für ihn ist. Der Erfolg gibt einem
Recht! Jenseits von Sandkastspielereien trennt sich die Spreu ganz
schnell vom Weizen.
Moby A. schrieb:> Ralf G. schrieb:>> Nun, 1000000 dezimal sind [0F 42 40] Hex. Einen 32-Bit Wert kann man> doch nun Byte für Byte abklappern ob er kleiner ist. Stellt Euch doch> nicht so dämlich.
Es war lediglich die Frage einen ASM-Experten, welche *kontret* Sequenz
er einsetzen würde.
Wie man das im Prinzip machen kann weiß hier wohl jeder. Ich war eben
nur neugierig auf eine ASM-Moby-Lösung. Aber Moby scheint lieber
weitschweifige Prosa zu produzieren als einen 10-Zeiler.
> Ach was. Wer Asm versteht kann das samt Datenblatt problemlos.> Mit der Aufgabe einem C-ler ASM zu erklären beschäftige ich mich nicht.> Und lenkt doch nicht ständig mit der Schreibweise, die gerade schön kurz> und knapp und gerade nicht so romanfüllend wie Hochsprachencodes> daherkommt, vom eigentlichen Problem ab: C ist einfach mehr sprachlicher> Aufwand für größere, langsamere Ergebnisse.
Okay, ich hab tatsächlich mal den LM335-Code in C dargestellt.
Dabei hab ich mir erlaubt, auf magische Zahlen wie $40 oder $e7 zu
verzichten:
== Quelle ==
C: Das weitschweifige Programm hat 34 Zeilen, von denen allerdings 14
Zeilen keinen Code enthalten und "nur" der Lesbarkeit dienen.
Moby-ASM: Ca. 40 Zeilen alleine für "adu".
== ASM-Code ==
avr-gcc: Braucht 40 Instruktionen für "adu", davon sind 5 32-Bit
Instruktionen.
Moby-ASM: Braucht 40 Instruktionen für "adu" (korrigierte Version),
davon sind 7 32-Bit Instruktionen.
Moby-ASM: Nach Moby die optimale Lösung.
avr-gcc: Hat nicht den Anspruch, die beste Lösung zu liefern, ist aber
um 4 Bytes kürzer. Die Registerlast ist höher als bei Moby, was hie
allerdings keine Rolle spielt.
avr-gcc: Inspektion des erzeugten ASM zeigt, dass der Code tatsächlich
suboptimal ist, und mindestens 3 Instruktionen überflüssig sind.
Ergo: Wenn Moby seinen optimalen ASM-Code noch optimaler bekommen will,
lohnt ein Blick über den Tellerrand.
Johann L. schrieb:> Okay, ich hab tatsächlich mal den LM335-Code in C dargestellt.
Danke!
Allerdings gefällt mir das Zitat nicht:
Johann L. schrieb:> Moby A. schrieb:>> Ralf G. schrieb:>>>> Nun, 1000000 dezimal sind [0F 42 40] Hex. Einen 32-Bit Wert kann man>> doch nun Byte für Byte abklappern ob er kleiner ist. Stellt Euch doch>> nicht so dämlich.
Das sieht so aus, als ob ich den Text geschrieben hätte.
(Also 1000000 händisch in Bytes zu zerlegen... tsss... Solchen Quatsch
mach' ich nicht.)
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 wird noch etwas dauern, aber
danke der Bemühung. Allerdings hatte ich meinen ASM
Projekt-Codeschnipsel mit wenig aufregender Codesequenz hier gar nicht
zur Diskussion gestellt, sondern das angehängte Programm weiter oben.
Aber egal.
Ein Blick über den Tellerrand ist immer sinnvoll.
Welche Erkenntnisse das bringt ist die zweite Frage.
Falk B. schrieb:> Jeder, der halbwegs clevver ist nutz das Werkzeug, dass im> Gesamtzusammenhang am ökonomischsten für ihn ist. Der Erfolg gibt einem> Recht!
Das ist jetzt inwiefern fundamentalistisch?
Johann L. schrieb:> ist aber um 4 Bytes kürzer
Hab ich jetzt was übersehen? Du schreibst, beides ist 40 Byte lang. Was
den optimierten ASM Code von Moby immer noch nicht vorne stehen läßt.
Johann L. schrieb:> Ergo: Wenn Moby seinen optimalen ASM-Code noch optimaler bekommen will,> lohnt ein Blick über den Tellerrand.
Gib ihm jetzt bloß nicht das Listing.
Gib ihm 'ne Anweisung, wie er gcc zu installieren hat, wo er den Code
hineinkopieren kann und wie er in das Listing reinschauen kann.
MACH JETZT BLOSS KEINEN FEHLER!
Moby A. schrieb:> Die Lösung (Varbytes nacheinander abklappern) hatte ich schon> angedeutet
Danke für die Unterstützung Moby. Ich hätte wirklich gerne von dir
dazugelernt. Aber die anderen haben oben scheinbar Recht, du schwafelst
hier nur rum und kannst nix. Sonst hättest du hier konkret die ASM
Anweisungen gepostet. Deine Lösung wäre wirklich interessant gewesen :-(
Horst S. schrieb:> MACH JETZT BLOSS KEINEN FEHLER!
Hat der Herr seinen Humor wiedergefunden?
So ernst scheint Dir "Dein" Thread dann auch nicht zu sein...
900ss D. schrieb:> Moby A. schrieb:> Die Lösung (Varbytes nacheinander abklappern) hatte ich schon> angedeutet>> Danke für die Unterstützung Moby. Ich hätte wirklich gerne von dir> dazugelernt. Aber die anderen haben oben scheinbar Recht, du schwafelst> hier nur rum und kannst nix. Sonst hättest du hier konkret die ASM> Anweisungen gepostet. Deine Lösung wäre wirklich interessant gewesen :-(
Hatte ich nicht weiter oben geschrieben die bekommst Du noch? Dein
letzter Beitrag gibt mir schon arg zu denken wie ernstgemeint Dein
Wunsch war ;-(
Horst S. schrieb:> Gib ihm jetzt bloß nicht das Listing.
Das wäre nicht so schlimm.
Wie du selber gemerkt hast (sogar als C-Neu-Einsteiger??), mit 'C'
kannst du ordentlich Struktur reinbringen. Der Assembler macht dann Code
draus, der, falls man im Original darauf angewiesen ist, einfach nicht
wartbar, nicht übersichtlich, nicht mal so fix erweiterbar ist. Willst
du bei einem Assembler-Programm die Übersicht behalten, kostet das eben
Ressorcen. Das geht sicher irgenwie (bis zu einer gewissen Größe). Der
Compiler braucht sich darum aber nicht zu kümmern.
Also: Das Assemblerlisting vom Compiler ist so speziell, will man nur
eine Kleinigkeit ändern, kann man's auch neu machen... [leicht
übertrieben :-) ]
Moby A. schrieb:> Hatte ich nicht weiter oben geschrieben die bekommst Du noch?
Upps, das hatte ich nicht so verstanden. Dann freu ich mich auf eine
Lösung von dir. Danke.
Moby A. schrieb:> Hatte ich nicht weiter oben geschrieben die bekommst Du noch?
Mundgemalt, auf feinstem Büttenpapier, welches du nächste Woche erst in
China persönlich abholst?
A. K. schrieb:> zu Lasten von ein paar> Befehlen mehr> diesen mit 9 Takten doch wesentlichen schnellern Code produziert:
Vor diesem Szenario steht man auch öfter bei Asm:
weniger Platz oder mehr Performance. In diesem Fall hab ich weniger
Platzbedarf den Vorzug gegeben.
Johann L. schrieb:> uint16_t *adc = & ADUC[adc_num];> uint16_t sum64 = adc[N_ADCs] += ADC;
Die beiden Zeilen kommen mir total spanisch vor. Liegt sicher nur an
meinem niedrigen Niveau. Warum '+='? 16-Bit-Werte aufaddieren... Das
passt zum Schluss immer noch in 16 Bit? Ich durchschaue den Trick nicht.
(Bitte nicht hauen!)
Und dann noch der extra Index am Zeiger. Ich gebe auf...
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 ;-)
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:
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...
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? ;-)
Ausnahmsweise:
Moby A. schrieb:> Ja hab schon mal.
Mensch Moby, das war 'ne Steilvorlage!! Falsch. Das war 'n Elfmeter mit
doppelter Torbreite, ohne Torwart, mit zwei Versuchen! Und du
versemmelst das! Ich fass' es nicht.
Ralf G. schrieb:> Johann L. schrieb:>> uint16_t *adc = & ADUC[adc_num];>> uint16_t sum64 = adc[N_ADCs] += ADC;> Die beiden Zeilen kommen mir total spanisch vor.> [...] Und dann noch der extra Index am Zeiger. Ich gebe auf...
Das liegt an der asm-Vorlage. Die 2 Variablen, die zur "Verwaltung"
eines ADC-Kanals gehören, liegen im Speicher verstreut.
Ohnehin ist es recht sinnfrei, einen gegebenen Asm-Code genauso umsetzen
zu wollen — das zeigen schon die magischen Konstanten wie $40. (Die zu
entsorgen freilich auch mit Asm nix kostete. Sie sind der Tribut an
einen Hang zur Kryptophilie).
* Die Variablen, die man zur "Verwaltung" eines ADC-Kanals brauch, wird
man zusammenhalten wollen, z.B. in einer Struktur wie unten.
* Der IRQ-Zähler hat eigentlich nix mit dieser Routine zu tun; den wird
man von außen reingeben. Falls er doch zum Modul gehören sollte, dann
in die gleiche Struktur in der auch die adcs[] leben:
1
typedefstruct
2
{
3
structadc
4
{
5
uint16_tresult,temp;
6
}adcs[4];
7
uint8_tn_irq;
8
}aduc_t;
9
10
aduc_tADUC;
11
12
voidadu(uint8_tn_irq)
13
{
14
uint8_tn_adc=3&(n_irq>>6);
15
structadc*adc=&ADUC.adcs[n_adc];
16
17
uint16_ttemp=adc->temp+=ADC;
18
19
if(0==(n_irq&0x3f))
20
{
21
adc->result=temp>>6;
22
adc->temp=0;
23
24
uint8_trefs=(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
externvoidf(void);
2
3
voidcaller(uint32_tval)
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.
Johann L. schrieb:> cpi r22,64> sbci r23,66> sbci r24,15> cpc r25,__zero_reg__
Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test
gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche, sondern so
gemischt.
(Ist gleich lang, gleich schnell. Sieht nur 'ungewöhnlich' aus.)
Moby schrieb:> Verstehen hier wirklich so wenige noch Asm?
Keiner hängt sich das Assembler-Täfelchen so nachdrücklich um den Hals
wie du...
Moby A. schrieb:> @TO> In einem öffentlichen wie diesem Thread musst Du mit den Antworten leben
Nicht unbedingt. Es es sein Thread. Er hat ihn eröffnet und darf ihn
zuallererst selber moderieren. Dass ihm Andere seinen Thread
entführen und verunstalten gehört nicht zum guten Umgangston.
Im realen Leben ist es, wie wenn er eine Besprechung einberufen hat, und
einfach jeder sein Zeug bespricht. Das ist zumindest unhöflich...
Schön, daß der Code weiter verbessert wird, obwohl ich immer noch nicht
durchsteige... So kann ich leider noch nicht die Gleichwertigkeit mit
meinem Code abschätzen. Allerdings hab ich den Eindruck, daß meine
Lösung schneller aufs Papier gebracht war, halte Johann L. aber auch die
Zeit fürs Reverse Engineering zugute ;-) Ganz sicher ist aber, daß diese
Form kryptischer Problemlösung niemals die meine werden wird.
Schließlich wollte ich noch die versprochene Lösung für 900ss
nachtragen:
Der C-Vorgabe
> void f (void);>> void caller (uint32_t val)> {> if (val < 1000000)> f();> }
ist die Lösung
> Lösung:caller:> cpi r22,64> sbci r23,66> sbci r24,15> cpc r25,__zero_reg__> brsh .L1> jmp f> .L1:> ret> .ident "GCC: (GNU) 5.2.1 20150816"
nicht ganz äquivalent, weil die Variable verloren geht.
Besser und ohne die Konstante in ihre Bytebestandteile zu zerlegen ist
ganz unspektakulär
1
.equ Konstante = 1000000
2
3
cpi r25,byte4(Konstante)
4
brlo f1
5
cpi r24,byte3(Konstante)
6
brlo f1
7
cpi r23,byte2(Konstante)
8
brlo f1
9
cpi r22,byte1(Konstante)
10
brsh end
11
f1: ...
12
13
end: ret
Das kostet im Maximum 9 Takte.
Lothar M. schrieb:> Moby schrieb:>> Verstehen hier wirklich so wenige noch Asm?> Keiner hängt sich das Assembler-Täfelchen so nachdrücklich um den Hals> wie du...
... mit dem 8-Bit AVR in der Hand. Das bleibt eine ideale Kombination.
Da ist das letzte Wort hier noch lange nicht gesprochen.
> Es es sein Thread. Er hat ihn eröffnet und darf ihn> zuallererst selber moderieren. D
Der TO hat sich lebhaft an der Diskussion beteiligt.
Einige Moderatoren (mit mir) auch (nicht immer sehr sachlich).
Die Beschwerde kam erst in Form einer üblen Beleidigung.
Darum solltet Ihr Moderatoren Euch mal zuallererst kümmern.
> Im realen Leben
sind wir hier nicht.
Das schließt Höflichkeit natürlich nicht aus.
Ralf G. schrieb:> Warum nicht nur Subtraktion bzw. Vergleiche, sondern so> gemischt.
Mist. Meine Assemblerkenntnisse sind doch ganz schön eingerostet. (Der
Vergleich mit Übertrag...)
Moby A. schrieb:> Das kostet im Maximum 9 Takte.
Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem
Thread anmerken muss. Beispielsweise wenn r25 > byte4(...) aber r24 <
byte3(...).
A. K. schrieb:> Moby A. schrieb:>> Das kostet im Maximum 9 Takte.>> Und ist falsch.
Ich fragte mich schon, warum der Johann dem Moby so eine einfache
Aufgabe stellt. Um den Moby an seine Grenzen zu führen, muss doch was
richtig Knackiges her.
Aber offensichtlich war die Aufgabe immer noch zu schwer :(
Und bevor wir hier weiterdiskutieren und immer mehr vom Usprungsthema
abkommen:
Moby, fang doch bitte einen neuen Thread an. Dann beschwert auch keiner
darüber, dass du den Thread kaperst.
Moby A. schrieb:> .equ Konstante = 1000000>> cpi r25,byte4(Konstante)> brlo f1> cpi r24,byte3(Konstante)> brlo f1> cpi r23,byte2(Konstante)> brlo f1> cpi r22,byte1(Konstante)> brsh end> f1: ...>> end: ret
Eben, leider falsch, und sicherheitshalber hier mal zitiert, ansonsten
verschwindet das wieder, wie weiter oben schon einmal ein Detail.
A. K. schrieb:> Moby A. schrieb:>> Das kostet im Maximum 9 Takte.>> Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem> Thread anmerken muss. Beispielsweise wenn r25 > byte4(...) aber r24 <> byte3(...).
Klar, hast recht. So geht das nun nicht. Ist wohl schon zu spät heute
geworden ;-)
Ich liefere aber noch eine korrekte Lösung, soviel Ordnung muß sein.
Dann soll der TO walten wie er will.
Obs dann hier noch lange weitergeht?
A. K. schrieb:> Und ist falsch. Ulkig, dass ich dies nun schon zum zweiten Mal in diesem> Thread anmerken muss.
Täusche ich mich oder geht es hier immer noch um den Vergleich zweier
4-Byte-Zahlen? Den Fehler hatte ursprünglich ich eingeschleppt:
Josef G. schrieb:> Vergleich von zwei unsigned 4-Byte-Zahlen A und B> mit 8bit-CPU und Sprung falls A > B>> Die 4 Bytes seien A3,A2,A1,A0 bzw. B3,B2,B1,B0>> Methode 1:>> Teste A3 > B3> Sprung falls A3 > B3> Teste A2 > B2> Sprung falls A2 > B2> Teste A1 > B1> Sprung falls A1 > B1> Teste A0 > B0> Sprung falls A0 > B0>> Methode 2:>> Berechne B0 - A0 mit Carry> Berechne B1 - A1 mit Carry> Berechne B2 - A2 mit Carry> Berechne B3 - A3 mit Carry> Sprung falls Carry gesetzt
Die korrigierte Version von Methode 1 hat A.K.
schon angegeben. Ich würde sie so schreiben:
Teste A3 > B3
Sprung falls A3 > B3
Abbruch falls nicht A3 = B3
Teste A2 > B2
Sprung falls A2 > B2
Abbruch falls nicht A2 = B2
Teste A1 > B1
Sprung falls A1 > B1
Abbruch falls nicht A1 = B1
Teste A0 > B0
Sprung falls A0 > B0
Dabei ist angenommen, dass der compare-Befehl einen Carry und
ein Zero-Flag liefert. Abbruch bedeutet Sprung ans Ende.
Bei Methode 2 ist angenommen, dass die CPU bei der Subtraktion den
Subtrahenden und den Carry am Addierer invertiert (wie bei 8085)
und nicht nur den Subtrahenden invertiert (wie bei 6502), und
dass zu Beginn der Carry Null ist.
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 ;-)
Und der (der Compiler) ist praktisch nur im AVR-Studio auf 'Assembler
Help' gegangen, hat das Beispiel zum 'cpc-Befehl' abgekupfert und auf
vier Bytes erweitert. ;-)
Ralf G. schrieb:> Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test> gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche, sondern so> gemischt.
Für jedes Byte eines Multibyte-Compares wird einzeln die Entscheidung
getroffen, welcher Befehl verwendet wird. Fürs erste Byte gibt es CPI,
für das letzte das Register mit Inhalt 0. Für die anderen wird
nachgesehen, ob die linke Seite überschrieben werden darf. Wenn ja wird
SBCI draus, wenn nicht LDI/CPC. Passt so auf beide Versionen des Codes,
die vorherige mit SBCI und die jetzige mit LDI/CPC. Siehe Johanns Link
oben, das hat er verbrochen.
Würde die Entscheidung über die zu verwendenden Methode vorneweg für
alle Bytes getroffen, statt für jedes Byte einzeln, wäre hier die
Optimierung über das Zero-Register über Bord gefallen.
Anders als Assembler-Programmierern ist Compilern die Eleganz des
entstehenden Codes gleichgültig.
Zu Mobys Fehleinschätzungen gehört wohl die Vorstellung, dass jene
Leute, die C verwenden, deshalb keine Ahnung von Asm hätten. Das trifft
freilich nicht immer zu.
A. K. schrieb:> Für jedes Byte eines Multibyte-Compares [...]Ralf G. schrieb:> Mist. Meine Assemblerkenntnisse sind doch ganz schön eingerostet. (Der> Vergleich mit Übertrag...)
Wie das funktioneren soll, ist mir schon klar. Ich hatte gedanklich in
der Sequenz einen Compare-With-Carry-Befehl drin, der auch Konstanten
verarbeitet. Den gibt's aber gar nicht. Und da kommt? ... natürlich die
Subtraktion ins Spiel.
Ralf G. schrieb:> der Sequenz einen Compare-With-Carry-Befehl drin, der auch Konstanten> verarbeitet. Den gibt's aber gar nicht. Und da kommt? ... natürlich die> Subtraktion ins Spiel.
Ein Compare-With-Carry Befehl ist ohnehin nicht sehr verbreitet. Die
meisten Architekturen kennen ihn nicht. Was freilich auch damit
zusammenhängt, dass er nur bei Architekturen mit mehreren
Rechenregistern im Zusammenspiel mit 2-Register-Befehlen Sinn ergibt.
Bei Akkumulator- oder 3-Register-Befehlen ist er sinnlos.
Recht clever und ebenfalls selten ist auch die Handhabung des Z-Flags in
SBC(I) und CPC, die ein für das Gesamtergebnis gültiges Z-Flag
hinterlässt. Bei den meisten Maschinen ist das Z-Flag nur für das letzte
Wort gültig und daher beim Multiwort-Vergleich nutzlos.
A. K. schrieb:> Recht clever ist auch die Handhabung des Z-Flags in SBC(I) und CPC
Ja. :)
Wie gesagt, ich weiß wo ich nachschlagen muss, da ich mir nicht mehr
alle Befehle geläufig sind. Da habe ich dann gesehen, dass es sowas wie
'cpci' gar nicht gibt. Hätte mich dann sicher für sowas...
A. K. schrieb:> Ergebnis vom Compiler:> cpi r22,64> ldi r18,66> cpc r23,r18> ldi r18,15> cpc r24,r18> cpc r25,__zero_reg__> brge .L1
... entschieden. Aber nicht um zu sagen: 'Bei mir existiert die Variable
aber noch!', sondern weil ich auf die andere Variante gar nicht gekommen
wäre.
Ralf G. schrieb:> sondern weil ich auf die andere Variante gar nicht gekommen wäre.
Das ist einfach nur die übliche Variante für zu Fuss programmierte
Vergleiche von potentiell längeren Strings, auch bei AVR. Allein schon,
weil du bei einem String nicht alle 50 Bytes abklappern willst, wenn es
nach den ersten paar Bytes schon klar ist.
Danke Moby, immerhin hast du deinen Code gepostet. Fazit: Auch
handgeschriebener ASM-Code ist nicht immer besser als der vom Compiler.
Ich verwende wohl weiter den Compiler.... Aber nicht nur deshalb. Alle
Vorteile des Compilers wurden ja schon genannt, selbst bei kleinen
Projekten ist die Verwendung von ASM-Code nur zweifelhaft von Vorteil.
Es gibt Gebiete, wo es sinnvoll ist, ihn einzusetzen (auch schon alles
weiter oben erwähnt), genauso wie ein GOTO in 'C'.
Warum du Moby, so verbissen an ASM festhälst, wird mir auch ein Rätel
bleiben, die von Dir genannten Vorteile sind alle objektiv widerlegt
worden. Deine persönliche Begeisterung für ASM-Code ist OK, wenn du mehr
Spaß daran hast, dann mach es so. Jedem das was er mag. Allerdings
sollte man schon objektiv bleiben und den Tellerrand hat Johann oben ja
schon mit gelungenen Worten erwähnt.
Neugier: Moby, ist programmieren eher aus Hobby betrieben oder verdienst
du dein Geld damit?
Moby A. schrieb:> Ganz sicher ist aber, daß diese Form kryptischer Problemlösung> niemals die meine werden wird.
Kryptisch sind beide; kryptisch, weil sie keine oder nur nixnutzige
Kommentare enthalten.
Johann L. schrieb:> Ob Code Code ist oder Hack, entscheidet sich zu 5% am Code und zu 95% an> Kommentaren und Dokumentation.> Schließlich wollte ich noch die versprochene Lösung für 900ss> nachtragen:>> Der C-Vorgabe>>> void f (void);>>>> void caller (uint32_t val)>> {>> if (val < 1000000)>> f();>> }>> ist die Lösung>>> Lösung:>>caller:>> cpi r22,64>> sbci r23,66>> sbci r24,15>> cpc r25,__zero_reg__>> brsh .L1>> jmp f>> .L1:>> ret>> .ident "GCC: (GNU) 5.2.1 20150816">> nicht ganz äquivalent, weil die Variable verloren geht.
Es ist absolut perfekt 100% äquivalent :-))
Der Wert in R22--R25 wird nämlich nicht mehr benötigt — falls doch, hat
Andreas schon eine Lösung gepostet:
A. K. schrieb:> Also gut, dann eben zerstörungsfrei:
1
>voidg(long);
2
>voidf(longx)
3
>{
4
>if(x<1000000)
5
>g(x);
6
>}
> Ergebnis vom Compiler:
1
> cpi r22,64
2
> ldi r18,66
3
> cpc r23,r18
4
> ldi r18,15
5
> cpc r24,r18
6
> cpc r25,__zero_reg__
7
> brge .L1
> Ergebnis von Moby:
1
> cpi r25,byte4(Konstante)
2
> brlo f1
3
> brne end
4
> cpi r24,byte3(Konstante)
5
> brlo f1
6
> brne end
7
> cpi r23,byte2(Konstante)
8
> brlo f1
9
> brne end
10
> cpi r22,byte1(Konstante)
11
> brsh end
Doch Vorsich! Der Moby-Vergleich geht NUR für unsigned. Für
vorzeichenbehaftete Zahlen muss eine andere Lösung her!
> ohne die Konstante in ihre Bytebestandteile zu zerlegen
Der von GCC erzeugte Assembler-Code ist selbsterklärend. Ist ja nicht
die Aufgabe von GCC, jemand Assembler oder Grundarithmetik beizubringen.
Und in Quelle steht "x < 1000000". Da ist nix zerlegt.
Yalu X. schrieb:> A. K. schrieb:>> Moby A. schrieb:>>> Das kostet im Maximum 9 Takte.>>>> Und ist falsch.>> Ich fragte mich schon, warum der Johann dem Moby so eine> einfache Aufgabe stellt.
Nur aus Interesse. Ehrlich gesagt hatte ich nicht erwartet, dass ein
erfahrener Programmierer da strauchelt. Oder zumindest die Haken und
Ösen ahnt und 2x nachdenkt bevor er / sie was schreibt. Ich hatte auch
nicht erwartet, dass er auf Anhieb die beste Sequenz findet, weil es die
eine beste Sequenz nämlich garnicht gibt.
> Aber offensichtlich war die Aufgabe immer noch zu schwer :(
Ich bin mir nicht sicher, ob das politisch korrekt ist, wenn ich hier
mal (in chronologischer Reihenfolge) was zusammenfasse. (Habe den
Beitrag prophylaktisch schon mal selbst gemeldet.) Ich hoffe, die Zitate
sind ohne den Zusammenhang noch sinngemäß.
-----
Weil eine Hochsprache ein Programm quasi aus Fertigbausteinen
zusammensetzt und die Aufgabenstellung damit nur unter Verlusten an
Platz und Performance gegenüber der feiner an die Gegebenheiten
anpassbaren Asm-Programmierung lösen kann.
-----
Hans schrieb:
> Wenn du nur 1:1 "übersetztst", dann wird C niemal kleiner als dein ASM> code werden.
Kleiner? Wie soll denn das passieren? Da muss sich ein Asm-Programmierer
aber schon selten dämlich anstellen :-)
-----
Eine uC-Softwarewelt braucht niemand retten, wenn sie mit pure Asm schon
im Klartext mit allen seinen Möglichkeiten, Transparenzen und Freiheiten
formuliert ist . Immer wieder schön, wenn dann der nächstkleinere
Controller genügt ;-)
-----
Ich möchte mir von keinem Compiler irgendwas vorschreiben und
verschleiern lassen, sondern das Heft des Handelns 100%ig selbst in der
Hand behalten. Wo überall geht das heute noch so einfach wie bei den
kleinen 8-Bittern? Dazu braucht es nur ein paar Dutzend Asm-Anweisungen
und das Datenblatt des Controllers seines Vertrauens.
-----
Die wenigen dutzend simplen Asm-Instruktionen bedeuten aber auch, man
braucht nicht mehr zu seinem Glück, es vereinfacht und macht die Sache
transparent.
-----
Vor der Aufgabe, ein gutes Programm zu schreiben stehen Asm- und C-
Programmierer gleichermaßen. Asm allein ist nun leider keine Garantie
für guten Code [...]
-----
X4U schrieb:
> Sagt mal, was ist an diesem Codeschnipsel eigentlich lesbar
Alles, wenn Du das Datenblatt und die paar Instruktionen kennst.
Klartext- und jeder weiß was gespielt wird.
-----
Das Ergebnis zählt und ein solches ist natürlich auch in C erreichbar.
Das ändert freilich nix an Simplizität und Effizienz von Asm für eine
große Klasse von Anwendungen.
-----
C ist einfach mehr sprachlicher Aufwand für größere, langsamere
Ergebnisse.
-----
[ Meine Lieblingsstelle ;-) , Moby an Rufus ]
Bist Du fähig mein obiges Beispiel als gleichlange C-Version zu liefern?
Nein?
Anfänger. Hauptsache große Klappe.
-----
Das heißt (zumindest) für viele 8-Bit Projekte: Assembler. Das Werkzeug
mit den maximalen Freiheiten und effektivstmöglichen Ergebnissen- mit
geringstem bürokratischen Aufwand.
-----
Autor: Moby AVR (moby-project) , Sommer 2015
PS:
Zählt das eigentlich jetzt schon als Aphorismen
Ralf G. schrieb:> Zählt das eigentlich jetzt schon als Aphorismen
Nö. Ein Aphorismus ist ein in sich widersprüchlicher Satz und ohne
Kontext verständlich.
Ralf G. schrieb:> Ich hätt's beinahe gegoogelt :-)
Vermutlich findet sich dieser Neologismus noch nicht im Duden. Dabei ist
die Bedeutung doch ganz einfach:
- Bei einem Aphorismus bringt jemand einen Gedanken auf den Punkt.
- Bei B-Forismus schreibt jemand in einem Forum immer wieder dasselbe
mit anderen Worten.
:-)
Ralf G. schrieb:> Johann L. schrieb:>> cpi r22,64>> sbci r23,66>> sbci r24,15>> cpc r25,__zero_reg__>> Oh, da hab' ich doch noch 'ne Frage, die ich mir schon beim Test> gestellt habe: Warum nicht nur Subtraktion bzw. Vergleiche,> sondern so gemischt.
Weil es so einfacher ist im Compiler:
Der geht alls Bytes von 0 bis N-1 durchund sucht die beste Möglichkeit
für den Byte-Vergleich.
o CPI geht weil 22 >=16.
o CPC 0 geht immer.
o SBCI geht weil 23 >= 16 und das Register danach nicht mehr
verwendet wird.
o CP/CPC geht immer
Wobei hier der Code einfach verbessert werden kann: Anstatt zu testen,
ob das 32-Bit Register noch verwendet wird, könnte getestet werden, ob
das entsprechende 8-Bit Subregister noch verwendet wird:
http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/config/avr/avr.c?revision=227035&view=markup#l5394
1
for(i=0;i<n_bytes;i++)
2
{
3
/* We compare byte-wise. */
4
rtxreg8=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
elseif(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:
Johann L. schrieb:> Weil es so einfacher ist im Compiler: [...]
Ich wusste (also, ich ahnte), dass es schwerer ist als
Ralf G. schrieb:> Da habe ich dann gesehen, dass es sowas wie> 'cpci' gar nicht gibt.
;-)
> Doch Vorsich! Der Moby-Vergleich geht NUR für unsigned. Für
vorzeichenbehaftete Zahlen muss eine andere Lösung her!
Das macht nichts. Kleine AVR's brauchen keine Vorzeichen ;-)
Moby's Kühlschrankdisplay zeigt die Temperatur eben in Kelvin an, auch
wenn man dabei ein Byte verschwenden muß, denn 255K sind recht kalt ;-)
Wenn man sich allein die letzten Diskussionen um Georg's
Compilerergebnis anschaut. Soll ich diese Entscheidungen, schnell und
fehlerfrei, bei jedem Vergleich selber machen, oder hab ich verstanden,
wozu es Software gibt. Auch wenn im Fall Software schreiben/Compiler nur
ein Problem gelöst wird, das es ohne IT gar nicht gäbe. Die Aufgabe von
Software ist nämlich solche Gedankengänge maschinenausführbar gemacht.
Man kann natürlich auch zu Fuß ans Ziel kommen. Aktuell machen das
manche zwangsweise um von Griechenland nach DE zu kommen. Aber keiner
wird bestreiten, daß man auf dieses "Vergnügen" zugunsten eines 2 1/2h
Flugs verziechten kann.
So geht's auch denen, die mit Software ihre Brötchen verdienen (mich
eingeschlossen). Die Blasen im Hirn haben sich Georg, Jörg und viele
andere geholt, dem Rest reicht das Ergebnis.
Nur ganz wenige verhandeln mit Atmel wegen Rückgabe unbenützter
Flash-Zellen gegen finanziellen Ausgleich. Für die wäre dann eine
Berufgruppe aus der Gesundheitsbranche zuständig: die Herren mit den
weißen Kitteln.
Horst S. schrieb:> Ich bin jetzt nicht unbedingt davon ausgegangen, dass ein (nicht> optimiertes) Assemblerprogramm in C portiert um 10% größer (und damit> auch langsamer) werden muss. Ist das so?
Nachdem ich schon in den ersten Beiträgen eigentlich eine eindeutige
Antwort auf meine Frage bekommen hatte, möchte ich mich abschließend bei
den Leuten, die sich die Mühe gemacht haben, mein Projekt(chen)
anzuschauen und mit konstruktiven Beiträgen zu verbessern, noch mal ganz
herzlich bedanken.
Ich finde, das ist keine Selbstverständlichkeit und verdient zumindest
die Anerkennung, den Antwortern bis zum Schluss zuzuhören (man muss
nicht jede Idee übernehmen, aber ausprobieren sollte man das schon mal).
Für mich scheint das Problem gelöst, wenn Euch nix Krasses mehr
auffällt, sehe ich mich als entlassen.
Zu den anderen 90% Beiträgen in diesem Threads:
Wenn ich noch mal versehentlich Auslöser solch eines Disputs werde,
probier' ich mal ganz blauäugig den "Beitrag melden"-Link und hoffe das
Beste. Möge ein Moderator mir beistehen, sein Holzbein überstülpen und
(Gregory Peck: "verfluchter Wal") da kräftig mit seiner Harpune
reinpieken.
Hmmm: wer den Film zu Ende geguckt hat, weiss, das hilft auch nicht
immer, aber es sieht zumindest so aus, als ob es Wirkung zeigen könnte.
In diesem Sinne
Gruß Horst
Horst S. schrieb:> Zu den anderen 90% Beiträgen in diesem Threads
Ach, nimm's locker, Horst: allein von Johanns Ausführungen über das,
was er (*) da so im Compiler treibt, kann man hinreichend viel auch
als gestandener Programmierer noch lernen. ;-)
(*) Johann ist derjenige, der in den letzten Jahren am AVR-Backend
des GCC massiv herumoptimiert hat. Davor war er zwar auch schon
brauchbar, aber eben manchmal recht suboptimal (vermutlich eher das,
was Moby sich unter einem Compiler vorstellen würde). Dank Johanns
Engagement hat er aber nochmal massiv zugelegt, und es dürfte
mittlerweile selbst einem gestandenen Assemblerprogrammierer oft
schwer fallen, vergleichbar guten Code zu erzeugen.
Jörg W. schrieb:> und es dürfte mittlerweile selbst einem gestandenen> Assemblerprogrammierer oft schwer fallen, vergleichbar guten Code zu> erzeugen.
Oh, wecke mal keine schlafenden Hunde ;-)
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
Frank M. schrieb:> Der interessanteste Benchmark dieser Aufgabe für mich:>> 1. Moby braucht dafür 1 Stunde und 5 Minuten
Johanns Frage: 28.08.2015 23:08
Mobys Antwort: 29.08.2015 23:37 (die falsche)
30.08.2015 02:02 (die richtige)
A. K. schrieb:> Johanns Frage: 28.08.2015 23:08> Mobys Antwort: 29.08.2015 23:37 (die falsche)> 30.08.2015 02:02 (die richtige)
Ich habe lediglich die Differenz der Zeiten aus beiden der oben
zitierten Beiträgen gezogen, weil ich annahm, dass sich Moby dieser
Aufgabe tatsächlich erst ab 30.08.2015 00:57 mit dem nötigen Ernst
annahm. Alles andere davor war einfach so dahingesaut und nicht
ernstzunehmen.
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.
Peter D. schrieb:> Welche Funktionalität denn?> Nirgends wird beschrieben, was der Code überhaupt machen soll!
Ja, genau das hab ich vor paar Tagen auch schon vergeblich
eingefordert...
Moby schrieb:> Es braucht diesbezüglich kein zeitvernichtendes Hinterherhecheln hinter> den neuesten Technologien und Programmiermethoden
Da musste man als C-Progammierer niemals irgendwie hinterherhecheln:
C ist viel älter als der AVR. Der AVR wurde sogar von Atmel zusammen mit
IAR für C-Compiler optimiert.
1
Atmel and IAR Systems have worked together since 1995, when we participated
2
in the design of the successful AVR 8-bit RISC microcontroller core, and
3
delivered a tailor-made C compiler.
(Quelle https://www.iar.com/iar-embedded-workbench/atmel/)
Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller
Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen
Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur
und seinen verbastelten Compiler herumgeärgert hatten.
Und wenn es schon einen optimierten Prozessor und dazu einen kostenlosen
sehr guten Compiler gibt, dann bin ich fertig. Da fange ich nicht mal
mehr für den Tiny9 ein Assemblerprojekt an.
BTW:
Ich kann mir übrigens vorstellen, warum der Thread inzwischen im
Offtopic gelandet ist, obwohl er im ersten Fünftel noch hübsche
technische Ansätze hatte...
Lothar M. schrieb:> Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller> Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen> Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur> und seinen verbastelten Compiler herumgeärgert hatten.
Der 8051 wurde ein einer Zeit entwickelt, in der man solche Aufgaben
nicht in C gelöst hat, sondern meist in Assembler. Und für Aufgaben, die
mit 256 Bytes RAM auskommen. Da ist er ziemlich gut.
Eine Akku-Architektur ist kein Problem für einen C Compiler.
Vorzugsweise mit 16-Bit Akku wie 68x11/12. Auf GCC sollte man dann aber
verzichten, der ist auf Register konzipiert.
Lothar M. schrieb:> Da fange ich nicht mal> mehr für den Tiny9 ein Assemblerprojekt an.
Da stimme ich zu. Ein simpler PWM-Controller auf einem ATtiny10: die
Hälfte vom Flash für eine PWM-Tabelle und der Rest hat immer noch für's
Programm gereicht. Ich bleibe beim Compiler, solange es keinen
zwingenden Grund für Assembler gibt.
Moby A. schrieb:> Hab mal meine bereits weiter oben zur Sprache gekommene ASM Lösung aus> einem anderen Hochsprachen-Thread(problem) angehängt. Zeigt mal, wie> sich die Funktionalität in höchstens gleicher C -Codegröße umsetzen> lässt. Das würde ja auf mich viel eher Eindruck machen ;-)
Deine beiden Codeschnipsel sind Mini-Programme und damit realitätsfern.
Bei realistischen Projekten (erzeugte Codegröße ab ca. 2KB) kann man mit
Assembler nicht mehr mithalten. Je größer das Programm, desto größer
auch der Speicherplatzgewinn mit C. So gut kann kein
Assembler-Programmierer sein, dass er bei mittelgroßen bis großen
Projekten so gut optimiert wie die Maschine. Ein Compiler kann hier
immer noch den Überblick behalten, während der Assembler-Programmierer
diesen so langsam aber sicher verliert.
So Moby, jetzt hab ich mir deinen asm Programm mal angesehen.
Da sind einige Dinge drin, die unsauber sind. zB hier:
1
DATARAM:
2
KEY0S: .DB 1 ;Key0 (0/$ff= un/betätigt Status)
3
KEY0C: .DB 1 ;Key0 (Betätigungsdauer, Counter)
4
KEY1S: .DB 1 ;Key1 (0/$ff= un/betätigt Status)
5
KEY1C: .DB 1 ;Key1 (Betätigungsdauer, Counter)
6
KEY2S: .DB 1 ;Key2 (0/$ff= un/betätigt Status)
7
KEY2C: .DB 1 ;Key2 (Betätigungsdauer, Counter)
Hier definierst Du sechs Variablen, welche hinternander im Speicher
liegen. Ok. Aber hier:
1
systemint:
2
..ldi ZL,low (KEY0S-2)
3
ldi ZH,high(KEY0S-2)
Hier setzt du den Z-Poiter auf zwei Speicherzellen vor das KEY0S. Das
funktioniert zwar, weil Du hier:
1
keyproc:
2
adiw ZH:ZL,2
beim Aufruf immer plus zwei rechnest und die Tasten in exakt der
Reihenfolge abfragst/aufrufst, in der Du die in DATARAM definiert hast.
Aber das ist bei weitem keine ordentliche Lösung. Wie soll ein fremder
Programmierer, der (nur) die Funktion keyproc bekommt/sieht/analysiert.
wissen, was das soll?
Sowas ist kein sauberes Programmieren. Sauberer wäre es, keyproc die
"Taste" im DATARAM mitzugeben.
Weiter:
1
systemint:
2
...
3
sec ;Entprellung Key1 (PB6)
4
sbis PINB,6
5
clc
6
rcall keyproc
Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc
aufgerufen wird. Weiter:
1
keyproc:
2
...
3
ldd XL,Z+0 ;8x alle 5ms testen
4
rol XL ;= 200% Bulletproof ;-)
5
std Z+0,XL
Das LDD/STD speicher/lädt den Wert KEYxS aus DATARAM. Das ROL schiebt
das Carryflag (von der Taste) von rechts rein. Ergebnis: (bleibt) Null,
wenn Taste nicht betätigt. Sonst: 0,1,3,7,15,31,63,127,255,255,255,255
bis wieder losgelassen. Weiter:
1
keyproc:
2
...
3
breq keyproc2
Wird aufgerufen, wenn obiger Zähler Null ist. Also wenn acht Samples
hinternander die Taste nicht gedrückt ist.
...
Lothar M. schrieb:> Ein maßgeschneiderter C-Compiler? Das ist doch die Erfüllung aller> Entwicklerträume, die sich bis dahin mit dem 8051, dem holprigen> Assembler (dessen bester Befehl der djnz war), seiner Akku-Architektur> und seinen verbastelten Compiler herumgeärgert hatten.
Der 8051 hatte noch viele andere geniale Befehle, CJNE, MOVC A,@A+DPTR,
JMP @A+DTPR hab ich sehr oft benötigt.
Und Bitlogik ging auch sehr einfach mit MOV C,bit, ORL C,(/)bit, MOV
bit,C, CPL bit, JBC usw.
Ich fands genial, was der Herr Keil da geleistet hat. Meine
Assemblerprogramme waren durchweg länger, als später in C geschrieben.
Und das Funktionen per default nicht reentrant waren, hat kaum gestört.
Die Idee mit dem SRAM-Overlay hätte man nie in Assembler umsetzen
können, das kann nur ein Compiler.
Matthias L. schrieb:> Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc> aufgerufen wird. Weiter:> keyproc:> ...> ldd XL,Z+0 ;8x alle 5ms testen> rol XL ;= 200% Bulletproof ;-)> std Z+0,XL
Du hättest statt der "..." die entsprechenden Befehle vollständig
hinschreiben sollen:
Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt, im
konkreten Fall mit 0. Somit schiebt ROL in das XL-Register nur Nullen
hinein, was den nett gemeinten Programmiertrick völlig versagen lässt.
Wir wissen zwar nicht, was Mobys Programm tun soll (er verrät es uns ja
nicht), eins kann aber sicher gesagt werden: Es entprellt keine Tasten.
Und was lernen wir daraus?
1. Das Carry-Flag ist eigentlich gedacht für das Zusammensetzen von
Multibyte- aus mehreren Einzelbytebefehlen (Addition, Shift usw.) und
für Vergleiche mit anschließenden bedingten Sprüngen. Dabei wird das
Flag in einem Befehl geändert und im direkt darauffolgenden Befehl
ausgewertet.
Es ist nicht gedacht für den Transport von booleschen Informationen
über weite Strecken innerhalb des Programms. Wenn man das trotzdem
tut, muss man sehr vorsichtig sein, damit man nicht versehentlich
einen Befehl dazwischen einfügt, der das Flag überschreibt.
=> Wenn man schon Assembler programmiert und dabei auzch noch tief in
die Trickkiste greift, sollte man gut ausgeschlafen sein und jede
Code-Änderung dreimal mit dem Auge durchgehen und zusätzlich intensiv
testen.
2. Ich vermute, Moby hat aus seinem Fundus eine ältere keyproc-Routine
übernommen, die zunächst nur für eine einzelne Taste vorgesehen war.
Er hat sie auf mehrere Tasten erweitert, musste dazu aber die
indirekte Adressierung für das Z-Register und damit verbunden den
ADIW-Befehl einführen, was schließlich zu dem Fehler führte.
=> Wiederverwendbarkeit von Code erfordert eine genaue und
vollständige Dokumentation nicht nur der Funktion, sondern auch der
Nebeneffekte. Das ist hier offensichtlich nicht geschehen.
Da Moby der Assembler-Gott ist, der immer alles richtig macht, hat er
auch keinen Bedarf gesehen, die Routine vor ihrer Veröffentlichung
wenigstens einmal zu testen ;-)
3. Hochsprachen sind weniger anfällig gegen solche Fehler, da dort
Information ausschließlich über Variablen transportiert wird.
Wenn eine Variable an einem Punkt geschrieben wird und etliche
Anweisungen später wieder gelesen wird, fällt es normalerweise auf,
wenn dazwischen eine weitere Zuweisung an die Variable erfolgt.
Ausnahme: Die Variable ist global und wird als Nebeneffekt eines
Unterprogrammaufrufs überschrieben. Dann ist der Fehler ähnlich
schwer zu erkennen wie in Mobys Fall. Das ist aber auch der Grund,
warum globale Variablen (vor allem Schreibzugriffe auf dieselben)
vermieden werden sollten.
Aber selbst diese Fehlerursache lässt sich aus der Welt schaffen,
indem man auf der Programmierprachenleiter noch eine Stufe höher
steigt (ich sehe schon Mobys entsetzten Gesichtsausdruck vor mir) und
eine Funktionalsprache verwendet. Damit gehören solche Fehler (und
viele andere auch) endgültig der Vergangenheit an.
Jetzt sind meine Feststellungen ja hier immer noch Thema.
Hatte Mod Yalu nicht angemahnt:
> Und bevor wir hier weiterdiskutieren und immer mehr vom Usprungsthema> abkommen:> Moby, fang doch bitte einen neuen Thread an. Dann beschwert auch keiner> darüber, dass du den Thread kaperst.
Hatte Mod Lothar M. nicht beklagt:
> Dass ihm Andere seinen Thread> entführen und verunstalten gehört nicht zum guten Umgangston.
Nun erklärte ich mich bereit, dem TO Horst S. wieder das Feld zu
überlassen.
Was vom TO folgt ist nun aber nur noch
> möchte ich mich abschließend ... bedanken.
Ja was jetzt? Was willst Du eigentlich? Deine Antworten hast Du also
bekommen. Darf nun darüber hinaus nicht mehr diskutiert werden? Mußtest
Du diesen Kübel Unrat weiter oben über mich ausgießen? Ich frage mich
schon sehr, welche Höflichkeit das nun meinerseits noch wert sein
soll...
Ich werde sobald möglich noch auf einige in der Zwischenzeit
aufgelaufenen Beiträge eingehen. Ein extra Thread dafür ist Blödsinn,
weil man sich nicht mehr sinnvoll auf vorhergehende Beiträge beziehen
kann.
Danke an alle, die sich konstruktiv mit meinen Sourcen
auseinandergesetzt haben. Ich hoffe daß ich auch noch was draus lernen
kann.
>Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt
Das hatte ich sogar noch übersehen.
>Es ist nicht gedacht für den Transport von booleschen Informationen>über weite Strecken innerhalb des Programms
Dafür würde das SREG das T-Flag bieten. Dieses kann frei verwendet
werden und wird nicht bei arithmetischen Ops geändert. Sprungbefehle
dafür gibt es aber genauso.
Peter D. schrieb:> Moby A. schrieb:>> Zeigt mal, wie>> sich die Funktionalität in höchstens gleicher C -Codegröße umsetzen>> lässt. Das würde ja auf mich viel eher Eindruck machen ;-)>> Welche Funktionalität denn?> Nirgends wird beschrieben, was der Code überhaupt machen soll!>> Die paar wenigen Zeilenkommentare kannst Du Dir an die Backe schmieren,> die sagen 0,nix über die Gesamtfunktion aus.
Peter, hast du immer noch nicht verstanden, dass Mobys Code quaDefinition 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.
Moby schrieb:> Asm allein ist nun> leider keine Garantie für guten Code, wie man beim TO-Programm schön> sehen kann ;-)
Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so
vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne
großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru,
aber einfach abfrühstücken lasse ich mich auch nicht von Dir.
Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung.
> Der 8051 wurde ein einer Zeit entwickelt, in der man solche Aufgaben
nicht in C gelöst hat, sondern meist in Assembler.
Wikipedia:
PLM compilers have been made for 8008, 8080, 8085, 8051, 8052, 8096.
80196, 8086, 80186, 286 and 386.
Nun ist PLM von der Syntax her kein C, aber sonst C ähnlicher als
Assembler. Und wenn man 8008 liest, offenbar ein Zeitgenosse von frühem
C anfang der 70er. Von Intel (und seinen Kunden) wurde mit PLM alles
gelöst was ging.
Ich erinnere mich an eine digitale Regelung um die 4 Farbwerke einer
großen Druckmaschine zu synchronisieren (damit die Farben richtig
übereinander kommen). Das hatte eine Schweizer Firma 1982 (da war ich
Werkstudent in der Druckerei) mit einem 8085-Board in PLM80 gemacht.
Auch das 8085-Entwicklungssystem hatte ein OS (ISIS II) in PLM80
geschrieben. Das Konkurrenzprodukt CP/M bestand in Teilen auch aus
PLM-Code. (grad gesehen: es gibt die CP/M Sourcen in Netz, dabei auch
die F66-Source des Intel PLM80 Compilers. Er soll mit Gnu-FORTRAN
übersetzbar sein)(das ist fast wie Oldtimerhefte durchblättern 8-))
Einziger Nachteil an dem Zeug damals: Intel lies es sich vergolden. Und
heute haben wir den avr-gcc. 0€, satte Gegenleistung.
Ich bekenne: alles Off-Topic, aber das hat in diesem Thread ja Tradition
;-)
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
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:
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!
>Das hatte eine Schweizer Firma
Ferag AG?
Gerade mal Google befragt:
Bobst, machen heute in Verpackungsmaschinen und nicht mehr in
Druckmaschinenausrüstung.
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.
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...
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
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)."
Jörg W. schrieb:> allein von Johanns Ausführungen über das, was er (*) da so im> Compiler treibt, kann man hinreichend viel auch als gestandener> Programmierer noch lernen. ;-)>> (*) Johann ist derjenige, der in den letzten Jahren am AVR-Backend> des GCC massiv herumoptimiert hat. Davor war er zwar auch schon> brauchbar, aber eben manchmal recht suboptimal (vermutlich eher> das, was Moby sich unter einem Compiler vorstellen würde).
Ja, ein Compiler arbeitet bestimmt nicht so, wie sich Lieschen Müller
das ausmalt. Aber in einem muss ich Moby recht geben: Der erzeugte
Code ist nicht optimal.
Das Verbesserungspotential würd ich mit 10% oder mehr ansetzen. Aber
andererseits ist auch die frage, die weit ein Assemblerprogrammierer vom
Optimum (das wir i.d.R nicht kennen) entfernt ist, insbesondere auch wie
weit er davon entfernt bleiben will weil er seinen Code nicht
kaputt-optimieren mag.
Bei Mobys Code könnte man z.B. einiges an Zeit sparen wenn — wie schon
erwähnt — auf die Schiebeschleife verzichtet würde und zudem die
Funktion inline in der ISR wäre. Dass der Code selbst ein paar Ticks
mehr braucht ist dabei garnicht das Problem, aber bei AVRs sind ISRs in
der Regel blockierend, und die Latenzzeiten aller anderen ISRs werden
höher.
> Dank Johanns Engagement hat er aber nochmal massiv zugelegt,
Leider geht teilweise viel Zeit drauf, manchen Atmel-Änderungen wie dem
Specs-Zeug hinterher zu wischeln. Allein das hat mich mehrere Tage
AVR-Zeit gekostet, was in Real Time dann locker Wochen bis Monate sind
:-(
A. K. schrieb:> Den Datasheets von z.B. ATmega32 und ATtiny26 zufolge betrifft das nur> den differentiellen Modus, und den hat nicht jeder AVR. Der ATmega8 hat> ihn nicht und da steht es folgerichtig auch nicht drin.
Ja, es stand / steht nicht im Datenblatt, und es war für ein Device ohne
differentiellen Modus. Wenn ich's richtig verstand wurde vom
2nd-LevelSupport nachgemessen, und ich musste einige Tage warten bis die
das Ergebnis hatten. Die genaue ADC-Config des ATmega8 hab ich
allerdings nicht mehr, eingestampft wie gesagt.
Na da hat sich ja einiges getan, seit ich in diesen Thread das letzte
mal reingeschaut habe.
Ja, genau so etwas hab ich schon erwartet. Das ist oft der Normalfall,
auch in den Programmierforen. Die ärgesten Assembler-Verfechter glänzen
da bei Assembler Fragen meistens mit Abwesenheit. Aber das das
rückzugsgefechtartige Gestammel von Moby so deutlich ausfallen würde,
das hab ich dann doch nicht erwartet. Besonders schön natürlich das
Bonmont mit der fehlerhaften Adressierung im BST in der ominösen ADC
Routine. Moby, was machst du eigentlich, wenn ich eine andere Verteilung
der Referenzspannungen haben will, oder mehr Kanäle, oder nicht 64
Samples sondern weniger? Oder gar, Gott bewahre, mehr? Dann platzt deine
ach so tolle handoptimierte Bitpfriemelei wie eine Seifenblase und die
Arbeit geht von vorne los. Das alles sind Dinge, die mir in C nur ein
Schulterzucken kosten. Einen Zahlenwert ändern und soll sich doch der
Compiler was überlegen, wie er das anständig umsetzt.
Und sorry. Ich weiss ja nicht, was du für Programme schreibst. Aber die
Welt hört beileibe nicht bei 8 Bit Arithmetik auf. Ein bisschen rechnen
ist ausserdem keineswegs so selten, wie du das hinstellst. Ganz im
Gegenteil: ein paar Werte in ein paar Register schreiben, das ist der
eigentlich geringfügigere Teil in einem Programm. Das kann man gut in
Assembler machen. Allerdings: Das kriegt der Compiler genau so gut hin.
Und wie man gesehen hat, ist der Schwellwert an Komplexität, den du noch
überblicken kannst, so gross dann auch wieder nicht. Ich gebe gerne zu,
dass ich den 32 Bit Vergleich nicht so elegant hingekriegt hätte. Muss
ich auch nicht. Bei mir macht das der Compiler. Mich interessiert es
schlicht und ergreifend nicht besonders wie er das macht. Ich kümmere
mich lieber darum, welche Bedeutung dieser Vergleich im Kontext meines
Programmes hat, warum er da stehen muss, ob es ein kleiner oder doch ein
größer sein muss. Die Details der Umsetzung - die macht der Compiler für
mich. Und wenn er da ein paar Takte zuviel reinhaut stört das in mehr
als 95% aller Fälle nicht die Bohne. Dafür, und diesen Seitenhieb kann
ich mir nicht verkneifen, macht der das zum Ausgleich korrekt und
braucht nicht anderthalb Stunden dafür. Ich hab mit meiner Zeit wirklich
was besseres zu tun, als mich mit Routine-Angelegenheiten rumzuschlagen.
So interessant sind die auch wieder nicht. Aber ein ausgefuchster
Algorithmus, der kann mich dann auch schon ein paar Stunden oder Tage
beschäftigen. Nur - so weit kommst du gar nicht, weil du ihn gar nicht
wegen des Umfangs im absehbarer Zeit implementieren kannst. Oder - was
noch viel wichtiger ist - du kannst gar nicht Varianten davon genauer
studieren, weil du viel zu sehr damit beschäftigt bist, warum das Carry
Flag schon wieder mal an einer Stelle nicht den Wert hat, den es haben
sollte (jetzt nur mal so zum Beispiel). Kurz und gut: du musst dich auf
einer Ebene mit Problemen rumschlagen, die nichts mit der eigentlichen
Aufgabenstellung zu tun haben. Die eigentliche Aufgabenstellung mag
lauten, anhand einer Uhrzeit ein Temperaturprofil mit einem PID Regler
abzufahren. Ob du dabei den X-Pointer oder doch den Z-Pointer zur
Indizierung in die Temperaturtabelle benutzt ist dabei völlig
nebensächlich. Du musst auch mal in etwas größeren Dimensionen denken
als nur "Wenn Taster dann Licht an".
Karl H. schrieb:> rückzugsgefechtartige Gestammel von Moby
Na na nicht so vorschnell. Es soll doch da tatsächlich noch andere Dinge
im Leben geben als hier permanent präsent zu sein. Oder etwa nicht?
Karl H. schrieb:> Besonders schön natürlich das> Bonmont mit der fehlerhaften Adressierung im BST in der ominösen ADC> Routine.
Wir werden doch nun einen Flüchtigkeitsfehler nicht so hoch aufhängen!
Daß es hier im Forum unentschuldbar ist, einen Quelltext mit einem
solchen zu veröffentlichen, ok, daß muß und werde ich zukünftig
berücksichtigen.
Karl H. schrieb:> Moby, was machst du eigentlich, wenn ich eine andere Verteilung> der Referenzspannungen haben will, oder mehr Kanäle, oder nicht 64> Samples sondern weniger? Oder gar, Gott bewahre, mehr? Dann platzt deine> ach so tolle handoptimierte Bitpfriemelei wie eine Seifenblase und die> Arbeit geht von vorne los.
Da platzt gar nichts. Oder ist eine entsprechende Umformulierung nun
gleich High-Tech? Nein, es ist Kiki. Wenngleich
flüchtigkeitsfehleranfällig und damit hier nicht sofort
veröffentlichungswürdig. Aber was man schließlich hat das hat man...
Moby A. schrieb:> Da platzt gar nichts. Oder ist eine entsprechende Umformulierung nun> gleich High-Tech? Nein, es ist Kiki.
Na Moby... wieder ganz der Alte? ;-(
Karl H. schrieb:> rückzugsgefechtartige Gestammel
Da mokieren sich die einen Mods über vaterlandsgefährdende
Threadübernahme, die anderen über Rückzug. Da werden beleidigende
Kommentare von Forumsteilnehmern kritisiert- und Mods schlagen in die
gleiche Kerbe. Diese Forummodlogik für in sich konsistent zu halten
würde ich Gestammel nennen...
Aber so sind sie, die Menschen. Einer wie der andere.
Karl H. schrieb:> Aber die> Welt hört beileibe nicht bei 8 Bit Arithmetik auf.
Sicher nicht. Das für Asm wie für 8-Bit AVR nachteilige Thema hatten wir
schon. Eine große Klasse von Steuerungs-Anwendungen kommt da ohne
aufwendiges 32 Bit aus. Sensoreinlesen, verarbeiten und verschiedene
Ausgaben veranlassen (z.B. an seriell angebundene Aktoren/Webinterfaces)
haben größere Berechnungen selten am Bein.
> Allerdings: Das kriegt der Compiler genau so gut hin.
Berechnungen? Sicher doch. Das ist dann aber nur ein Aspekt von vielen
und ich erspare mir an dieser Stelle weitere Wiederholungen zu den
Vorteilen von Asm.
> Mich interessiert es> schlicht und ergreifend nicht besonders wie er das macht.
Was man in Asm hat das hat man. Über die Jahre begeisterten
Asm-Programmierens kann das eine ganze Menge werden.
> braucht nicht anderthalb Stunden dafür.
Ja es ist wirklich interessant was sich aus den Zeitdaten
veröffentlichter Beiträge so alles ableiten lässt ;-)
> ausgefuchster> Algorithmus, der kann mich dann auch schon ein paar Stunden oder Tage> beschäftigen. Nur - so weit kommst du gar nicht, weil du ihn gar nicht> wegen
fehlender Notwendigkeit eines solchen ;-)
> weil du viel zu sehr damit beschäftigt bist, warum das Carry> Flag schon wieder mal an einer Stelle nicht den Wert hat, den es haben> sollte
C-Programmierer haben da andere, gewichtigere Probleme: Den ganzen
Zirkus von C-Konstruktionen mitsamt komplexer Ausdrücke und
Compileroptionen unter Kontrolle zu behalten... Was ist denn da ein
Carry Flag ;-)
> in etwas größeren Dimensionen denken> als nur "Wenn Taster dann Licht an".
Das Zusammenwirken vieler Sensoren und Aktoren verknüpft über drahtlose
Netze stellt durchaus ein paar Anforderungen. Nur eben weniger an
Berechnungen.
Johann L. schrieb:> Das Verbesserungspotential würd ich mit 10% oder mehr ansetzen.
Meine Rede. Insbesondere bei kurzen Programmen sind die Chancen dieses
Potential zur Geltung zu bekommen hoch.
> Aber> andererseits ist auch die frage, die weit ein Assemblerprogrammierer vom> Optimum (das wir i.d.R nicht kennen) entfernt ist, insbesondere auch wie> weit er davon entfernt bleiben will weil er seinen Code nicht> kaputt-optimieren mag.
Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch
(fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen
Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen.
Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich
interessiert allein die effiziente,simple Lösung und kein 32bittiges
Herumprotzen mit Ressourcen und Vernichtung derer mit Hochsprachen.
Falk B. schrieb:> Ich verweise auf die Universalantworten, auch zu diesem Thema
Ja Falk, verweise ruhig was das Zeug hält ;-)
Mein Anspruch ist nun aber die praktikable Lösung-und wenn ich mich in
der Bude so umschaue- sorry Falk, dann kann ich nicht anders als mich
darin total bestätigt zu fühlen ;-)
Der Spaß an der Sache ist allerdings auch nicht zu unterschätzen!
Falk B. schrieb:> Ich verweise auf die Universalantworten,
Hmm..., jaa..., neee...
Da muss es noch was anderes geben.
Moby A. schrieb:> Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich> interessiert allein die effiziente,simple Lösung und kein 32bittiges> Herumprotzen mit Ressourcen und Vernichtung derer mit Hochsprachen.
Das kommt mir wie 'ne Politikerrede vor. Beeindruckende Wortwahl und
nichts dahinter.
Moby A. schrieb:> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch> (fast) erreichbar.
Klar: nur dort. Schon bei mittleren nämlich nicht mehr. Schließlich
ist auch dein Leben endlich …
Was du generell unterschätzt: die, gegen die du hier ankämpfst, sind
fast durchweg Leute, die eine solche Sturm-und-Drang-Phase, die du
da gerade hast, schon vor ein oder zwei (oder drei) Jahrzehnten
durchlaufen haben. Es sind alles Leute, die teilweise wohl viel
besser als du wissen, wie ein Assembler funktioniert (und der vom
AVR Studio ist in dieser Hinsicht ohnehin nur eine Krücke auf eher
unterem Niveau), die teilweise Assembler-Pamphlets von mehreren
Dutzend Seiten fabriziert und zumindest zur geplanten Funktion
bekommen haben. Im Gegensatz zu dir wissen sie jedoch aus gerade
dieser Erfahrung, dass es um die dabei verschwendete Lebenszeit
schade war, wenn stattdessen eine Maschine einen durchaus vergleichbar
guten Job mittlerweile innerhalb von ein paar Sekunden hinlegt.
Moby A. schrieb:> Da werden beleidigende Kommentare von Forumsteilnehmern
Nur mal so, weil du das immer wieder anbringst: geh' mal zum
Staatsanwalt deines geringsten Misstrauens und befrage ihn, was er
als „Beleidigung“ ansieht. Du wirst dich ziemlich wundern, wie hoch
die Schwelle dafür liegt. Ein paar flapsige Kommentare eines
Forenteilnehmers, dessen Thread du letztlich mit deiner dir üblichen
Penetranz gekapert hast (ohne ihm damit auch nur im geringsten zu
helfen), fallen da ganz gewiss nicht drunter.
Jörg W. schrieb:> Moby A. schrieb:> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch> (fast) erreichbar.>> Klar: nur dort. Schon bei mittleren nämlich nicht mehr. Schließlich> ist auch dein Leben endlich …
Bei mittleren muß man systematischer rangehen.
Funktionalität als unabhängiges Modul formulieren das sich von weiteren
Nebenabhängigkeiten befreit zum Beispiel flexibel in einem
Timerinterrupt aufrufen lässt. So wie die beiden (ADU+Tastenentprell)
Beispiele.
> Was du generell unterschätzt: die, gegen die du hier ankämpfst, sind> fast durchweg Leute, die eine solche Sturm-und-Drang-Phase, die du da> gerade hast, schon vor ein oder zwei (oder drei) Jahrzehnten durchlaufen> haben. Es sind alles Leute, die teilweise wohl viel besser als du> wissen, wie ein Assembler funktioniert (und der vom AVR Studio ist in> dieser Hinsicht ohnehin nur eine Krücke auf eher unterem Niveau), die> teilweise Assembler-Pamphlets von mehreren Dutzend Seiten fabriziert und> zumindest zur geplanten Funktion bekommen haben. Im Gegensatz zu dir> wissen sie jedoch aus gerade dieser Erfahrung, dass es um die dabei> verschwendete Lebenszeit schade war, wenn stattdessen eine Maschine> einen durchaus vergleichbar guten Job mittlerweile innerhalb von ein> paar Sekunden hinlegt.
Ich möchte gegen niemand ankämpfen.
Schon gar nicht jemand, der aus vielerlei Gründen (beruflich) Lösungen
in Hochsprache undoder 32-bittig umzusetzen hat. Wenn die gleichen Leute
dies aber in einer Form verallgemeinern, die Asm und AVR generell in
Frage stellen wiederspreche ich vehement.
> Nur mal so, weil du das immer wieder anbringst: geh' mal zum> Staatsanwalt deines geringsten Misstrauens und befrage ihn, was er als> „Beleidigung“ ansieht.
Da darf ich Dich beruhigen- sooo wichtig ist mir dann das Forum als
solches nicht ;-)
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.)
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.
Moby A. schrieb:> Und das wird noch mehr wenn x>16777215.
Du meintest eventuell 'wenn x mit einer Konstanten größer 16777215'
verglichen wird? Da schreibt man die Konstante hin und zack!, hat der
Compiler den entsprechenden Code gezaubert.
Jörg W. schrieb:> Du siehst das immer noch durch die falsche Brille: wir müssen das nicht> so machen, sondern machen das alle völlig freiwillig so.
Dann bitte auch gern freiwillig.
Warum auch nicht? Ich bin doch nicht so verrückt anzunehmen, jeder
C-Programmierer sei auf dem Holzweg. Entscheidend ist was hinten
rauskommt.
Da sehe ich den Asm-Programmierer bei typischen 8-Bit Projekten auf
8-Bit Controllern aber im Vorteil. Erreichbare Performance/Codesize sind
auch nur zwei technische Aspekte. Mir fast noch wichtiger sind
übersichtliche Programmstruktur (bei sinnvoller Funktionskommentierung)
wie überhaupt der Bruchteil notwendiger sprachlicher Mittel, um ans Ziel
zu kommen. Direkt. Und daß der unmittelbare Kontakt zum Datenblatt nun
wirklich nicht schadet sieht man weiter oben...
Wir sollten anfangen, die Argumente zu nummerieren. Spart Tipparbeit,
weil man dann in der hiesigen schon heftig entrollten
Argumentationsschleife nur noch die Nummern hinschreiben muss.
A. K. schrieb:> Wie wärs Moby, könntest du deine Variante noch auf 32 Bits mit> Vorzeichen ausdehnen?
Nö. Brauch ich nicht. Wozu? Um hier irgendwas zu beweisen? Ist das
fertig kommst Du mit dem nächsten um die Ecke ;-)
Versuch Du doch umgekehrt mal gegebene Asm-Texte mit C einzudampfen.
Weitere Gelegenheiten werde ich noch liefern.
Moby A. schrieb:> Bei den Takten kommen wir aber auch auf 7...8.
Und da gibts noch einen Nachteil.
Die 7...8 Takte sind bei obiger Compiler-Lösung die Regel, bei meiner
schon fast die Ausnahme ;-)
Horst S. schrieb:> Moby schrieb:> Asm allein ist nun> leider keine Garantie für guten Code, wie man beim TO-Programm schön> sehen kann ;-)>> Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so> vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne> großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru,> aber einfach abfrühstücken lasse ich mich auch nicht von Dir.>> Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung.
Die Entschuldigung kannst Du Dir sparen.
Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das
jedenfalls nicht für Deinen Asm-Code.
Die lange diesbezügliche Rumbastelei am C-Code im übrigen auch nicht für
C.
Moby A. schrieb:> Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das> jedenfalls nicht für Deinen Asm-Code.
Allerdings waren die alternativen (und besseren) C-Varianten, die
Horst geholfen haben, schon nach wenigen Forums-CPU-Takten verfügbar.
Eine alternative Assembler-Variante hast du ihm jedenfalls bis heute
noch nicht angeboten.
Damit bleiben all deine Argumente reine Theoretisiererei, die vielleicht
deinem Ego hilft, aber sonst niemandem.
A. K. schrieb:> Wir sollten anfangen, die Argumente zu nummerieren.
So, wie die beiden Typen mit den Witzen. Gute Idee. :-)
Johann L. schrieb:> Peter D. schrieb:> Welche Funktionalität denn?> Nirgends wird beschrieben, was der Code überhaupt machen soll!> Die paar wenigen Zeilenkommentare kannst Du Dir an die Backe schmieren,> die sagen 0,nix über die Gesamtfunktion aus.>> Peter, hast du immer noch nicht verstanden, dass Mobys Code qua> Definition selbsterklärend ist?>> Nirgends wird beschrieben, was der Code überhaupt machen soll!>> Ich bezieht mich hier mal auf den Code für den LM335:
Asm-Code ist selbsterklärend. Es braucht nämlich nur die
Instruktionsbeschreibung und das Datenblatt sowie ein paar
funktionserklärende Kommentare.
Da es aber zu meiner Überraschung offensichtlich Fragen zum Einsatz und
dem Wie&Warum gibt werde ich das in dem entsprechenden Projekte-Beitrag
nochmal thematisieren.
Jörg W. schrieb:> deinem Ego hilft
Das spielt die letzte Geige, sonst wär durchaus schon eine Menge
meiner veröffentlichungsfähigen Entwicklungen in den Projekten. Wenn man
das aber trotzdem verstärkt tun sollte dann weil ich natürlich gemerkt
habe, daß es diesbezüglich hier einen gewissen Nachhol- bzw.
Wissensbedarf gibt und die besten Argumente immer noch überzeugender
Code liefert.
900ss D. schrieb:> Danke Moby, immerhin hast du deinen Code gepostet. Fazit: Auch> handgeschriebener ASM-Code ist nicht immer besser als der vom Compiler.
Wiegesagt, das C-Ergebnis sollte dann aber erstmal wirklich gleichwertig
sein was es so nicht ist.
> Warum du Moby, so verbissen an ASM festhälst, wird mir auch ein Rätel> bleiben, die von Dir genannten Vorteile sind alle objektiv widerlegt
Das sehe ich anders aber es mag sein, daß es noch ein paar
überzeugenderer Beispiele bedarf ;-)
> Neugier: Moby, ist programmieren eher aus Hobby betrieben oder verdienst> du dein Geld damit?
Mobby Hobby.
> 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!
Carl D. schrieb:> Auf alle Fälle bringt es beim> Vorteile, wenn man nicht ständig in Vokabel- und> Grammatikheft blättern muß.
Ja, die Grammatik gilt es im Gegensatz zu Asm bei C ja noch zusätzlich
zu beherrschen.
> Und damit> verbietet sich die Missionstätigkeit spätesten dann, wenn alle Anderen> sagen: "is gut jetzt".
Die würde sich für mich nur dann verbieten, wenn meine Erfahrungen mit
Asm denn schlechte wären.
Sind sie aber nicht! Das ist auch kein Wunder, weil Asm alle
Voraussetzungen zum effizienten Programmieren mit allen erdenklichen
Möglichkeiten, zu minimalem Aufwand bietet.
> auf einer in C und C++ geschriebenen VM> ausgeführten Sprache geschrieben hat, deren Vor- und Nachteile er seit> 25 Jahren kennt und sinnvoll einsetzt. Der kann sogar die Opcodes der VM> zum Glück gibt es für diese keinen Assembler, denn> dann bleiben ihm zumindest in dem Umfeld fischige Diskussionen erspart.
Warum werde ich bloß nicht müde zu betonen, für welche Zielplattform
und für welche Anwendungen ich Asm vorn sehe? Warum fühlt sich jeder
Profi bemüßigt, das sogleich auf sein Gebiet- bis hin zur PC
Programmierung zu beziehen?
Wannkappierst du eigentlich, daß dein Ges.... keiner mehr hören kann.
Soll ich dir ständig runterbeten, womit ich schon gute Erfahrungen
gemacht hab? Spätestens nach der Erfahrung, daß andere es nicht mehr
hören wollen, würde ich es für mich behalten und mich ganz allein an der
glückseeligmachen Erkenntnis laben. Und schon garnicht würde ich einer
solchen Gruppe von Ignoranten auch noch demonstrieren, wie rudimentär
ich mein Spezialgebiet tatsächlich nur beherrsche. Aber vielleicht
wollte ich deshalb auch nie Klassenkasper werden. Oder bekommst du
Provision dafür, Threads ins OffTopic zu treiben?
Carl D. schrieb:> der bis gerade für Brötchen in einer von wenigen gekannten,> aber von vielen belächelten, auf einer in C und C++ geschriebenen VM> ausgeführten Sprache geschrieben hat
Siehst Du. Viele belächeln diese. Nichtmal auf dem Level ein
eindeutiges Urteil. Was sagt uns das? Zuvieles jenseits harter Fakten
wird subjektiv erlebt und kann individuell durchaus verschieden bewertet
werden. So erklärt sich dann wohl auch manche Vorliebe in der Diskussion
C vs. Asm.
Moby A. schrieb:> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch> (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen> Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen.
Wenn jemand 18 Jahre lang in Assembler programmiert und damit seine
ganze Haussteuerung umgesetzt hat, wird er doch wohl ein paar
fehlerfreie Zeilen Quelltext vorweisen können?!
> Eine künstliche Distanz einzuhalten ist mir dabei fremd, denn mich> interessiert allein die effiziente,simple Lösung
Die interessiert uns auch. Aber es sind ja Sie, welcher behauptet, die
"effiziente,simple Lösung" zu haben. Belege dafür bleiben Sie schuldig,
unterstellen den Anwesenden aber
> 32bittiges Herumprotzen mit Ressourcen und Vernichtung derer mit> Hochsprachen.
Das interessiert vermutlich die wenigsten hier -- weder die 32 Bit, noch
das Herumprotzen, noch die Vernichtung von Ressourcen. Ich habe auch
noch nie jemanden mit so etwas "herumprotzen" sehen. Sie etwa?
Johann Lay, Jörg Wunsch und Peter Danegger, die sich an diesem Thread ja
mehrmals beteiligt haben, "protzen" jedenfalls nicht mit 32-Bit oder der
"Vernichtung von Ressourcen". Diese Leute könnten mit ihrem fehlerlosen
Code "protzen", und trotzdem tut es keiner. Deren Code hat übrigens auch
keine "Flüchtigkeitsfehler".
Carl D. schrieb:> Wannkappierst du eigentlich, daß dein Ges.... keiner mehr hören> kann.
Du musst hier nichts lesen oder gar schreiben.
Immerhin ist es Dir ja wert auf mich zu reagieren.
Sogar so spät/so früh ;-)
Was meinst Du was ich alles nicht mehr hören mag?
> Provision dafür, Threads ins OffTopic zu treiben?
Tatsächlich sind wir hier nach wie vor bei C vs. Assembler ->
Performance und nicht etwa schon beim Kuchenbacken...
Moby A. schrieb:> Asm-Code ist selbsterklärend.
Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei
einem "selbsterklärenden Code" passieren?
Sheeva P. schrieb:> Moby A. schrieb:> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch> (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen> Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen.>> Wenn jemand 18 Jahre lang in Assembler programmiert und damit seine> ganze Haussteuerung umgesetzt hat,
... dann wird ja wohl das allermeiste ohne Fehler funktionieren ;-)
> Aber es sind ja Sie, welcher behauptet, die> "effiziente,simple Lösung" zu haben.
Ich habe nicht die effiziente simple Lösung, sondern sage daß Asm alle
nötigen Mittel dafür bietet.
> Ich habe auch> noch nie jemanden mit so etwas "herumprotzen" sehen. Sie etwa?
In vielen Jahren hier zur Genüge ;-)
> Deren Code hat übrigens auch> keine "Flüchtigkeitsfehler".
Das bestreite ich jetzt einfach mal so.
Wenn sich später in den Projekten auch kaum noch davon was findet. Ich
bin weit davon entfernt, wegen Flüchtigkeitsfehlern die Ohren
hängenzulassen. Aber in die Projektveröffentlichungen (meine erste und
einzige mit Quellcode wohlgemerkt) gehören sie nicht hin. Hatte ich das
nicht weiter oben schon gesagt?
Sheeva P. schrieb:> Moby A. schrieb:> Asm-Code ist selbsterklärend.>> Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei> einem "selbsterklärenden Code" passieren?
Hatte ich eigentlich auch schon erklärt: Der im Einsatz befindliche Code
funktioniert, der für die Projekte leicht veränderte Code (zunächst)
nicht.
Wirst Du mir daraus jetzt den großen Strick drehen?
Bitte bitte nicht, ich flehe um Gnade ;-)
Moby A. schrieb:> Asm-Code ist selbsterklärend.
Auf den Niveau von
> die Instruktionsbeschreibung und das Datenblatt
ist C das auch, das ist aber nicht der Sinn einer ordentlichen
Dokumentation.
Moby A. schrieb:> Sheeva P. schrieb:>> Moby A. schrieb:>> Asm-Code ist selbsterklärend.>>>> Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei>> einem "selbsterklärenden Code" passieren?>> Hatte ich eigentlich auch schon erklärt: Der im Einsatz befindliche Code> funktioniert, der für die Projekte leicht veränderte Code (zunächst)> nicht.>> Wirst Du mir daraus jetzt den großen Strick drehen?> Bitte bitte nicht, ich flehe um Gnade ;-)
Wie kann das sein?
Wow, drei Seiten Diskussionstext in ein paar Tagen. Davon gefühlte 99%
Ping-Pong mit einem Troll. Bei jedem anderen Thema wären die Herren
Moderatoren nicht so zimperlich, aber hier scheints ihnen Spaß zu
machen...
Ich habe gerade zwanzig Benachrichtigungsemails zu diesem Thread
gelöscht. Die Diskussion geht immer noch um dasselbe Nicht-Thema.
Irgendjemand muß sehr, sehr einsam sein.
Moby A. schrieb:> 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.
@ Walter Tarpan (nicolas)
>gelöscht. Die Diskussion geht immer noch um dasselbe Nicht-Thema.>Irgendjemand muß sehr, sehr einsam sein.
Oder ein ZEN-Meister?
https://de.wikipedia.org/wiki/Zen#Lehre
Sheeva P. schrieb:> Moby A. schrieb:>> Asm-Code ist selbsterklärend.>> Die "Flüchtigkeitsfehler" sind Dir nicht aufgefallen. Wie kann das bei> einem "selbsterklärenden Code" passieren?
Der Code erklärt sich halt nur sich selbst, aber nicht anderen.
Zumindest wenn es mehr als ein paar Zeilen sind.
>Der Code erklärt sich halt nur sich selbst, aber nicht anderen.>Zumindest wenn es mehr als ein paar Zeilen sind.
WUrde ja bereits gesehen. Der von mir gepostete Asm COde wurde von Moby
bisher nicht erklärt. Obwohl es doch selbsterklärend ist.
@Matthias Lipinsky (lippy)
>>Der Code erklärt sich halt nur sich selbst, aber nicht anderen.>>Zumindest wenn es mehr als ein paar Zeilen sind.>WUrde ja bereits gesehen. Der von mir gepostete Asm COde wurde von Moby>bisher nicht erklärt. Obwohl es doch selbsterklärend ist.
Das erklärt doch alles!
Falk B. schrieb:> Das erklärt doch alles!
Jetzt bist du uns aber eine Erklärung schuldig! :)
Icke ®. schrieb:> Davon gefühlte 99% Ping-Pong mit einem Troll.
Moby ist kein Troll. Der Unterschied ist, dass ein Troll vorsätzlich
eine Dikussion stört. Moby stört sie auch, es ist auch Vorsatz dabei,
aber ich würde ihm mal nicht unterstellen, dass er sie tatsächlich
stören will. Es ist halt nur seine (sehr, sehr penetrant dargelegte)
Meinung, dass doch seine Philosophie für alle das beste wäre …
Da Horst aber bereits am Anfang des Threads gut und (so ich ihn
verstanden habe) ausreichend geholfen worden ist, denke ich, dass es
nicht übermäßig stört, hier weiterzudiskutieren. Wenn du dir den ein
oder anderen Beitrag mal ansiehst (also eher nicht Mobys, aber
beispielsweise Johanns), dann kann man durchaus noch bisschen dabei
lernen. OK, von Mobys Beiträgen kann man auch lernen, aber wohl nicht
in seinem Sinne. :-))
Moby A. schrieb:> Warum werde ich bloß nicht müde zu betonen, für welche Zielplattform> und für welche Anwendungen ich Asm vorn sehe? Warum fühlt sich jeder> Profi bemüßigt, das sogleich auf sein Gebiet- bis hin zur PC> Programmierung zu beziehen?
Weil du dein Assembler Anpreisung auch nicht auf die von dir vorne
gesehenen Anwendungen beschränkst.
Du kommst mir vor, wie der in Österreich berühmt berüchtigte
Flachlandtiroler, der meint nur weil er zu Hause gerade noch so seine
120 Meter hohe Schutthalde raufschnaufen kann, dass er geradezu
prädestiniert dazu wäre, andere davon zu überzeugen, dass man die Eiger
Nordwand auch mit Sandalen und etwas Bindfaden bezwingen kann.
Moby A. schrieb:> Asm-Code ist selbsterklärend. Es braucht nämlich nur die> Instruktionsbeschreibung und das Datenblatt sowie ein paar> funktionserklärende Kommentare.
Brainfuck, Befunge, Malbolge, FRACTRAN und wie sie alle heißen
(https://de.wikipedia.org/wiki/Esoterische_Programmiersprache) sind
deiner Definition nach ebenfalls selbsterklärend, denn für jede davon
gibt es eine klare Sprachspezifikation, die zudem sogar sehr viel kürzer
ausfällt als das AVR Instruction Set Manual.
Die allerkürzeste Instruktionsbeschreibung haben diese Prozessoren:
https://en.wikipedia.org/wiki/One_instruction_set_computer
Deren Assemblersprache müsste für dich somit das Optimum aller
Programmiersprachen darstellen, was das Selbsterklärendsein betrifft.
Was du bei der Bewertung der Sprachen völlig auser Acht lässt, ist ihre
Ausdrucksstärke, d.h. die maximale Komplexität der Problems, das mit
einer gegebenen Menge an Code gelöst werden können. Die ist bei den eben
erwähnten Sprachen nahezu null, beim AVR-Assembler sehr niedrig, bei C
aber schon recht hoch, wie das obige Beispiel des Vergleichs mit einer
Konstanten deutlich zeigt:
Der aus 9 Zeichen bestehende Term x<1000000 in C ist nicht nur viel
kürzer, sondern darüberhinaus auch noch besser lesbar und leichter
änderbar als die entsprechende CPI/SBCI-Kette in Assembler. Und wie man
gesehen hat, hat selbst ein überzeugter Assembler-Only-Programmierer
immense Schwierigkeiten, dieses noch recht einfache Beispiel erst einmal
fehlerfrei runterzuprogrammieren und dann auch noch zu optimieren.
Eine sehr schöne Routine, die so nur in C praktikabel ist, ist z.B. der
Scheduler:
Beitrag "Wartezeiten effektiv (Scheduler)"
Die original Idee ist nicht von mir, ich habe sie nur etwas auf den 8051
und den AVR optimiert. Durch die Vorsortierung ist das sehr effizient.
Sie läuft unverändert auf jeder anderen CPU und man kann bequem
festlegen, ob die Zeitbasis 8, 16, .. 64bittig ist.
In Assembler wäre das ein Albtraum und weder anpaßbar noch lesbar oder
gar portabel.
Yalu X. schrieb:> 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.
@ Karl Heinz (kbuchegg) (Moderator)
>Flachlandtiroler, der meint nur weil er zu Hause gerade noch so seine>120 Meter hohe Schutthalde raufschnaufen kann, dass er geradezu>prädestiniert dazu wäre, andere davon zu überzeigen, dass man die Eiger>Nordwand auch mit Sandalen bezwingen kann.
Ein Sandal! ähh, Skandal!
Jörg W. schrieb:> Moby ist kein Troll.
Ich kenne Moby und seine Diskussionskultur schon von anderen Threads.
Deswegen halte ich mich hier auch raus.
> OK, von Mobys Beiträgen kann man auch lernen
Ich habe daraus gelernt, daß jeglicher Versuch, Menschen mit derartig
zementierten Standpunkten (nannte man früher "Betonköpfe") von ihrem
Holzweg abzubringen, selbst unter Zuhilfenahme einleuchtendster
Argumente kläglich scheitert.
Noch ein klein wenig Topic. Ich programmiere auch gern in ASM, aber ich
kenne die Grenzen. Ab einer gewissen Komplexität macht das einfach
keinen Sinn mehr.
Es ist auch schön, per Pedes durch den Wald zu streifen, den Geräuschen
zu lauschen und mit den Füßen direkten Bodenkontakt zu spüren. Und es
macht Sinn, die 100m bis zum Bäcker um die Ecke zu laufen. Aber für den
Großeinkauf oder die Urlaubsfahrt steig ich dann doch lieber ins Auto.
Karl H. schrieb:> und das ist genau die Art Kommentierung, die komplett am Sinn einer> Kommentierung vorbei geht.
In diesem Fall würde ich da eine Ausnahme machen und auch eine
Kommentierung der Bedeutung der einzelnen Statements nahelegen:
Beitrag "Ein Vorschlag zur Intervall-Arithmetik"
Moby A. schrieb:> Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das> jedenfalls nicht für Deinen Asm-Code.
Wenn das Dein einziges Argument ist, gehe ich nicht davon aus, dass Du
Dir die Mühe gemacht hast, das Projekt überhaupt zu öffnen.
Die reinen Zahlen für die intellektuelle Höchstleistung des numerischen
Vergleiches im vierstelligen Bereich (ab der 3. Klasse praktiziert)
waren ja im Thread deutlich ablesbar.
Frank M. schrieb:> Moby A. schrieb:> Das Optimum ist bei kurzen AVR Programmen eher zu erkennen und auch> (fast) erreichbar. Ich hoffe, ich kann das in ein paar zukünftigen> Projektbeispielen (auch wie viele andere Autoren) unter Beweis stellen.>> Da bin ich mal gespannt. Ich wette, jedes Deiner zukünftiger> "Projektbeispiele"(*) lässt sich in C performanter und kürzer umsetzen -> sowohl was Programmier- als auch Prozessoraufwand betrifft.
Dann bin ich schon sehr gespannt...
Wer die realisierte Funktionalität dann kürzer umsetzt gewinnt den
Hauptpreis: Moby hält bzgl. Überlegenheit von Asm die Klappe ;-)
> 2:0.... Damit bist Du ziemlich im Rückstand, Moby.
Geduld, Geduld. Das Spiel läuft noch nicht lange.
> Also wenn ich Deine Programmiergeschwindigkeit in ASM hochrechne (einen> simplen Vergleich zu programmieren dauert bei Dir über eine Stunde)
... schließt Du aus den Zeiten meiner Beiträge?
Du bist ein Fuchs ;-)
Leider mach ich das nicht hauptberuflich und soviel Zeit steht in der
Freizeit nun auch nicht gerade zur Verfügung ;-(
> Du bleibst also weiter bei Deiner Blender-Strategie
Wen meinst Du kann ich hier blenden?
Daß Asm eine Menge Potential hat, nun, da bin ich nicht der Einzige der
das behauptet- und täglich erlebt ;-)
Moby A. schrieb:> Leider mach ich das nicht hauptberuflich und soviel Zeit steht in der> Freizeit nun auch nicht gerade zur Verfügung
Tja, da geht's den Menschen wie den Leuten. Genau sowas ist halt der
Grund, warum so ziemlich alle anderen Mitdiskutanten hier, trotz
teils guter oder sogar sehr guter Kenntnisse der jeweiligen
Assembler-Welt (siehe Johanns Code) ihre Zeit eben nicht damit
verplempern wollen, sich nun zu überlegen, ob in der nächsten Zeile
ein gesetztes oder ein gelöschtes Carry-Flag ausgewertet werden soll,
und ob die Auswertung direkt als bedingter Sprung erfolgen kann oder
wegen eines schier unerreichbaren Sprungziels indirekt (also negiert),
indem der nächste (lange) Sprungbefehl stattdessen ausgelassen wird.
Diesen ganzen aufwändigen Kleinkram beherrscht eine Maschine namens
Compiler einfach mal um mehrere Größenordnungen schneller und vor
allem weniger fehleranfällig, weil sie ständig inhärent alle
Randbedingungen berücksichtigen kann (wie die Länge eines Sprungs
oder eben den adressierbaren Bereich einer BST-Anweisung) und auch
bei doppelter Verneinung noch keinen Knoten im Gehirn bekommt.
Dafür wiederum kann man dann, ganz ohne es hauptberuflich tun zu
müssen, auch mal schnell ein paar Zeilen Code nur für eine Antwort
im Forum zusammenhacken, um einem Menschen, der um Hilfe bittet, schnell
und unbürokratisch zu helfen – nebenbei, neben der ganz normalen Arbeit,
Familie, sonstigen Freizeitbeschäftigungen.
Klaus W. schrieb:> Der Code erklärt sich halt nur sich selbst, aber nicht anderen.> Zumindest wenn es mehr als ein paar Zeilen sind.Das gilt für C genauso. Selbsterklärend im Sinne von 'die
Sprach-Vorkenntnis überflüssig machend' ist keine von beiden. Direkter
Asm-Text sagt aber direkt was nun wirklich Fakt ist und sich bei C nur
über Umwege erschließt. Freilich, man muß es oft gar nicht unbedingt
100%ig wissen. Wenn man auf den Effizienzvorteil von Asm verzichten kann
und seine einschränkende Hochsprache liebt.
Matthias L. schrieb:> Der von mir gepostete Asm COde wurde von Moby> bisher nicht erklärt. Obwohl es doch selbsterklärend ist.
Bitte Geduld Matthias. Siehst ja was hier los ist. Danke für Deine
Analyse, die ist noch auf meinem Stack geparkt ;-)
Falk B. schrieb:> Das erklärt doch alles!
Falk und seine schnellen Erklärungen.
Hattest Du den AVR nicht schon längst in der Steinzeit verortet? Wie zum
Teufel kann der hier heute immer noch so präsent sein?
Karl H. schrieb:> Weil du dein Assembler Anpreisung auch nicht auf die von dir vorne> gesehenen Anwendungen beschränkst.
In der Tat sehe ich für Asm größeres Potential wenn ein paar andere
Randbedingungen erfüllt wären. Das hier zum Thema zu machen wäre aber
uferlos.
Bleiben wir mal bitteschön beim Thread-aktuellen AVR!
Jörg W. schrieb:> Diesen ganzen aufwändigen Kleinkram
Aufwand?
Machen wir mal das AVR Instruction Set nicht aufwendiger als es ist. So
ein AVR ist schön überschaubar. Und der "Kleinkram" ist ja gerade jenes
Kleinteilige was die bessere Anpassbarkeit an die Hardware und damit die
bessere Effizienz von Asm ausmacht!
> weil sie ständig inhärent alle Randbedingungen> berücksichtigen kann (wie die Länge eines Sprungs oder eben den> adressierbaren Bereich einer BST-Anweisung) und auch bei doppelter> Verneinung noch keinen Knoten im Gehirn bekommt.
Das sind gar nicht soviele Randbedingungen. Anders als beim ARM. Daß BST
mit einem falschen Operanden unbemängelt assembliert wird muß wirklich
nicht sein. Und was den Knoten im Gehirn angeht: Der entsteht mit
komplexen C-Ausdrücken sehr viel schneller. Und da reden wir noch nicht
vom weitaus abstrakteren OOP wo der Bezug zur Hardware-Wirklichkeit
vollends den Bach runter geht.
Moby A. schrieb:>> Diesen ganzen aufwändigen Kleinkram>> Aufwand?
Ja. Aufwand. Schließlich hast du dich gerade beklagt, dass dir die
Zeit für bestimmte Dinge fehlt. Glaubst du etwa, die anderen Leute
hier würden hauptamtlich fürs Forum schreiben, hätten alle keine
Familie, keine anderen Hobbys?
Moby A. schrieb:> Und was den Knoten im Gehirn angeht: Der entsteht mit komplexen> C-Ausdrücken sehr viel schneller.
Ganz gewiss nicht. Hier geht's noch um so einfache Dinge wie
1
if(i<1000000)
wie dir oben bereits ausgiebig demonstriert worden ist.
> Und da reden wir noch nicht vom> weitaus abstrakteren OOP wo der Bezug zur Hardware-Wirklichkeit vollends> den Bach runter geht.
Ach ja. Das kannst du bestimmt auch mit Code belegen, oder?
Moby, du bist einfach mal 50 Jahre zu spät geboren worden. Vor 50
Jahren hättest du dir als "Mel" ja vielleicht noch Respekt erheischt.
https://en.wikipedia.org/wiki/The_Story_of_Mel
Yalu X. schrieb:> Brainfuck, Befunge, Malbolge, FRACTRAN> Die allerkürzeste Instruktionsbeschreibung haben diese Prozessoren
Hochsprachen erklären immer mehr oder weniger schlecht was wirklich
vor sich geht. Genau diese Wirklichkeit aber adressiert und erklärt Asm.
Das ist es was für mich zählt. Andere Prozessoren? Wir wollen doch nun
kein neues Faß aufmachen wenn es hier um AVR geht...
> Was du bei der Bewertung der Sprachen völlig auser Acht lässt, ist ihre> Ausdrucksstärke, d.h. die maximale Komplexität der Problems, das mit> einer gegebenen Menge an Code gelöst werden können.
Da stimme ich Dir sogar zu.
Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für
maximale Komplexität bekannt, und das ist gut so ;-)
Ausdrucksstärke/Flexibilität und mögliche Komplexität sind die zwei
Seiten einer Medaille!
> hat selbst ein überzeugter Assembler-Only-Programmierer> immense Schwierigkeiten, dieses noch recht einfache Beispiel erst einmal> fehlerfrei runterzuprogrammieren und dann auch noch zu optimieren.
Nochmal:
1. 32-Bit Arithmetik ist keine AVR/ASM Stärke.
2. Was man hat das hat man. Für AVR gibts auch genügend fertigen Asm-
Beispielcode so denn umfangreichere Berechnungen mal nötig sind.
3. Sind sie ständig nötig ist AVR/ASM die falsche Wahl.
Jörg W. schrieb:> Moby A. schrieb:> Diesen ganzen aufwändigen Kleinkram>> Aufwand?>> Ja. Aufwand. Schließlich hast du dich gerade beklagt, dass dir die> Zeit für bestimmte Dinge fehlt. Glaubst du etwa, die anderen Leute hier> würden hauptamtlich fürs Forum schreiben, hätten alle keine Familie,> keine anderen Hobbys?
Oh welche weiten Zusammenhänge man da doch gleich herstellen kann ;-)
Das AVR-Instruktion Set ist weniger Aufwand als das bücherfüllende
C-Universum. So definier ich das.
> Hier geht's noch um so einfache Dinge wie if (i <> 1000000)
Und? Das in Asm hinzuschreiben ist nun kein Hexenwerk. Ich bezog mich
beim Thema Gehirnknoten auf komplexere Ausdrücke. Beispiele finden sich
weiter oben ;-)
> Ach ja. Das kannst du bestimmt auch mit Code belegen, oder?
Das belegt jeder OOP Code ;-)
> Moby, du bist einfach mal 50 Jahre zu spät geboren worden.
Meinst Du?
Ich hab eher den Eindruck noch gerade richtig, um mit leistungsstarken
kleinen simplen AVRs die Chance zu haben, selber wirklich alles in der
Hand zu behalten und gestalten zu können!
Moby A. schrieb:> Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für> maximale Komplexität bekannt, und das ist gut so ;-)
Warum meinst du, baut Atmel dann AVRs mit 256 KiB und mehr an Flash?
> 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke.
Hier irrst du bezüglich des AVR gewaltig.
Der AVR ist bei der 32-Bit-Arithmetik viel besser als manch anderer
8-Bitter.
Selbst die 32-Bit-Gleitkommaarithmetik von AVR-GCC/avr-libc (und
auch IAR) ist so rasend schnell, dass du Mühe haben wirst, ihr mit
handgefeilter 24-Bit-Ganzzahlarithmetik in deinem Assemblercode das
Wasser zu reichen – wobei du dann immer noch die Grenzen des
Wertebereichs im Blick behalten musst, während float eben in der
Richtung von selbst skaliert.
(OK, Turbo-Pascals 48-Bit-Gleitkomma konnte das auch schon vor 30
Jahren auf dem Z80. Nicht ganz so schnell, aber genauso bequem für
den Anwender.)
> 2. Was man hat das hat man. Für AVR gibts auch genügend fertigen Asm-> Beispielcode so denn umfangreichere Berechnungen mal nötig sind.
Ja, und? Für C gibt es mehr Bibliotheken, als du dir auch nur
ansatzweise ausmalen kannst. Viele davon laufen durchaus auch auf
einem AVR.
> 3. Sind sie ständig nötig ist AVR/ASM die falsche Wahl.
Trenne mal zwischen AVR und ASM. Die beiden sind nicht miteinander
verheiratet (außer in deinem Kopf), und selbst die ältesten
Randnotizen von Atmel bezüglich des AVR zeigen, dass Alf Bogen und
Vegard Wollan schon vor 20 Jahren deiner Denkweise massiv voraus
waren, da sie bereits in der Designphase einen Compilerhersteller
(IAR aus Schweden) mit ins Boot genommen haben. Ihnen war klar, dass
man den damals fest aufgeteilten Markt an Microcontrollern (zwichen
8051, PIC und MC68) nur dann neu aufrollen kann, wenn bereits die
CPU-Architektur möglichst gut auf eine Sprache wie C passt.
Dir ist das selbst 15 Jahre später noch nicht klar.
Peter D. schrieb:> Eine sehr schöne Routine, die so nur in C praktikabel ist, ist> z.B. der Scheduler:> Beitrag "Wartezeiten effektiv (Scheduler)"
Ohne jetzt den Code im Einzelnen durchgegangen zu sein- fürs "Warten
ohne Rechenzeitverschwendung" ist nun wirklich kein C nötig. Meine
Controller haben meist einen mehr oder weniger gleichschnellen
Timerinterrupt für allgemeine Aufgaben, so auch zur zeitgesteuerten
Taskauslösung bzw. Wartezyklen.
Das muß nicht zum Albtraum ausarten.
Moby A. schrieb:> Oh welche weiten Zusammenhänge man da doch gleich herstellen kann ;-)
Diese Zusammenhänge sind so ziemlich jedem hier klar, nur dir nicht.
Aber geben wir's auf, du willst sie ja nicht sehen.
> Das AVR-Instruktion Set ist weniger Aufwand als das bücherfüllende> C-Universum. So definier ich das.
Definieren kannst du natürlich, was du willst. Der Gültigkeitsbereich
der Definition wird dann allerdings auf dein privates Universum
beschränkt bleiben.
AVR-Befehlssatz: irgendwas um die 150 Seiten
C-Sprachbeschreibung (Kapitel 6 im Standard): 135 Seiten
> Ich bezog mich> beim Thema Gehirnknoten auf komplexere Ausdrücke.>> Ach ja. Das kannst du bestimmt auch mit Code belegen, oder?>> Das belegt jeder OOP Code ;-)
OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und
irgendwer hat dir mal gesagt, es sei "komplex".
Jörg W. schrieb:> Warum meinst du, baut Atmel dann AVRs mit 256 KiB und mehr an Flash?
Für Daten?
Und natürlich für ausschweifende Hochsprachen!
> Der AVR ist bei der 32-Bit-Arithmetik viel besser als manch anderer> 8-Bitter.
Und? Deshalb ist ein 32Bitter in diesem Fall immer noch sinnvoller. Aber
freut mich das hier so festgestellt zu wissen ;-)
> Selbst die 32-Bit-Gleitkommaarithmetik von AVR-GCC/avr-libc (und auch> IAR) ist so rasend schnell, dass du Mühe haben wirst, ihr mit> handgefeilter 24-Bit-Ganzzahlarithmetik in deinem Assemblercode das> Wasser zu reichen – wobei du dann immer noch die Grenzen des> Wertebereichs im Blick behalten musst, während float eben in der> Richtung von selbst skaliert.
Klasse wenns so ist!
Für umfangreichere Arithmetik hätte ich aber auch super Asm Code in der
Hinterhand, wenngleich nicht aus meiner Feder.
> Ja, und? Für C gibt es mehr Bibliotheken, als du dir auch nur> ansatzweise ausmalen kannst. Viele davon laufen durchaus auch auf einem> AVR.
Ja und? Deshalb hab ich wiegesagt damit trotzdem keine Mühe. Das mit den
vielen vielen Bibliotheken sehe ich kritisch. Man begibt sich damit in
gewisse Abhängigkeiten, nimmt unbekannte Fehlerquellen in Kauf, oft ist
eine Funktion schneller selbst geschrieben als irgendwo passend gefunden
und verstanden.
> wenn bereits die CPU-Architektur möglichst> auf eine Sprache wie C passt.
Warum sollte das verwundern wenn sich der potentielle Anwenderkreis
damit erweitert? Deshalb bleibt die einfache Architektur weiter
einfachem Asm zugänglich. Asm ist da seeehr flexibel ;-)
Karl H. schrieb:> weil er viel zu sehr mit diesen Low-Level> Details beschäftigt ist
Nö. Mit der Hardware- Wirklichkeit. Und bestmöglicher
programmtechnischer Anpassung an diese. Damit mit der optimalen Chance
auf effizienten Code.
> Wenn Moby C programmieren würde, dann würde er so kommentieren bzw.> erklären i = 5; // i mit 5 laden> j++; // j um 1 erhöhen
So ein Quatsch.
Wenn ich sage daß ldi r16,25 selbsterklärend ist (mit Kenntnis der
Instruktion) dann würde ich doch in C nicht derart kommentieren ;-)
> und das ist genau die Art Kommentierung, die komplett am Sinn einer> Kommentierung vorbei geht.
Richtig. Das wäre so.
Aber ich sehe schon Du krallst Dich wieder an subjektiven
Kommentierungsfragen fest.
Wozu ist eigentlich dieses Forum im allgemeinen und die
Projekte-Abteilung im speziellen da?
Richtig. Zum Fragen.
> Man kann die> Funktionsweise einer Raffinerie nicht dadurch ergründen und erklären,> dass man sich alle Schrauben, Muttern und Beilagscheiben ansieht.
Es muß langen, Funktionalität und Interfaces zu beschreiben. Mehr Doku-
Aufwand treibe ich nicht. Punkt. Alles andere kann erfragt werden.
Asm Quellcode bleibt damit herrlich übersichtlich.
Von langatmigen Klammerwüsten keine Spur ;-)
Jörg W. schrieb:> OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und> irgendwer hat dir mal gesagt, es sei "komplex".Noch einer schrieb:> Beide Aussagen sprechen von einer Überforderung durch> Informationen und Optionen> Im laufe der Jahrzehnte hat sich die Programmierung komplett geändert.> In die Register eines 8-Bit Controllers, oder auch in ein DOS-Programm> konnte man sich noch vollständig einarbeiten. Heutzutage ist es so> umfangreich - bis man alle Detail durchgearbeitet hat, ist es schon> wieder veraltet.> Es spaltet sich auf - der eine schreibt Python-Libraries für> Raspberry-Peripherie, der andere schreibt damit Web-Oberflächen für> Steuerungen. Pic32 liegt vielleicht noch an der Grenze, wo sich einer> alleine in alles einarbeiten kann. Bei Cortex-A geht das nicht mehr.>> Und dann kommt noch etwas total bescheuertes dazu:>> 20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme> auf 40 verschiedene Arten. C++ ist da am schlimmsten. Man findet in> einem Programm alles von K&R bis Java-Stil; Selbst gebastelte Container> mit obskurer Garbage-Collection neben QList, STL und alten C-Arrays;> Präprozessor-Tricksereinen neben Inline-Funktionen.>> Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während> man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon> wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut.
Soweit zum Thema Komplexität und Kleinkram.
Aufgegabelt in "C++ für Mikrocontroller" gleich nebenan ;-)
Icke ®. schrieb:> Ich habe daraus gelernt, daß jeglicher Versuch, Menschen mit derartig> zementierten Standpunkten (nannte man früher "Betonköpfe") von ihrem> Holzweg abzubringen, selbst unter Zuhilfenahme einleuchtendster> Argumente kläglich scheitert.Das höre ich oft als letztes verbleibendes Argument. Immerhin ist
das aber noch irgendwo verständlich im Gegensatz zu jenen, die glauben,
man müsse nur hinreichend beleidigen.
> Noch ein klein wenig Topic. Ich programmiere auch gern in ASM, aber ich> kenne die Grenzen.
Ich auch. Nur sind die weit weg. Außer es stehen wirklich mal größerer
Berechnungen an ;-)
> Es ist auch schön, per Pedes durch den Wald zu streifen, den Geräuschen> zu lauschen und mit den Füßen direkten Bodenkontakt zu spüren. Und es> macht Sinn, die 100m bis zum Bäcker um die Ecke zu laufen. Aber für den> Großeinkauf oder die Urlaubsfahrt steig ich dann doch lieber ins Auto.
Ja ja die Vergleiche. Habens wirklich in sich.
Yalu X. schrieb:> Matthias L. schrieb:> Ergebnis: Der Tastenpin befindet sich im Carryflag wenn keyproc> aufgerufen wird. Weiter:> keyproc:> ...> ldd XL,Z+0 ;8x alle 5ms testen> rol XL ;= 200% Bulletproof ;-)> std Z+0,XL>> Du hättest statt der "..." die entsprechenden Befehle vollständig> hinschreiben sollen:keyproc: adiw ZH:ZL,2 ;Tastenstatus entprellend> ermitteln> in YH,GPIOR0> mov YL,YH> ldd XL,Z+0 ;8x alle 5ms testen> rol XL ;= 200% Bulletproof ;-)>> Der erste Befehl ist nämlich ADIW, das das Carry-Flag überschreibt, im> konkreten Fall mit 0. Somit schiebt ROL in das XL-Register nur Nullen> hinein, was den nett gemeinten Programmiertrick völlig versagen lässt.
So. Hab mal drübergeschaut.
In der Tat löscht adiw ZH:ZL in jedem Fall das C-Flag.
Vermutlich hab ich das später noch hinzugefügt/umgeändert. Abhilfe:
Aufruf von keyproc mit T- statt C-Flag und nach mov YL,YH ein brtc zum
ldd XL,Z+0 sowie zwischendrin noch ein sec. Also 2 Instruktionen mehr.
Es stimmt, das Programm ist noch nicht getestet, sollte aber auch nur im
ursprünglichen Thread eine einfache Problemlösung in Asm andeuten. Nach
einem Test soll der Main-unabhängige Timerinterrupt-Baustein zur
Tastenentprellung und Feststellung der Betätigungsdauer beliebiger
IO-Pin Tasten in die Codesammlung.
> Wir wissen zwar nicht, was Mobys Programm tun soll
Was sollen solche halbgaren Feststellungen?
Die beabsichtigte Funktionalität ist doch klar definiert.
> Und was lernen wir daraus?> 1. Das Carry-Flag ist eigentlich gedacht
Man muß sich nicht unbedingt daran orientieren wofür etwas gedacht
ist. Damit geht vielleicht ein höheres Risiko für Fehler (wie hier)
einher aber man bewahrt sich alle technischen Möglichkeiten.
> Wenn man schon Assembler programmiert und dabei auzch noch tief in> die Trickkiste greift, sollte man gut ausgeschlafen sein und jede> Code-Änderung dreimal mit dem Auge durchgehen und zusätzlich intensiv> testen.
Flüchtigkeitsfehler sind wirklich nicht die größten Probleme. Die sind
eher systematischer Natur, etwa in Zusammenhang mit unklaren realen
Messwerten.
> Er hat sie auf mehrere Tasten erweitert, musste dazu aber die> indirekte Adressierung für das Z-Register und damit verbunden den> ADIW-Befehl einführen, was schließlich zu dem Fehler führte.
Gut möglich.
> => Wiederverwendbarkeit von Code erfordert eine genaue und> vollständige Dokumentation nicht nur der Funktion, sondern auch der> Nebeneffekte. Das ist hier offensichtlich nicht geschehen.
Richtig.
> Da Moby der Assembler-Gott ist, der immer alles richtig macht, hat er> auch keinen Bedarf gesehen, die Routine vor ihrer Veröffentlichung> wenigstens einmal zu testen ;-)
Schön wärs.
> 3. Hochsprachen sind weniger anfällig gegen solche Fehler
Dafür gegen andere.
Also sollte der C-Flag Fehler der Einzige im Programm gewesen sein bin
ich schon zufrieden. Das Angebot zum kürzeren Formulieren der
beschriebenen Funktionalität in C steht nach wie vor... Dabei muß man
sich auch nicht an meiner Programmlogik orientieren.
Moby A. schrieb:> Jörg W. schrieb:>> OK, Thema abgehakt. Du kennst von OOP offenbar nur den Namen, und>> irgendwer hat dir mal gesagt, es sei "komplex".>> Noch einer schrieb:>> Beide Aussagen sprechen von einer Überforderung durch>> Informationen und Optionen
...
>> Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während>> man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon>> wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut.>> Soweit zum Thema Komplexität und Kleinkram.> Aufgegabelt in "C++ für Mikrocontroller" gleich nebenan ;-)
Na und? Du bist halt nicht der einzige, der nicht programmieren kann.
Nö, Moby hat in einer Hinsicht schon recht. Von Assembler zu C zu C++
steigern sich Abstraktion und Komplexität - wobei ich damit nicht die
des erzeugten Codes meine. Mit der Länge des Handbuchs ist das nur
unzureichend beschrieben.
So steht der Assembler-Befehl XXX R0,R1 für eine klare Anweisung, genau
an dieser Stelle genau das zu tun, was da steht, und es reicht
weitgehend aus, die Beschreibung des Befehls nachzulesen um zu
verstehen, was die Zeile genau tut. Man kann aufgrund des vielen
Kleinklein zwar das Programm schlechter anhand des Codes erfassen, aber
die einzelnen Zeilen sind einfacher.
Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt
sich die tatsächliche Operation erst aus den Datentypen der Operanden.
So ist nicht von vorneherein klar, ob mit oder ohne Vorzeichen
verglichen wird, weil das von den exakten Datentypen und dem
Typenmodell des Compilers abhängig ist (u16 < i32 => signed, u32 < i32
=> unsigned). Dafür aber sieht man gleich, dass es ein Vergleich ist,
egal ob dahinter nur ein Maschinenbefehl sitzt, oder hunderte.
Die ersten C Compiler waren auch noch auf einer Ebene, der C die
Einstufung als glorifizierter Makroassember verdankte. Sie übersetzten
ziemlich linear den geschriebenen Code in Maschinencode. Wer
Registeroptimierung wollte, der tat das selbst und schrieb "register"
hin. Code wurde nicht wegoptimiert, nicht verschoben. Probleme mit in
Interrupts verwendeten Daten entstanden erst, als die Compiler besser
wurden, weshalb dann "volatile" nachgereicht wurde. Dieses "volatile"
sorgt zwar nur für ein paar Zeilen im Handbuch, hat aber fundamentalen
Einfluss auf bestimmte Programmierkonzepte, wie viele µC-Programmierer
erst lernen müssen. Moby bleibt dies erspart.
Mit C++ setzt sich das fort. So kann man sich bei eigentlich per
Referenz übergebenen Parametern von dummerweise vom Compiler nur
temporär angelegten Daten überraschen lassen, wodurch das Ergebnis im
Nirvana entschwindet. Aus dem Quellcode der Zeile geht das nicht hervor,
da muss man weit mehr überblicken.
Inwieweit das freilich gegen die Programmierung in Hochsprachen spricht
muss jeder für sich entscheiden. Komplexität ist nicht grundsätzlich ein
Nachteil, weil man oft nur aufgrund der Komplexität der Mittel überhaupt
erweiterte Probleme lösen kann. Moby beschränkt sich dann eben auf jene
Probleme, die er lösen kann. Die anderen negiert er gerne, weil "braucht
man kaum".
Das Problem mit Moby ist nicht seine Beschränkung auf Werkzeuge, deren
Komplexität er überblicken kann, sondern sein Sendungsbewusstsein, diese
persönliche Eigenheit zu Mass der Dinge zu erklären und andere davon
überzeugen zu wollen. Ihn schreckt der höhere Abstraktionsgrad höherer
Sprachen, andere Leute aber nicht, und das versteht er nicht.
Moby A. schrieb:> Nun sind AVR und seinen typischen 8-Bit Apps aber nicht gerade für> maximale Komplexität bekannt, und das ist gut so ;-)
Du hast gar keine Ahnung, wie "typische 8-Bit-Apps" für AVRs aussehen.
Da passt schon jede Menge an Funktionalität rein, von denen Du noch
nichtmals zu träumen wagst.
Beschränke Dich mal bei Deinen ganzen Behauptungen auf ATTiny mit
höchstens 1KB Flash. Da machen Deine Argumente (und damit Assembler)
vielleicht noch in einigen Ausnahmefällen überhaupt Sinn.
Deine Welt ist klitzeklein, Moby. Du wüsstest noch nichtmals, was Du mit
einem ATmega328 anfangen könntest. "Typische AVR-Anwendungen" finden
aber eher in diesen Größenordnungen statt.
A. K. schrieb:> So steht der Assembler-Befehl XXX R0,R1 für eine klare Anweisung, ...
...
> Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt...
So kann man aber nicht sinnvoll vergleichen, es sei denn man misst seine
Arbeit in Anzahl Programmzeilen.
Es geht ja in der Regel nicht darum, Text zu produzieren, sondern ein
Problem zu lösen.
Und dann kann man nicht einen C-Ausdruck mit einem Assemblerbefehl
vergleichen, sondern müsste den C-Ausdruck mit der entsprechenden Folge
von Assemblertext vergleichen, der funktional gleichwertig ist.
Und genau dann ist Assembler bei nichttrivialen Problemen eben schon
nicht mehr so klar und übersichtlich - wie man an den Fehlern in Mobys
ach so klaren, übersichtlichen und selbsterklärenden Programmen sieht.
Hier sehe ich den die Crux der ganzen Diskussion (neben dem
Missioniergeist, der mit Verblödung regelmäßig einhergeht in jeder
Religion): EIN Assemblerbefehl ist übersichtlich, klar.
Aber die vielen, die man für ein halbwegs komplexes Problem braucht,
sind es nicht mehr.
Auch ein typisches C-Programm besteht ja nicht mehr aus einem Vergleich,
sondern aus wesentlich mehr.
Wenn man dann für jedes Detail etliche Maschinenbefehle erfassen muß,
hat man einfach keinen Überblick.
Außer man ist so genial wie Moby; ich bin zu doof für sowas.
> ich bin zu doof für sowas.
Viele hier sind zu doof dafür, mich eingeschlossen. Deshalb müssen wir
mit Programmieren unsere Brötchen verdienen. Nur einer macht das als
Hobby, der Mobby! (wie er sich diesen NickName ausgesucht hat. Welch
Weitblick!)
(bin ich froh, daß ich den nicht als Kollegen hab. Obwohl, der ein oder
andere, um den ich einen großen Bogen mache, ist auf einem "guten" Weg)
Klaus W. schrieb:> Und dann kann man nicht einen C-Ausdruck mit einem Assemblerbefehl> vergleichen,
Doch, kann man schon. Man kann Programmzeilen vergleichen und man kann
Lösungen vergleichen.
Ich hatte oben eine Programmzeile verglichen, um den Unterschied der
Komplexität dieser Programmzeile hervorzuheben. Dass man für die gleiche
Lösung wesentlich mehr Asm-Zeilen benötigt ist unstrittig und eine
andere Art von Vergleich.
> Aber die vielen, die man für ein halbwegs komplexes Problem braucht,> sind es nicht mehr.
Klar.
> Außer man ist so genial wie Moby; ich bin zu doof für sowas.
Die Grösse eines Programms, das man noch einigermassen überblicken kann
ist begrenzt. Weshalb die Lösungen, die man noch alleine stemmen kann,
mit der Komplexität des verwendeten Werkzeugs wachsen. Weshalb man in
einer geeigneten Hochsprache komplexere Lösungen stemmen kann als in
Assembler.
Er beschränkt sich auf das, was er überblicken kann, und definiert alles
darüber hinaus als "braucht man nicht". ;-)
A. K. schrieb:> Er beschränkt sich auf das, was er überblicken kann, und definiert alles> darüber hinaus als "braucht man nicht". ;-)
Genau dieser Mikrokosmos von Moby ist der Grund für diesen ellenlangen
Thread.
Moby A. schrieb:>> Wir wissen zwar nicht, was Mobys Programm tun soll>> Was sollen solche halbgaren Feststellungen?> Die beabsichtigte Funktionalität ist doch klar definiert.
Ok, das nehme ich zurück. Ich hatte das mit deinem anderen Code
(adu.asm) verwechselt, dem tatsächlich die Beschreibung der
Gesamtfunktion fehlt.
> Also sollte der C-Flag Fehler der Einzige im Programm gewesen sein bin> ich schon zufrieden.
Ich habe das Programm genauso wenig getestet wie du. Der Fehler mit dem
Carry-Flag ist mir aufgefallen bei dem Versuch, die Funktion des Codes
wenigstens grob zu verstehen. Die meisten Fehler werden aber nicht beim
Durchlesen des Codes, sondern erst beim realen Test aufgedeckt.
Zum Thema
Moby A. schrieb:> Hardware- Wirklichkeit
Es ist sicher kein Fehler, wenn ein C-Programmierer auch ein wenig
Ahnung von Assembler-Programmierung auf der von ihm eingesetzten
Plattform hat, ganz im Gegenteil: Dadurch hat er ein besseres Gefühl
dafür, was er mit bestimmten C-Konstrukten der CPU tatsächlich zumutet.
Ich behaupte mal, dass C-Programmierer, die auch etwas Assembler können,
i.Allg. effizienteren Code schreiben als diejenigen, die nur in
Hochsprachen unterwegs sind.
Umgekehrt gilt das aber auch: Assembler-Programme von Leuten, die auch
regelmäßig in Hochsprachen programmieren, haben i.Allg. eine bessere
Struktur. Dazu gehören bspw. die Vermeidung von Nebeneffekten in
Unterprogrammen (wo möglich), einheitliche Konventionen für den Transfer
der Input- und Outputdaten von Unterprogrammen und die Behandlung
zusammengehörender Daten als eine Einheit (Datenstrukturen). Das kostet
zwar evtl. ein paar Prozent CPU-Leistung, erleichtet dafür aber die
Wiederverwendung von früher geschriebenem Code und reduziert dabei
gleichzeitig die Gefahr von Flüchtigkeitsfehlern, wie sie dir bei der
Anpassung relativ kurzer Code-Abschnitte jetzt schon zweimal passiert
sind.
Mein Rat an dich: Bleib bei deinem Assembler, wenn es dir Spaß macht,
aber versuche parallel dazu, mehr Einblick in die C-Programmierung zu
bekommen. Du wirst dabei immer wieder Aha-Effekte erleben, die dir auch
bei der Assembler-Programmierung zugute kommen. Als Nebeneffekt wirst
du dann auch bei Assembler-vs-C-Diskussionen wie dieser hier von den
anderen ernster genommen :)
Moby A. schrieb:> Asm Quellcode bleibt damit herrlich übersichtlich.> Von langatmigen Klammerwüsten keine Spur ;-)
Du siehst ein C-Programm als eine langatmige Klammerwüste, weil du von C
keine Ahnung hast.
Mir geht es ähnlich, wenn ich mir das von A. K. gepostete APL-Beispiel
anschaue:
A. K. schrieb:> Ich kann da nur wieder dieses Beispiel ans Herz legen
Weil ich von APL keine Ahnung habe, stellt sich das Beispiel für mich
als Wüste von seltsamen Symbolen dar. Ich käme aber nicht auf die Idee,
in einer Diskussion mit APL-Programmierern APL deswegen schlecht zu
reden, denn ich weiß genau:
- Alle anderen Diskussionsteilnehmer verstehen diesen Code und sehen
zwar die Symbole, aber keine Wüste.
- Als einziger Ahnungsloser werde ich von den anderen zunächst
mitleidig belächelt werden.
- Wiederhole ich meine Auffassung, dass APL Käse ist, zu oft, werde
ich irgendwann in hohem Bogen aus der Diskussion hinausfliegen.
Wenn das Wetter am Wochenende schlecht ist, werde ich mir das
APL-Beispiel vielleicht mal genauer anschauen und dann mein erstes
Urteil über diese Sprache bilden. Einen Startpunkt habe ich schon
gefunden: http://tryapl.org/ :)
Yalu X. schrieb:> Es ist sicher kein Fehler, wenn ein C-Programmierer auch ein wenig> Ahnung von Assembler-Programmierung auf der von ihm eingesetzten> Plattform hat, ganz im Gegenteil: Dadurch hat er ein besseres Gefühl> dafür, was er mit bestimmten C-Konstrukten der CPU tatsächlich zumutet.
Das kann ich nur bestätigen. Auch ich habe mal in den 80ern
Z80-Assembler gelernt und konnte nach einiger Übung sogar
Binär-Programme direkt in HEX-Codes in den Rechner eingeben, ohne einen
Assembler bemühen zu müssen - hatte also den Assembler sozusagen
eingeatmet :-)
Auf jeden Fall ist die Kenntnis einiger Assembler Dialekte (später kam
noch 68000 dazu) auch für einen Hochsprachen-Programmierer sehr
nützlich. Denn er weiß dann, wie er dem Compiler "Hilfestellung" beim
Compilieren/Optimieren geben kann. Als Beispiel sei hier nur das
Arbeiten mit Kopien von volatile-Variablen in ISRs genannt.
Auch heute schaue ich noch ab und zu in das vom Compiler generierte
Assembler-File, einfach weil ich neugierig bin, wie er diese oder jene
(kniffligere) Aufgabe gelöst hat und bin manchmal sehr überrascht, wie
effizient die Lösung ist.
> Ich behaupte mal, dass C-Programmierer, die auch etwas Assembler können,> i.Allg. effizienteren Code schreiben als diejenigen, die nur in> Hochsprachen unterwegs sind.
ACK.
> Umgekehrt gilt das aber auch: Assembler-Programme von Leuten, die auch> regelmäßig in Hochsprachen programmieren, haben i.Allg. eine bessere> Struktur.
Sehe ich genauso.
Ich weiß leider nicht, ob Moby aus Deinen Argumenten eine nützliche
Lehre ziehen kann, denn manchmal kommt mir sein Horizont ziemlich
beschränkt vor.
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 ;-)
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.
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.
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. ;-)
> 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.
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 :-)
A. K. schrieb:> Das kann allerdings auch in die Hose gehen, wenn man die Maschine> wechselt, neue und alte Maschine sich erheblich unterscheiden und man> die Regeln der alten Welt im Kopf hat.
Ja, natürlich. Wenn man aber nicht nur in der (eingeschränkten) Welt der
µCs zuhause ist, sondern zum Beispiel auch für diverseste sehr
heterogene UNIX-Umgebungen (beileibe nicht nur x86), programmiert,
bekommt man langsam mit der Erfahrung ein "Gefühl" dafür, was unter
welcher Plattform sinnvoll ist und was nicht.
> Wechseln man dann auf beispielsweise ARM, dann führt das zu> ausgesprochen ineffizienten Programmen, da es bei denen genau umgekehrt> ist. Statische Adressierung ist ineffizient, relative Adressierung> effizient, und man nimmt dem Compiler die Chance zur Optimierung über> Register.
Okay. Manchmal muss man dann halt Kompromisse machen - gerade wenn man
so portabel programmiert, dass ein- und dasselbe Programm sowohl auf ARM
als auch auf AVR und PIC läuft.
Wenn ich aber ein Programm erstelle, dass nur auf einem ARM laufen soll,
gehe ich da mit ganz anderen Methoden dran. Die hier eher üppigen
Ressourcen verleiten mich dazu, den Processor auch als "erwachsene
Maschine" auszunutzen. Dazu gehören auch die Methoden zur Adressierung
von Speicher bzw. dessen Verwaltung. Das macht wesentlich mehr Spaß als
das eher beschränkte Programmieren von 8-Bit-AVRs.
Karl H. schrieb:> blinkende LED kann ruhig auch dabei sein. 3 oder 4 Stück, die> voneinander unabhängig in einer vom Benutzer eingebbaren Frequenz> blinken sollen. Kleine Menüsteuerung noch dazu, mit der man die LED zb> auf einen Triggereingang 'verkabeln' kann.
Mein Vorschlag:
8-Kanal Software-UART (nur Eingänge), um 8 verschiedene LEDs mit SW-PWM
zu steuern. Hierbei kann dann jeder Teilnehmer Skalierbarkeit seiner
Software demonstrieren.
Kleines UART-Protokoll dazu:
Bn<CR> Helligkeit (Brightness) auf n%
Ft,n<CR> Fading innerhalb der Zeit t auf n%
Beispiele:
B80<CR> Helligkeit (Brightness) auf 80%
B00<CR> Ausschalten
B100<CR> Brightness auf 100%
F10,80<CR> Fading innerhalb von 10 Millisekunden auf 80%
F100,00<CR> Fading innerhalb von 100 Millisekunden auf 0%
Diese Aufgabe halte ich für sinnvoller, da die Lösung nachher nicht für
die Tonne ist, sondern durchaus für das eine oder andere Projekt
verwendet werden kann :-)
A. K. schrieb:> Nö, Moby hat in einer Hinsicht schon recht. Von Assembler zu C zu C++> steigern sich Abstraktion und Komplexität
Die Abstraktion steigt, aber auch die Komplexität? Eher nicht. Es gibt
ja schließlich Gründe, warum Spaghetticode wie in Assembler so einen
enorm schlechten Ruf hat und warum dringendst von der Verwendung des
"goto"-Befehls in C und C++ abgeraten wird: weil das den Code
unübersichtlich (vulgo: komplizierter) macht sowie Pflege und
Wiederverwendung erschwert.
Ja, eine einzelne Assembler-Instruktion ist "einfacher" insoweit als sie
nur einen einzigen, winzigen kleinen Teil des Programms ausmacht. Aber
das ist nur der eine Teil der Wahrheit, und der andere Teil lautet: eine
einzelne Instruktion ist eben nur ein winzig kleiner Teil eines deutlich
größeren Programms. Genau da liegen aber die Vorteile einer besseren
Strukturierung und Abstraktion durch die Hochsprachen, im Gegensatz zu
Spaghetticode, in dem zwischen verschiedenen Sprungmarken und Codeteilen
wild hin- und hergesprungen wird.
> Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt> sich die tatsächliche Operation erst aus den Datentypen der Operanden.
Das ist nicht komplizierter, sondern viel einfacher, weil der Compiler
dem Entwickler die Entscheidung, welche Maschineninstruktion(en) zu
verwenden sind, ganz einfach abnimmt. Dank der deklarierten Datentypen
der Variablen weiß der Compiler nämlich, welche Operation benutzt werden
muß, und nimmt automatisch und ohne jedes Zutun die Richtige(tm). Für
den Entwickler ist das eine enorme Vereinfachung und Erleichterung
seiner Arbeit, und nicht zuletzt deswegen ist die Produktivität eines
Entwicklers in Hochsprachen so viel höher als in Assembler.
Richtig ist, daß der Entwickler dabei ein wenig von der Kontrolle
darüber verliert, was sein Code genau macht. Mehr Kontrolle bedeutet
aber immer mehr Arbeit und Komplexität, um die sich der Entwickler
kümmern muß.
Sheeva P. schrieb:> Die Abstraktion steigt, aber auch die Komplexität? Eher nicht.
In aller Kürze: Bei geeigneten Werkzeugen wird die Lösung eines nicht
trivialen Problems durch die Wahl eines komplexeren Werkzeugs oft
einfacher, sofern man nicht an der Komplexität des Werkzeugs scheitert.
Es ist weitaus schneller, nach Malle zu fliegen als zu schwimmen. Aber
man behilft sich dabei eines hochkomplexen Werkzeugs namens "Flugzeug"
und überlässt dessen Komplexität andern Leuten und Automaten. Schwimmen
ist ein Vorgang von weitaus geringerer Komplexität und ist dabei nicht
unmöglich, aber es ist nicht wirklich als Lösungsansatz zu empfehlen.
Gäbe es keine Piloten (inkl. Auto-) und man müsste selber ans Steuer des
Vogels, dann würde viele Leute wohl den Moby machen und in einfacher
erreichbaren heimatlichen Gefilden urlauben.
"Komplexität" ist ein weiter Begriff. Ich bezog mich darauf, dass man
die Abfolge von Assembler-Befehlen relativ leicht anhand der einzelnen
Beschreibungen der Befehle nachvollziehen kann.
In einer Hochsprache hingegen gibt es eine Vielzahl an Faktoren, die in
die exakte Funktion einer Zeile einfliessen können. Viele dieser
Faktoren sind quer über die Sprachbeschreibung gestreut und der
Programmierer muss sie im Kopf haben und zum passenden Zeitpunkt mit der
Zeile assoziieren.
> Ja, eine einzelne Assembler-Instruktion ist "einfacher" insoweit als sie> nur einen einzigen, winzigen kleinen Teil des Programms ausmacht.
Weshalb ich ja auch vorhin schon zwischen der Komplexität der Zeile und
der Komplexität der Lösung unterschied.
>> Im C Statement ist das komplizierter. Im Statement if(a < b)... ergibt>> sich die tatsächliche Operation erst aus den Datentypen der Operanden.>> Das ist nicht komplizierter, sondern viel einfacher, weil der Compiler> dem Entwickler die Entscheidung, welche Maschineninstruktion(en) zu> verwenden sind, ganz einfach abnimmt.
Die Codegenerierung ist nur ein Teil der Gesamtproblematik.
Ein häufiges Problem unter C Programmieren ergibt sich aus der
Kombination vorzeichenfreier und vorzeichenbehafteter Typen. Aus if(a <
b)... ergibt sich nicht direkt, ob der Vergleich mit oder ohne
Vorzeichen stattfindet. Auch wenn "unsigned a" und "long b" bekannt sind
ist das noch nicht klar, denn 16- und 32-Bit Maschinen verhalten sich
dann völlig verschieden.
Der Programmierer muss also jenseits der Bedeutung des "<" Operators
auch die in C üblichen Konvertierungsregeln im Kopf haben und diese in
Bezug zur realen Maschine setzen. Es ist diese Art der Komplexität
einer Sprache, auf die ich mich beziehe.
> muß, und nimmt automatisch und ohne jedes Zutun die Richtige(tm).
Er nimmt das, was sich aus den Regeln ergibt. Das ist keineswegs immer
die richtige Wahl in Bezug auf die Lösung des Problems. Das "do what I
mean, not what I say" Problem ist nach wie vor ungelöst.
> Für den Entwickler ist das eine enorme Vereinfachung und> Erleichterung seiner Arbeit,
Richtig. Weshalb ich ja diese Form der Komplexität nicht ablehne. Ich
weise nur darauf hin, dass es sie gibt.
A. K. schrieb:> Doch, kann man schon. Man kann Programmzeilen vergleichen und man kann> Lösungen vergleichen.
Wenn man die Anzahl von Programmzeilen in Assembler, C und, sagen wir,
Ruby vergleicht, wird daraus aber zwangsläufig ein Vergleich von Äpfeln,
Bananen, und Rinderhacksteaks, oder anders gesagt: solche Vergleiche
hinken und sind weder sinnvoll, noch zielführend. Zumal die Zeilen, die
Du vergleichen willst, nicht einmal näherungsweise etwas ähnliches tun.
Das ist aber gerade das, was einen Programmierer interessiert: nämlich
das, was sein Programm tut, also daß das Programm sein Problem löst. Wie
es das Problem dann tatsächlich löst, ist eher nebensächlich.
Programmieren ist schließlich kein Selbstzweck, sondern soll praktische
Probleme lösen, wie hier im Beispiel den Vergleich zweier Zahlen.
> Ich hatte oben eine Programmzeile verglichen, um den Unterschied der> Komplexität dieser Programmzeile hervorzuheben. Dass man für die gleiche> Lösung wesentlich mehr Asm-Zeilen benötigt ist unstrittig und eine> andere Art von Vergleich.
Es ist die einzige Art von Vergleich, die einen Sinn ergibt. Aber auch
wenn wir bei Deinem Vergleich bleiben, zeigt sich, wie viel komplizerter
ASM ist: ein "if(a < b)" versteht sogar jemand, der überhaupt keine
Ahnung von der Programmiersprache C oder überhaupt vom Programmieren
hat. In Assembler steht da etwas wie "cp r16, r17", "cpc r16, r17" oder
"cpi r16, r17", was sich einem Betrachter nur erschließen kann, wenn er
weiß, was "cp", "cpc" und "cpi" tun und was die Register "r16" und
"r17" sind.
Um Dein Assembler-Beispiel aber auch nur halbwegs vergleichbar mit jenem
in C zu machen, kommt allerdings noch der Sprungbefehl hinzu, und erst
wenn man den hinzunimmt, kommt am Ende etwas heraus, das wenigstens im
Ansatz mit dem C-Beispiel äquivalent und vergleichbar ist. Denn das ist
schließlich jener Grad an Komplexität, die der Programmierer letztlich
behandeln und beherrschen muß. Und dann bekommt die Sache einen Sinn:
1
if(a<b)mach_dies();
ist viel einfacher und lesbarer und sogar für Laien verständlicher als
1
cp r16, r17
2
brlo mach_dies
-- und das gilt nur für vorzeichenlose (unsigned) Zahlen in r16 und r17.
Wenn die Zahlen vorzeichenbehaftet (signed) sind, heißt die Instruktion
nicht mehr "brlo", sondern "brlt"... Das erschließt sich jemandem, der
Programmieren kann, aber ein Laie versteht nichtmal, warum es da zwei
verschiedene Instruktionen gibt, die (vermeintlich) dasselbe tun. Und
weil nur Masochisten und Ideologen sich an solcherlei Kinkerlitzchen
aufhalten, reale Programmierer aber praktische Probleme schnell und
effizient lösen wollen, wird Assembler heute nurmehr in wenigen
Ausnahmefällen benutzt. Für einen, der sie beherrscht, sind C und, wo
wir gerade dabei sind, auch C++ sehr viel klarer und einfacher als
Assembler.
für unterschiedliche Leute sind halt verschiedene Sachen eine
'Erklärung/Dokumentation'. Hier mal ein klassischer Filmausschnitt:
https://www.youtube.com/watch?v=rFz2llnnC1o
Es ist ganz klar was dieses Objekt (Zeile Code) tut. Nur das 'wozu'
fehlt.
Sheeva P. schrieb:> Wenn man die Anzahl von Programmzeilen in Assembler, C und, sagen wir,> Ruby vergleicht,
Wir schreiben aneinander vorbei. Ich beziehe mich stets auf die
Komplexität des Werkzeugs und du zählst andauernd Programmzeilen.
Wer ein komplexes Werkzeug beherrscht, der hat bei der Lösung eines für
dieses Werkzeug geeigneten Problems weniger Arbeit als jemand, der mit
einem weitaus einfacheren Werkzeug auskommen muss. Das ändert nichts an
der Komplexität des Werkzeugs, sehr wohl aber den Aufwand zur Lösung
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.
Karl H. schrieb:> Eine andere Analogie wäre für mich Schach:> Die möglichen Züge sind so etwas wie Assembler.
Der Vergleich mit Schach stellt aber auch schnell die Aussage 'Wenn der
Computer(Compiler) besser ist, dann war der
Schachspieler(ASM-Programmierer) nicht gut' stark in Frage. Inzwischen
ist die Menge der 'guten' Schachspieler ja schon die leere Menge.
Dumdi D. schrieb:> Inzwischen> ist die Menge der 'guten' Schachspieler ja schon die leere Menge.
Ich bin gerne bereit zuzugestehen, dass es für praktische Zwecke nicht
akzeptabel ist, dass ein Compiler 20 Minuten an der Übersetzung eines
moderaten Codes arbeitet. Würde man ihm die Zeit geben, dann würde er
auch die perfekte Lösung finden können. Inklusive rumprobieren, welche
Variablen er global in welche Register legt, wie er auf einem AVR das
T-Bit für Einzelbitflags sinnvoll nutzen kann, wie er die Pipeline aufs
Beste befüllt halten kann. etc. Bruth Force vom Feinsten.
Da aber Compiler, anders als die 'großen Schachprogramme', kein
Prestigeobjekt sind, wird da nicht so viel investiert.
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/SuperoptimizationKarl 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.
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
Karl H. schrieb:> Können wir gerne machen.> Wir vereinbaren einen Zeitpunkt an dem du und ich Zeit haben. Ein paar> Forneteilnehmer denken sich eine Aufgabe aus, irgendjemand (du, ich, wir> beide) wählt eine der Aufgaben aus und dann schaun wir mal, wer> schneller das Programm stehen hat und wer es fehlerfreier hinkriegt.>> Ich hab nur eine Bedingung: es darf kein Pipifax Beispiel sein sondern> sollte schon was ordentliches sein.
Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem
Mega2560? :P
Karl H. schrieb:> Da aber Compiler, anders als die 'großen Schachprogramme', kein> Prestigeobjekt sind, wird da nicht so viel investiert.
Der Aufwand, die optimale Lösung zu finden, sollte nicht grösser sein
als die Differenz zur suboptimalen leicht ermittelbaren Lösung.
Das ist wie beim Informatikern wohlbekannten Problem des
Handlungsreisenden. Wenn der erst losfährt, nachdem er seine lange
Reiseroute voll durchoptimiert hat, kann es sehr gut sein, dass er
insgesamt länger braucht als wenn er einfach so frei Nase losgefahren
wäre.
Kaj G. schrieb:> Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem> Mega2560? :P
Da muss ich mich erst mal schlau machen, was das überhaupt ist :-)
Karl H. schrieb:> Kaj G. schrieb:>>> Wie waere es mit einer Simulation von 3 ccTalk-Slaves auf einem>> Mega2560? :P>> Da muss ich mich erst mal schlau machen, was das überhaupt ist :-)
1
ccTalk (pronounced see-see-talk) is a serial protocol in widespread use
2
throughout the money transaction and point-of-sale industry. Peripherals
3
such as the currency detectors for coins and banknotes found in a diverse
4
range of automatic payment equipment such as transportation, ticketing,
5
payphones, amusement machines, and retail cash management use ccTalk to
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.
Matthias L. schrieb:> Könnte man das dann gleich praktisch nutzen? Zb für gratis Bahnfahrten?
Wenn du die Verschlüsselung (wo jeder Hersteller seine eigene haben
dürfte, so wie wir) nachbauen/knacken kannst, klar :)
Kaj G. schrieb:> Wenn du die Verschlüsselung (wo jeder Hersteller seine eigene haben> dürfte, so wie wir) nachbauen/knacken kannst, klar :)
Nicht ist so verlässlich unsicher, wie selbstgebaute Verschlüsselung.
;-)
A. K. schrieb:> Nicht ist so verlässlich unsicher, wie selbstgebaute Verschlüsselung.
Stimmt schon, aber lass dir gesagt sein:
Wenn man es wie wir mit organisierter Kriminalität zu tun hat, steckt da
sehr viel Zeit, Geld, und auch entsprechende versuche (von sehr
kreativen/kompetenten leuten), das ding zu knacken, drin ;)
Oder anders gesagt:
Selbst wenn du den Algorithmus kennst, kannst du die Verschlüsselung
nicht brechen ;)
Also "können" schon, dafür muss man dann aber unverhältnis mäßig viel
aufwand treiben.
So, mal zurück zum Thema:
Kaj G. schrieb:> Die Implementierung könnte man Testen, in dem Jemand einen Master> schreibt,
Das reicht aber nicht, denn wirklich interessant wird es erst, wenn
jemand "das Gerät bedient", also z.B. "Geld einwirft und ausgezahlt
haben möchte". Geld einwurf könnte man z.B. durch Taster simulieren (10,
20, 50 cent, 1 und 2 euro, je münze ein taster).
Ich denke mögliche Aufgaben gibt es genug. Nur wie wird das ganze dann
nachher effektiv verglichen, und was ist wann besser?
Geht es nur um den Asm-Code, oder auch sachen wie "Lesbarkeit"? geht es
um die laufzeit?
Was genau will man nachher wie vergleichen? Und wer beurteilt am Ende,
was jetzt "besser" ist?
Oder geht es nur um "selbstgeschriebenen Asm" vs. "vom Compiler
erzeugten Asm"?
(Ja ich geb zu, ich hab irgendwo nach 150 Beiträgen auf gehört zu lesen
und hab erst jetzt wieder angefangen)
Frank M. schrieb:> Diese Aufgabe halte ich für sinnvoller, da die Lösung nachher nicht für> die Tonne ist, sondern durchaus für das eine oder andere Projekt> verwendet werden kann :-)
Sorry, Kay, aber Franks "Anforderung" bezüglich Wiederverwenbarkeit hat
was! ;-)
> Ich würde dann aber an deiner Stelle auch am Terminal zweifeln. Zeig mir mal, an
welcher Stelle deines 8-Bit Zeichensatzes Symbole wie ⍳, ⌹ oder ⍴ zu finden sind.
;-)
Es gab zu APL auch spezielle Schablonen, die man auf
MainFrameTerminalTastaturen legte, damit man auch eintippen konte, was
auf dem Display zu sehen war. Das Terminal war dabei im APL-Mode. APL
hab ich zwar nie benutzt, aber an diese komischen Schablonen kann ich
mich erinnern.
Konrad S. schrieb:> Sorry, Kay, aber Franks "Anforderung" bezüglich Wiederverwenbarkeit hat> was! ;-)
Ist ja völlig legitim.
Ich hatte ja einfach nur was in den Raum/Chat geworfen :-)
Kaj G. schrieb:> Geht es nur um den Asm-Code, oder auch sachen wie "Lesbarkeit"? geht es> um die laufzeit?
Zuallererst geht es um die Funktionsfähigkeit. Und zwar fehlerfrei :-)
Laufzeit ist ein natürlich ein Thema. Da kann sich Moby was aussuchen.
Zeitbedarf in der Erstellung ist ebenfalls ein Thema. Speziell wo doch
Moby eh so wenig Zeit für sein Familie hat (Sorry, could not resist)
> Was genau will man nachher wie vergleichen? Und wer beurteilt am Ende,> was jetzt "besser" ist?
Da hätt ich einen fiesen Ansatz :-)
Jeder von uns beiden baut einen Fehler in seine Version ein. Und dann
schaun wir mal, welche Fraktion (Assembler oder C) den Fehler schneller
findet. :-)
Aber kein Sorge.
Wenn die Dinge so laufen, wie sie eigentlich immer laufen, wird es nie
zu so einem Wettstreit kommen.
Ich bin übrigens das Wochenende über unterwegs. Daher nicht wundern,
wenn ich (falls doch etwas zu stande kommt), nicht zeitnah antworte.
> Oder geht es nur um "selbstgeschriebenen Asm" vs. "vom Compiler> erzeugten Asm"?
Es geht darum, die vollmundigen Aussagen endlich mal auf einen Prüfstand
zu stellen. Und zwar mit ein bischen mehr als Micky Mouse "Wenn Taster
gedrückt, dann LED ein" Programmen (oder Variationen davon). Da Moby
kein Profi ist, gestehe ich ihm eine Beschränkung der Komplexität der
Aufgabenstellung zu. Aber auch nicht zu trivial.
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 ;-)
Karl H. schrieb:> Da Moby kein Profi ist,
Also wenn ich die erste Seite dieses Threads richtig verstehe, macht
Moby seit 18 Jahren Asm, da sollte man doch schon zu den "Profis"
zählen, oder? :)
Kaj G. schrieb:> Karl H. schrieb:>> Da Moby kein Profi ist,> Also wenn ich die erste Seite dieses Threads richtig verstehe, macht> Moby seit 18 Jahren Asm, da sollte man doch schon zu den "Profis"> zählen, oder? :)
Hätte ich auch gesagt. Aber auf der anderen Seite wenn ihn ein 32 Bit
Vergleich schon vor so unübeerwindliche Hürden stellt.
(Den Fehler im ADC Beispiel seh ich so wie er nicht als verzeihlichen
Flüchtigkeitsfehler an, sondern der ist schon massiv mittelprächtig
schwer und genau von der Sort, vor denen wir Asm-Programmierer immer
warnen: du musst dir bei einer Änderung ALLES ansehen. Und ALLES meint
auch wirklich alles. Du musst dich um jeden Kleinscheiss selber kümmern:
Adressierung, Flags, Registerbenutzung. So gesehen wäre genau dieser
Fehler das beste Argument, warum ein Compiler sinnvoll ist. Aber seis
drum. Wir alle machen mal Fehler das man sich hinterher nur noch auf den
Kopf greift und fragt: Wie konnte das passieren?)
Moby A. schrieb:> Das Angebot zum kürzeren Formulieren der beschriebenen> Funktionalität in C steht nach wie vor... Dabei muß man> sich auch nicht an meiner Programmlogik orientieren.
Du schreibst, du willst den optimalen Code? Warum sparst zu dann auf
Teufel-komm-raus 1, 2 läppische Instruktionen anstatt SCHNELLEN Code zu
schreiben?
Z.B dein Code für den LM335:
o Ob der der 2 Byte kürzer oder länger ist, ist sooo egal, egaler
geht's nicht.
o Der Code läuft in einer ISR. Warum machst du den Code extra
lahm, obwohl er in einer ISR laufen soll??? Es ist doch total
hirnrissig, paar Bytes zu sparen wenn der Code schnell sein soll!
Fangen wir mal mit der Erbsenzählerei an:
o RCALL, RET und dein arschlahmer Rechtsschift kosten
2 + 5 = 7 Instruktionen.
o Ohne große Verrenkungen macht man den 16-Bit Rechtsshift
in 9 Instruktionen OGOTTOGOTT 9 INSTRUKTIONEN HÖLLE!!!
o Zieh die 7 Instruktionen für CALL + RET + Schnach-Schift ab, und
es bleiben 2 Mehrinstruktionen.
o Wenn der Code eh in der ISR laufen soll, wozu dann CALL und RET?
Sind doch unnötig wien Kropf!
Und jetzte schaust du NICHT auf deinen Codelängenfetisch, sondern
schaust dir mal eine SIMULATION an und hälst die SIMULIERTEN BEFEHLE
nebeneinander!
DAS ist nähmlich, was hier zählt.
> 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke.
Das ist doch Käse.
Assembler ist ein exzellentes Einsatzgebiet für Arithmetik. Und wenn
ich solchen Assembler schreibe, dann fuchse ich auch um jedes Byte und
jeden Tick. Aber der Code landet dann auch nicht in der Tonne, sondern
wird von Tausenden von Compiler-Anwendern eingesetzt.
900ss D. schrieb:> Aber ich steige jetzt schon aus wenn Johann mitmacht.> Ich kenne den Source seiner Scopeuhr ;-)
Ja, die Scope-Uhr; Morpheus und Rudi. Ist momentan eingemottet, was
aber nicht an Morpheus liegt ("Morpheus" is der Projektname der
Software), sondern an Rudi ("Rudi" ist der Projektname für die
Handware).
Es gab sogar schon Interesse die Uhr zu vermarkten, aber dazu müsste es
eine vermarktbare Hardware geben, und mit dem Zeug kenn ich mich nicht
aus. Um das professionell und verkaufbar zu machen müsste jemand vom
Fach her...
Übrigens hab ich "Morpheus" als Name für die Software gewählt, weil ich
Gimmiks wie folgendes implementieren wollte:
Beitrag "Re: Wie Parametrisierung für Kurve finden?"https://www.mikrocontroller.net/attachment/52470/A-ani.gifhttps://www.mikrocontroller.net/attachment/52552/AB-ani.gif
Moby A. schrieb:> Das Angebot zum kürzeren Formulieren der beschriebenen Funktionalität> in C steht nach wie vor... Dabei muß man sich auch nicht an meiner> Programmlogik orientieren.
"Angebot" angenommen ;-)
Es geht doch um deinen Assemblercode in diesem Beitrag:
Moby A. schrieb:> Hab mal meine bereits weiter oben zur Sprache gekommene ASM Lösung aus> einem anderen Hochsprachen-Thread(problem) angehängt.
Im Anhang findest du den entsprechenden C-Code, der bis auf ein paar
Kleinigkeiten die gleiche Funktion wie dein Assemblercode hat.
Die Unterschiede:
- Die Anzahl der zu verarbeitenden Tasten ist statt auf 8 nur durch die
Anzahl der verfügbaren Portpins limitiert. Für jede Taste wird ein
zusätzliches RAM-Byte benötigt, dafür bleibt aber das GPIOR0-Register
frei. Für die Erweiterung auf mehr als 3 Tasten müssen nur das Makro
KEYS auf den entsprechenden Wert gesetzt und zusätzliche Aufrufe von
debounce in der Funktion processAllKeys hinzugefügt werden.
- Die Anzahl der Abtastwerte lässt sich mit dem Makro DEBOUNCE_SAMPLES
leicht ändern. Insbesondere sind auch Werte größer als 8 möglich (für
besonders stark prellende Taster).
- Es wird nicht nur die Dauer des Tastendrucks, sondern auch die des
Loslassens gemessen. Dieses Feature braucht man zwar eher selten, aber
wenn doch, dann ist es bereits da und muss nicht mehr implementiert
werden.
- Die Funktion debounce wird wie bei dir die Routine keyproc für
jede Taste aufgerufen, allerdings ist die Aufrufreihenfolge von
debounce unwichtig. So kann bspw. die Auswertung einzelner Tasten
ausgelassen werden, wenn diese in einer bestimmten Situation gar nicht
aktiv sein müssen, was dann etwas CPU-Zeit spart.
- In deinem Code muss man bei der Erweiterung der Aktionsroutinen
(key<i>pressed und key<i>released) darauf achten, dass darin die
Register R27 (XH), R30 (ZL) und R31 (ZH) nicht versehentlich
überschrieben werden, da in diesen Informationen zwischen zwei
Aufrufen von keyproc aufgehoben werden. Das wird – wie schon beim
Carry-Flag geschehen – ganz sicher zur Falle, wenn du deinen Code nach
ein paar Monaten wieder herauskramst, um ihn zu erweitern ;-)
Beim C-Code besteht diese Gefahr nicht.
- Die Entprellung der Tasten und die Ausführung der davon abhängigen
Aktionen (key<i>Pressed und key<i>Released) erfolgt bei mir nicht in
der Interruptroutine, sondern in der Hauptschleife des Programms (aber
trotzdem interruptgetriggert). Dadurch werden – insbesondere bei etwas
aufwendigeren Aktionen – weitere Interrupts, die vielleich später
hinzukommen – nicht unnötig blockiert.
- Zudem erlaubt es diese Ablaufstruktur der CPU, sich während des
Nichtstuns zwischen zwei Timer-Interrupts schlafen zu legen und damit
Strom zu sparen.
Die Entprellroutine ist ganz klassisch, ohne jegliche Tricks und damit
für jeden C-Programmierer (hoffentlich) leicht nachvollziehbar mit zwei
Zählern (für die eigentliche Entprellung die Gedrücktzeitmessung)
realisiert. Man könnte den Code mit Kniffen wie den vertikalen Zählern
in Peter Danneggers Routine sicher noch straffen. Peters Routine ließe
sich auch relativ problemlos auch auf 8 Abtastwerte erweitern.
Allerdings wäre der Code dann nicht mehr so klar verständlich und man
müsste Einschränkungen bzgl. der Erweiterbarkeit in Kauf nehmen (maximal
8 Tasten, die alle an denselben I/O-Port angeschlossen sein müssen).
Trotz der höheren Flexibilität und der für die meisten sicher leichter
verständlichen Programmlogik kann der C-Code größenmäßig gut mit deinem
Assemblercode mithalten:
1
Mobys Asm-Code Yalus C-Code
2
—————————————————————————————————————————————————
3
Flash-Verbrauch 266 256
4
RAM-Verbrauch¹ 6 + 1 GPIOR 9
5
Stack-Verbrauch 2 4
6
Quellcodezeilen² 143 91
7
Quellcodezeichen³ 1614 1707
8
—————————————————————————————————————————————————
9
¹) ohne Stack
10
²) ohne Leer- und Kommentarzeilen
11
³) ohne Kommentare, Leerraum und Zeilenvorschübe
12
13
Compiler: GCC 4.7.4
14
Assembler/Linker: Binutils 2.25.1
15
C-Standardbibliothek: AVR-Libc 1.8.1
Die 26 Interruptvektoren und die Routine zur Initialisierung des
genutzten RAM-Bereichs mit Nullen sind übrigens in den 256 Flash-Bytes
enthalten, auch wenn sie nicht explizit im C-Quellcode auftauchen. Da
übernimmt die C-Toolchain also netterweise eine weitere lästige Aufgabe.
Die versteckte Startroutine initialisiert übrigens auch den Stackpointer
und das Statusrgister, was beim ATmega88 nicht unbedingt erforderlich
ist. Eine dahingehend optimierte Startroutine würde noch einmal 10 Bytes
sparen.
Wenn man die Startroutine aber sowieso anpasst, könnte man bei dieser
Gelegenheit gleich noch den Aufruf des nie endenen Hauptprogramms
optimieren, was weitere 6 Bytes Flash und 2 Bytes Stack spart. Damit
läge der Flash-Verbrauch mit 240 Bytes fast 10% unter dem deines
Assemblerprogramms.
Die Quellcodegröße in Zeichen ist beim C-Code immerhin knapp 6% größer
als beim Assemblercode. Mit kürzeren Variablennamen, die dann ähnlich
nichtssagend wären wie die Registernamen R18, XL, ZH usw. n deinem
Assemblerprogramm könnte auch dieses Manko behoben werden, aber das
lasse ich besser bleiben ;-)
Abschließende Anmerkungen:
Den C-Code habe ich mangels einer Schaltung mit dem ATmega88, den
Tastern und den LEDs nicht auf dem Zielsystem laufen lassen. Allerdings
habe ich die Funktion debounce mit simulierten Eingaben auf dem PC
getestet, so dass ich mit ziemlich sicher bin, dass diese Funktion
korrekt ist. Eventuelle Fehler in anderen Programmteilen (Tasten lesen,
Ergebnis von debounce abfragen, LEDs schalten usw.) sollten mit
minimalen Änderungen und ohne Erhöhung des Flash- und RAM-Verbrauchs
korrigiert werden können.
Die Initialisierung des Timers habe ich ohne Prüfung von Mobys Code
übernommen in der Hoffnung, dass sie fehlerfrei ist.
Yalu X. schrieb:> "Angebot" angenommen ;-)
Gut gemacht :-)
Bin mal gespannt wie groß der Moby's Assemblercode denn wird wenn er all
deine Features auch noch implementiert
Kommt, die Sache ist doch schon erledigt.
Laut Moby:
Moby A. schrieb:> Horst S. schrieb:>> Moby schrieb:>> Asm allein ist nun>> leider keine Garantie für guten Code, wie man beim TO-Programm schön>> sehen kann ;-)>>>> Begründe mir nur diese eine Aussage, sachlich, fachlich kompetent und so>> vollständig, dass ich es aus Deinen Worten verstehen kann (also ohne>> großartige Literatur, die ich nicht habe). Ich bin bestimmt kein Guru,>> aber einfach abfrühstücken lasse ich mich auch nicht von Dir.>>>> Überzeug' mich, dann hast Du eine Chance auf 'ne Entschuldigung.>> Die Entschuldigung kannst Du Dir sparen.> Wenn sich Dein Asm-Code mit C locker unterbieten lässt dann spricht das> jedenfalls nicht für Deinen Asm-Code.
Da sich sein Asm-Code auch mit C locker unterbieten lässt, kann er
selber laut seiner Argumentation keinen guten Code schreiben.
Johann L. schrieb:>> 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke.>> Das ist doch Käse.
Zwar tun sich 32-Bitter damit naturgemäss leichter, aber unten den
8-Bittern schlägt sich AVR dabei ziemlich gut. Register sind dabei
deutlich besser als ein Akkumulator.
A. K. schrieb:> Moby beschränkt sich dann eben auf jene> Probleme, die er lösen kann. Die anderen negiert er gerne, weil "braucht> man kaum".
Danke A.K. für diesen tiefschürfend analysierenden Beitrag, hab mich
köstlich amüsiert. Hast schon recht: Ich beschränke mich. Aber nicht auf
die Probleme die ich lösen kann sondern auf die Auswahl dazu hilfreicher
Werkzeuge. Da nehm ich nämlich gern das Einfachste ;-)
> Ihn schreckt der höhere Abstraktionsgrad höherer> Sprachen, andere Leute aber nicht, und das versteht er nicht.
Mich schreckt gar nichts.
Ich interessiere mich sogar sehr dafür.
Und hab gelernt daß alle ach so vereinfachende Abstraktion und
hochsprachliche Seiltänzerei zumindest über dem 8-Bit Hardware-Abgrund
eine böse Kehrseite hat.
Frank M. schrieb:> 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.
Du bist ja top informiert ;-)
Das war zwar gar nicht der Punkt, aber klar doch kann man mit der
Leistung eines AVR eine Menge anstellen. Soviel nämlich, das 8-Bittern
noch lange kein Ende beschieden ist.
Klaus W. schrieb:> 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.
Da sehe ich keinen Unterschied zu den komplexen Ausdrücken der
Hochsprache. Klarheit, Übersichtlichkeit und Selbsterklärnis von
ASM-Programmen wird durch Flüchtigkeitsfehler nicht tangiert.
A. K. schrieb:> 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.
Interessante These und da mag für höherbittige Universen samt deren
Software was dran sein. Notwendig höhere Softwarekomplexität in
Asm-Programmen lässt sich aber auch durch ein besonders systematisches
Herangehen, Modularisierung und ausgefeilte Schnittstellen erreichen.
Alles ohne Sprach-Bimbamborium höherer Sprachen.
Frank M. schrieb:> Genau dieser Mikrokosmos von Moby ist der Grund für diesen ellenlangen> Thread.
Nun ist ja gut, Frank M. Ich weiß ja, daß Du mit Deinen Programmen das
Tor zu höheren Welten aufgestoßen hast. Versichere Dich nur weiter
meines arg begrenzten Mikrokosmos- ich merke schon, das tut Dir gut ;-)
Karl H. schrieb:> Aber erst mal muss er den Fehdehandschuh aufgreifen. Mal sehen, obs so> kommt wie es immer kommt, wenn ich sowas anbiete :-)
Den greife ich natürlich nicht auf, weil ich für solche Späße keine Zeit
investiere. Meine Software die ich veröffentlicht habe und noch zu
veröffentlichen gedenke ist nicht so umfangreich, daß ein C-Profi das
nicht mal eben schnell kürzer codiert und mich so zum Staunen und
Schweigen bringt ;-)
Gerade läuft wieder ein Thread:
Verzweifelt keine Anzeige am LCD
Es geht um LCD in Assembler. Da wäre eine echte Konifere gefragt. Der
Kolege versteht zwar die Befehle, aber nicht, was sie zusammen tun.
Aber wie immer: große Klappe, nix tun!
Johann L. schrieb:> 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?
Wie schon gesagt steht auch beim Asm-Programmieren öfter die
Entscheidung an: Platz oder Speed. Das entscheidet man von Fall zu Fall.
Hier geht es aber erst mal drum, welchen Vorsprung Asm zu Hochsprachen
hat...
Johann L. schrieb:> Z.B dein Code für den LM335:
Schön daß Du ihn analysiert und in C codiert hast (bin immer noch nicht
durch) aber ich will an dieser Stelle nochmal darauf hinweisen, daß
diese relativ langweilige kurze Sequenz gar nicht zur Diskussion stand!
Zur Diskussion stand das Entprellprogramm samt Erfassung der
Tastenbetätigungsdauer für beliebige IO-Pin Tasten und der beschriebenen
Funktionalität... und das steht es immer noch. Zur Diskussion stehen
auch alle meine neueren Programme in der Codesammlung. So schwer sind
die doch nicht zu verstehen!
Johann L. schrieb:>> 1. 32-Bit Arithmetik ist keine AVR/ASM Stärke.>> Das ist doch Käse.
Das ist kein Käse weil diese Aussage auf 32-Bit und C gemünzt war.
Carl D. schrieb:> Aber wie immer: große Klappe, nix tun!
Och Carl D., war heute auch fleißig. Vielleicht entdeckst Du was Neues
von mir in der Codesammlung ??? Wo steckt da eigentlich Dein Name ???
Moby A. schrieb:> Und hab gelernt daß alle ach so vereinfachende Abstraktion und> hochsprachliche Seiltänzerei zumindest über dem 8-Bit Hardware-Abgrund> eine böse Kehrseite hat.
Und die böse Kehrseite wäre da welche?
Moby A. schrieb:> Zur Diskussion stand das Entprellprogramm samt Erfassung der> Tastenbetätigungsdauer für beliebige IO-Pin Tasten und der beschriebenen> Funktionalität... und das steht es immer noch.
Dann guck doch mal Yalu X's Beitrag von 11:44 an ( Link:
Beitrag "Re: C versus Assembler->Performance" )
Wie du siehst ist das C-Programm kürzer und flexibler als dein
ASM-Geraffel.
Kaj G. schrieb:> 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? :)
Den Titel beanspruche ich für mich sicher nicht.
Hobby ist Hobby. Der Fokus liegt auf MSR-Lösungen für den Heimbereich.
Das Wissen langt, um dort alles Gewünschte umzusetzen.
> Und die böse Kehrseite wäre da welche?
Intransparenz.
Ausdruckskomplexität.
Sprachmittelkomplexität.
Sprachkonstruktionskomplexität.
Compilerkonfiguritis.
Um nur mal 5 Details der bösen Kehrseite zu nennen.
Verlange nun nur nicht das jetzt nochmal zu erläutern ;-)
Torben H. schrieb:> Dann guck doch mal Yalu X's Beitrag von 11:44 an ( Link:> Beitrag "Re: C versus Assembler->Performance" )>> Wie du siehst ist das C-Programm kürzer und flexibler als dein> ASM-Geraffel.
Sorry- soweit war ich noch gar nicht mit dem Beantworten...
Yalu X. schrieb:> "Angebot" angenommen ;-)
Danke. Das werde ich mir noch gesondert zu Gemüte führen.
Spekuliere nicht damit daß ich der Sache nicht zugrunde gehe ;-)
Moby A. schrieb:>> Und die böse Kehrseite wäre da welche?> Intransparenz.
Wenn man gerne wissen will was da bit für bit vorgeht, hindert einen
-auch wenn man in C programmiert- niemand daran das ASM-Listing, den
AVR-Instruction Set und die Mikroarchitektur anzusehen
> Ausdruckskomplexität.> Sprachmittelkomplexität.> Sprachkonstruktionskomplexität.
So komplex wie du immer predigst ist C überhaupt nicht. Wenn du wüstest
wovon du redest wäre dir das auch schon lange öaufgefallen.
> Compilerkonfiguritis.
Ich verstehe schon, dass es einem Angst machen kann wenn ein Compiler
mit ein paar Flags besseren Code als du in hochgelobten, handoptimiertem
ASM erzeug, deswegen ist es aber noch lange nicht böse.
Rea L. schrieb:> So komplex wie du immer predigst ist C überhaupt nicht. Wenn du wüstest
Ja ja ich weiß schon. Verlass Dich drauf. Schon dieser Thread zeigt
einige Beispiele.
Eigentlich brauche ich mich dazu auch nur an mein erstes und einziges
C-Programm für die DOS-Kommandozeile erinnern ;-(
Wieviele C-Programmierer die hier klug daherreden können eigentlich Asm?
Wissen die Möglichkeiten dort überhaupt einzuschätzen?
Moby A. schrieb:> Wieviele C-Programmierer die hier klug daherreden können eigentlich Asm?> Wissen die Möglichkeiten dort überhaupt einzuschätzen?
Alle!
Wobei: 'daherreden' ist natürlich abwertend. Also daherreden tut hier
keiner von den C-Programmierern.
Moby A. schrieb:> Ausdruckskomplexität.> Sprachmittelkomplexität.> Sprachkonstruktionskomplexität.
Das ist Blödsinn, und das weißt du.
C hat ca. 1/3 der Schlüsselwörter von dem AVR-Asm-Instruktionen, und
über x86-Asm brauchen wir da mal gar nicht reden. Von Komplexität kann
in C nicht wirklich die Rede sein.
Natürlich kann man in C unglaublich komplexen Code schreiben, das geht
in Asm aber genauso gut.
Der Grund, weshalb du Hochsprachen ablehnst, ist der selbe Grund,
weshalb sehr viele Leute (besonders hier in Deutschland) "Angst" vor
autonomen Fahrzeugen haben: Der Verlust von Kontrolle (die man gar nicht
braucht) und das eingestehen, dass jemand anderes (der Compiler bzw. die
Compilerbauer bzw. die Technik) besser sind, als man selbst. Dieses "Ich
bin der perfekte Autofahrer" ist ein Irrglaube, und das ist bei Dir und
Asm nicht anders.
Der Kassiererin vertraust du doch auch, das sie deine Ware richtig über
die Kasse zieht, oder ziehst du deine Sachen selber über die Kasse? Und
ob sie es richtig gemacht hat, kannst du kontrollieren, anhand des
Kassenbons, so wie du den Compiler kontrollieren kannst, anhand des
Listings.
Wo ist dein Problem, zu akzeptieren, das die Compilerbauer besser sind
als du?
Du hängst dich dann an kleinigkeiten auf, wo der Compiler Deiner
Meinung nach, nicht optimialen Code erzeugt hat. Das schöne daran: Es
ist deine Meinung. Wenn du was an dem erzeugten Code auszusetzen hast,
dann frag doch mal die Compilerbauer, was die sich da gedacht haben und
reich einen Patch ein. Die würden sich da bestimmt drüber freuen und dir
die Füße küssen.
Ebenso wurde bei dir ja auch, wenn es nach der Meinung anderer geht,
nicht optimaler Code gefunden... Warum ist das in deiner Welt ok, wenn
du das verbrochen hast, es ist aber nicht ok, wenn der Compiler das
macht?
Oder ist es einfach deine Sturheit, "ich mach schon immer Asm, was
anderes braucht ich nicht, was neues lern ich nicht"?
Würd mich mal interessieren, ob du überhaupt schon mal versucht hast,
eine von deinen Aufgaben in C zu lösen. Und wenn das Ergebnis vom
Compiler ja ach so schlecht gewesen sein soll, dann zeig doch mal bitte
den entsprechenden C-Code, zusammen mit dem verwendeten Compiler und der
Compilerversion usw.
Ich bin mir sicher, das würde hier alle beteiligten interessieren...
Aber nein, du wirst wieder abwiegel (so wie immer): Ist ja alles nur
Hobby, und Hochsprachen haben ja ihre berechtigung, außer im MC bereich,
und du wirst Code zeigen, wenn die Zeit gekommen ist, bla bla.
Kaj G. schrieb:> Du hängst dich dann an kleinigkeiten auf,
"Ach, der will nur spielen!", wollt' ich gerade sagen... ;-)
Das ist nur Schaumschlägerei.
Da gibt's einen oben schon mal erwähnten Thread, wo einer ein paar
Probleme bei der Ansteuerung eines LCD in Assembler hat. Ursache: Als
Anfänger sieht man da einfach nicht durch, was man alles ändern soll,
wenn man zur Steuerung mal fix ein paar Pins wechselt. Von Moby keine
Spur. Wo ist das Problem, einfach mal zu erklären, was da zu beachten
ist? Ich warte einfach mal. Auf meine Hinweise muss der TO dort leider
noch ein bisschen warten...
Moby A. schrieb:> Wieviele C-Programmierer die hier klug daherreden können eigentlich Asm?
Ich kann beides
> Wissen die Möglichkeiten dort überhaupt einzuschätzen?
Nicht nur dass, ich weiß auch wann es sinnvoll ist.
> Eigentlich brauche ich mich dazu auch nur an mein erstes und einziges> C-Programm für die DOS-Kommandozeile erinnern ;-(
Ich kann mich auch noch an mein erstes ASM Programm erinnern:
Status-Bits, LDI geht nur für die halben Register, bedingte Sprünge,
manuelles PUSH/POP... viel zu kompliziert.
Wenn ich nicht weitergemacht hätte wäre das bis heute mein Bild von ASM.
Moby A. schrieb:> Ralf G. schrieb:>> Moby A. schrieb:>>> Dir ist es lieber hier>>> rumzustänkern ;-)>>>> Da ist was Wahres dran ;-)
Du hast diesen ';-)' gesehen?
Als ich das geschrieben habe, habe ich noch geglaubt, mit etwas
Provokation dich wachzurütteln. Ich dachte wirklich, du merkst es mal,
dass du dich hier zum Affen machst. Wollte dich nur vor Schlimmerem
bewahren. Ich hatte mich geirrt!
Rea L. schrieb:> Nicht nur dass, ich weiß auch wann es sinnvoll ist.
Diese Sinnhaftigkeit hängt auch davon ab, über welche Codebasis man
verfügt.
> Ich kann mich auch noch an mein erstes ASM Programm erinnern:> Status-Bits, LDI geht nur für die halben Register, bedingte Sprünge,> manuelles PUSH/POP... viel zu kompliziert.> Wenn ich nicht weitergemacht hätte wäre das bis heute mein Bild von ASM.
Also ist dieses Bild von Asm jetzt positiver. Freut mich.
Schau, dieses Werkzeug langt für MC völlig aus. Die Zeit und Mühe zum
Beherrschenlernen von C und anderer Weiterentwicklungen kann allein in
die eigentlichen Projekte fließen.
Moby A. schrieb:> Also ist dieses Bild von Asm jetzt positiver. Freut mich.
Ja, nur schade dass du diese Erfahrung mit C nie machen durftest :-(
> Die Zeit und Mühe zum Beherrschenlernen von C
war's eindeutig wert. Auf dem PC ist ASM sowieso keine sinnvolle Option
und die Zeit habe ich durch den Verzicht auf ASM-Frickelei wenn's nicht
notwendig war um ein Vielfaches wieder reingeholt.
PS: Wenigstens weiß ich jetzt, dass ich und viele Anderen hier
wahrscheinlich auch uns in Sachen C von Mobby nichts sagen lassen
müssen.
Ich finde es interessant, wie/wenn Einer viele Andere an der langen
Leine um sich herumtanzen lassen kann. Solche Egozentriker kenne ich
auch. Ich meide sie.
Moby A. schrieb:> Die Zeit und Mühe zum Beherrschenlernen von C und anderer> Weiterentwicklungen kann allein in die eigentlichen Projekte fließen.
Und nun stell' Dir mal vor, Du müsstest auf eine andere µC-Architektur
umsteigen. Aus welchem Grund auch immer. Kein AVR mehr.
Stell' Dir also vor, Du müsstest jetzt plötzlich mit MSP430, PIC oder
ARM zurechtkommen.
In Assembler.
Wer C benutzt, und gar einen C-Compiler, der für diverse
µC-Architekturen existiert, wie z.B. gcc, der muss sich in so einer
Situation natürlich auch umstellen, weil er andere, anders aufgebaute
Peripherie ansteuern muss, und weil er möglicherweise Dingen wie der
Harvard-Architektur entrinnen kann, und er wird ein anderes
Programmiergerät bzw. ein anderes Debuginterface verwenden lernen
müssen, aber davon abgesehen kann er seine in das Beherschenlernen von C
gesteckte Zeit einfach weiterverwenden.
Du hingegen musst zusätzlich auch noch die komplett andere
Maschinenarchitektur, den anderen Befehlssatz, die anderen
Registersätze, gegebenenfalls die andere Assemblersyntax und die ganzen
kleinen ekligen Eigenheiten der neuen µC-Architektur lernen müssen. Und
algorithmisch umdenken müssen; MSP430 ist eine 16- und ARM sogar eine
32-Bit-Architektur, wo Dinge komplett anders laufen können.
Da ist Dein "selbsterklärender" AVR-Assemblercode vollkommen wertlos.
Gut, die Wahrscheinlichkeit, daß Atmel in absehbarer Zeit damit aufhören
wird, 8-Bit-AVRs herzustellen, die ist überschaubar; aber es könnte ja
auch sein, daß Du aus beruflichen Gründen mit µCs arbeiten musst. Und
da wird Dir üblicherweise vom Arbeitgeber vorgegeben, womit Du
arbeiten musst.
Auch der Umstieg von einem C-Compiler auf einen komplett anderen (gcc zu
IAR) ist keine unüberwindbare Hürde -- die Programmiersprache selbst
bleibt nämlich die gleiche, nur ein paar Rahmenbedingungen ändern sich.
> Eigentlich brauche ich mich dazu auch nur an mein erstes und einziges
C-Programm für die DOS-Kommandozeile erinnern
Das ist so wie wenn der Papst dir was über Frauen erzählt.
Also nochmal es gibt was, was du nur rudimentär kennst, aber alle
anderen sind zu blöd deine Leuchtkraft zu verstehen.
Ein Fall für die Graukittel!
Rufus Τ. F. schrieb:> Und nun stell' Dir mal vor, Du müsstest auf eine andere µC-Architektur> umsteigen. Aus welchem Grund auch immer. Kein AVR mehr.
Das Schöne ist: Mein Hobby muß sich tatsächlich nicht an solchen
Vorstellungen orientieren ;-)
Rufus Τ. F. schrieb:> die ganzen> kleinen ekligen Eigenheiten der neuen µC-Architektur lernen müssen. Und> algorithmisch umdenken müssen; MSP430 ist eine 16- und ARM sogar eine> 32-Bit-Architektur,
... die im Falle von ARM sinnvollerweise nicht mit ASM programmiert
wird.
MSP430 soll diesbezüglich ja sehr entgegenkommend sein. Leider sind die
AVRs für das Meiste aber schon gut genug so daß ein Umstieg vor allem
eines wäre: Pure Zeitverschwendung.
Rufus Τ. F. schrieb:> aber es könnte ja> auch sein, daß Du aus beruflichen Gründen mit µCs arbeiten musst. Und> da wird Dir üblicherweise vom Arbeitgeber vorgegeben, womit Du> arbeiten musst.
Komplett andere Sachlage. Ja, da müsste ich wohl ob konkret sinnvoll
oder nicht mit anderen MCs arbeiten- und aus Gründen der dann nötigen
Portabilität auch mit Hochsprachen. So aber ist der Hobbyist in einer
komfortablen Lage: Er kann das Einfachste nehmen. Und dabei bleiben.
Rufus Τ. F. schrieb:> nur ein paar Rahmenbedingungen ändern sich
Nur ein paar Rahmenbedingungen?
Ja, solche Untertreibungen kenn ich auch aus eigener
Entwicklertätigkeit:
Meistens ist alles aufwendiger als man erst denkt ;-)
Lothar M. schrieb:> Solche Egozentriker
Im Zentrum meiner Beiträge steht was ganz anderes:
Keep it simple! Schon bemerkt?
Carl D. schrieb:> aber alle> anderen sind zu blöd deine Leuchtkraft zu verstehen.> Ein Fall für die Graukittel!
Geht es bei Dir nur noch auf diesem Niveau?
Ist Dir das Deine wertvolle Zeit am Sonntag wert?
Erstell mal mit Deiner Leuchtkraft, die ich bis jetzt nur Deinen Worten
entnehmen darf ein schönes Projekt! Bislang ist Dein Name in der
Projekteabteilung nur mit abwertenden Bemerkungen zu anderen Arbeiten
vertreten ;-(
Da ich mittlerweile denke, wer hier zuletzt postet, hat gewonnen
(Argumente scheinen genug ausgetauscht worden zu sein), fasse ich mich
kurz mit:
DAGEGEN
(Goil, ich kann jetzt sinus auf'm AVR)
Jemand eine Ahnung warum es im Atmel Studio 6.2 zum abgebildeten
Compilierfehler kommt, wenn das C-Executable Projekt im Netzwerk (NAS)
liegt? Lokal funktionierts.
Hallo Yalu X., hier mal eine allererste Reaktion auf Deine
freundlicherweise erstellte Version meiner Tastenauswertung. Durchaus
ganz interessant, mal wieder in die C-Welt reinzuschauen, auch wenn sich
meine Begeisterung bislang in argen Grenzen hält.
Yalu X. schrieb:> - 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.
Damit wird eine wesentliche und beabsichtigte Funktion meiner Version
nicht erfüllt: Die ganze Tastenauswertung im Hintergrund zu halten.
Die ist im Timerinterrupt 1. recht schnell und 2. auch wenig
zeit-sensibel gegenüber Verzögerungen durch weitere (i.a. schnelle)
Interruptbehandlungen. Die Umsetzung als Hauptprogramm ist natürlich die
einfachere Variante- dieses sollte nun aber gerade komplett frei
bleiben. Ganz davon abgesehen, daß meine Hauptprogramm-unabhängige
Umsetzung schon allein 8 Instruktionen zur Registersicherung
verschlingt. Der Timerinterrupt enthält in meinen größeren Programmen
viele Service-Aufgaben, die ein Hauptprogramm dann nur noch
bedienen/anfordern muß.
> - Zudem erlaubt es diese Ablaufstruktur der CPU, sich während des> Nichtstuns zwischen zwei Timer-Interrupts schlafen zu legen und damit> Strom zu sparen.
Da im Hauptprogramm gar nix los ist kann "meine" CPU dort genauso
schlafen... Macht dann nochmal +3 Instruktionen.
> Wenn man> könnte man> Damit läge
Bitte keinen Illusionen hingeben: Da hätte ich für mein in zwei Stunden
entstandenen Programm auch noch so einige Ideen zum Verkleinern... ;-)
Moby A. schrieb:> Lothar M. schrieb:>> Solche Egozentriker> Im Zentrum meiner Beiträge
qed.
> Im Zentrum meiner Beiträge steht was ganz anderes:> Keep it simple!
Gerade wegen C kann ich Programmschnipsel unter den 5 Prozessorwelten
von 8 bis 32 Bit, in denen ich unterwegs bin, einfach austauschen. Und
Code, der z.B. auf einem alten 68332 uC schon seit 20 Jahren läuft,
einfach mal kurz auf einem STM32 oder auf einem AVR benchmarken. Das
ist für mich simpel...
Moby A. schrieb:> Bitte keinen Illusionen hingeben: Da hätte ich für mein in zwei Stunden> entstandenen Programm auch noch so einige Ideen zum Verkleinern... ;-)
Zeigen, nicht schwätzen.
Du bist ein Blender - nichts weiter.
Lothar M. schrieb:> Gerade wegen C kann ich Programmschnipsel unter den 5 Prozessorwelten> von 8 bis 32 Bit, in denen ich unterwegs bin, einfach austauschen.
Mir fehlt zwar nun jede Vorstellung, welchen Sinn ein solcher Austausch
denn haben könnte (doch nicht etwa nur Benchmarking?), aber wenn man den
braucht macht es C natürlich simpler. Gar keine Frage.
Wenn man seit Jahr und Tag mit einfachen AVRs auskommt sieht die Welt
ganz anders aus. Da wird der hier groß beworbene Portabilitäts-Vorteil
schlicht eines: Hinfällig!
Frank M. schrieb:> Zeigen, nicht schwätzen.
Für Dich gilt hier leider bislang nur letzteres ;-)
Moby A. schrieb:
> Lothar M. schrieb:>> Solche Egozentriker> Im Zentrum meiner Beiträge
Jetzt handelt es sich auch schon um eine multiple Persönlichkeit.
Wenn ich das lese, dann steht da "Horst S.".
Man erwirbt kein Eigentum an Beträgen die man sich ungefragt aneignet!
Carl D. schrieb:> Man erwirbt kein Eigentum an Beträgen die man sich ungefragt aneignet!
Richtig giftig kann er werden, der Carl D.
Wie hoch man doch Eigentumsfragen aufhängen kann ;-)
Gibt es nichts Wichtigeres für Dich heut abend?
Moby A. schrieb:> Mir fehlt zwar nun jede Vorstellung, welchen Sinn ein solcher Austausch> denn haben könnte
Meine ersten C Programme entstanden in den 80ern auf VAX, 68000 und
DOS-PC (davor waren es andere Sprachen), munter durcheinander. Dann kam
Inmos Transputer hinzu, in 16- wie in 32-Version, später diverse anderen
x86 Bitbreiten. Um nur die wichtigsten zu nennen. Bei einigen davon war
auch Assembler dabei, keine Sorge.
Manche C Programme und Programmteile migrierten in den Jahrzehnten durch
etliche dieser Systeme und auch durch etliche Betriebssysteme.
Mit den Mikrocontrollern waren dann AVR und ARM Original/Thumb/Thumb2
mit dabei, testweise auch mal 8-Bit und 16-Bit PICs. Auch hier ist mir
jedoch Assembler durchaus vertraut.
Kannst du dir vorstellen, dass Portabilität dabei einen Reiz hat?
A. K. schrieb:> Kannst du dir vorstellen, dass Portabilität dabei einen Reiz hat?
In dieser Gemengelage? Absolut. Da ist Portabilität ja geradezu
essentiell...
Wenngleich ich mir nicht vorstellen kann daß der über die Jahre
mitgeschleifte Code auf verschiedenen Architekturen immer gleichermaßen
"frisch" und effizient bleibt. Gerade bei hardwarenaher
MC-Programmierung.
Die krassteste Variante: Diplomarbeit zu Hause auf 68000 (32bit)
entwickeln und an der Uni sowohl auf DOS-PC (16bit) als auch Transputer
(32bit) zu Ende entwickeln und einsetzen.
Moby A. schrieb:> Gerade bei hardwarenaher MC-Programmierung.
Ich habe einen recht guten Sinn dafür, was bei C Code ungefähr hinten
rauskommt. Das ergibt sich von selbst, wenn du selber ein Bisschen an
Compilern rumgebaut hast.
Umgekehrt führt das freilich dazu, dass ich mir die häufiger genutzten
Architekturen etwas danach aussuche, wie gut sich C darauf abbilden
lässt. Ausreisser wie 8-Bit PIC (schaurig) sind da nur als Spass am
Rande beteiligt.
Moby A. schrieb:> Verständlich, ja. Nur, was hat das jetzt mit C vs. Asm auf AVR zu tun?
Es ist immer das gleiche C. Aber jedesmal ein anderes Asm.
Da hat man dann beispielsweise eine Funktion rprintf() für formatierte
Zahl/Stringausgabe, die ein stark eingedampftes printf() darstellt und
viel weniger Platz braucht. Auf allen µC-Plattformen der gleiche Code.
A. K. schrieb:> Umgekehrt führt das freilich dazu, dass ich mir die häufiger genutzten> Architekturen etwas danach aussuche, wie gut sich C darauf abbilden> lässt.
Und da kommen sicher auch die AVRs in Frage...
A. K. schrieb:> Es ist immer das gleiche C. Aber jedesmal ein anderes Asm.
Auf verschiedenen Architekturen.
Deren Notwendigkeit für viele Zwecke diskutabel ist.
Moby A. schrieb:> Und da kommen sicher auch die AVRs in Frage...
Ja. Nicht ohne Kritik freilich, denn die der Sprache C fremde
Adressraumtrennung ging mir angesichts des recht hässlichen Ersatzcodes
mächtig auf den Senkel. Erst in neuerer Zeit wurde das besser (dank
__flash).
Diese in Programmen jenseits der kleinen Tinys unbefriedigende Situation
führte mich dann auch zu dem ARM Varianten, ab ARM7/LPC2000. Mit eigenem
Startup-Code in Asm um bei Interrupts weniger Zirkus in C zu haben.
War ein Projekt dabei, das ich mit 2 kooperierenden µCs implementierte,
Mega32 in C und Tiny2313 in Assembler. Asm deshalb, weil ich beides
dabei haben wollte.
>> Es ist immer das gleiche C. Aber jedesmal ein anderes Asm.> Auf verschiedenen Architekturen.
Ja, gleicher Quellcode.
> Deren Notwendigkeit für viele Zwecke diskutabel ist.
Ich habe keinen Horror vor neuen Architekturen. Ist sogar andersrum -
immer die gleiche Basis langweilt mich und als Hobbyist kann ich mir
diese Neugierde leisten.
Moby A. schrieb:> Durchaus ganz interessant, mal wieder in die C-Welt reinzuschauen,> auch wenn sich meine Begeisterung bislang in argen Grenzen hält.
Wenn ich ganz ehrlich bin, habe ich auch gar keine Begeisterungsstürme
von dir erwartet ;-)
> Damit wird eine wesentliche und beabsichtigte Funktion meiner Version> nicht erfüllt: Die ganze Tastenauswertung im Hintergrund zu halten.> Die ist im Timerinterrupt 1. recht schnell und 2. auch wenig> zeit-sensibel gegenüber Verzögerungen durch weitere (i.a. schnelle)> Interruptbehandlungen.
Die Tastenentprellung an sich braucht nicht viel Zeit, das ist richtig.
Aber die keypress-Funktionen, die du daraus aufrufst, können durchaus
etwas aufwendiger werden, wenn sie in einer realen Anwendungen über das
bloße Ein- und Ausschalten von ein paar LEDs hinausgehen.
Ein sinnvoller Kompromiss wäre, die Entprellung und die Messung der
Dauer in der Interruptroutine und den Rest im Vordergrund laufen zu
lassen.
Aber auch in der vorliegenden Form erfüllt mein Programm eine Vorgaben,
die da lauten:
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.
Die Funktionalität ist die gleiche wie bei deinem Programm, die
Unterschiede liegen nur in der Art und Weise der Implementierung.
> Ganz davon abgesehen, daß meine Hauptprogramm-unabhängige Umsetzung> schon allein 8 Instruktionen zur Registersicherung verschlingt.
Die Registersicherung ist unnötig, da im Hauptprogramm nach dem
Aktivieren des Interrupts nur eine Leerschleife ausgeführt wird. Um
wirklich hauptprogrammunabhängig zu sein, genügt es auch nicht, die
Register einfach nur in andere Register umzukopieren, da diese ja
genauso vom Hauptprogramm überschrieben werden können. Die einzig
wirklich unabhängige Registersicherung ist die auf den Stack.
Um aber vergleichbare Verhältnisse zu schaffen, darfst du von deinen 266
Bytes die 16 Bytes für die Registersicherung abziehen. Damit liegst
jetzt mit 250 zu 256 Bytes wieder knapp vorn. Zufrieden?
> Da im Hauptprogramm gar nix los ist kann "meine" CPU dort genauso> schlafen... Macht dann nochmal +3 Instruktionen.
Ah, damit musst du natürlich wieder 6 Bytes hinzuaddieren, und es steht
jetzt final
1
256 : 256
also unentschieden.
Ich kann mit diesem Ergebnis sehr gut leben, du auch?
Und Moby, jetzt mal ganz unter uns: Selbst wenn das C-Programm 300 oder
gar 400 Bytes belegen würde, würde ich einen Teufel tun, es in Assembler
umschreiben. Denn die 400 Bytes sind gerade einmal lausige 5% des
Flash-Speichers des ATmega88. Mit den restlichen 95% kann man in C noch
so viele nützliche Dinge erledigen, an die du als Assemblerprogrammierer
gar nicht zu denken wagst, weil das deine Arbeitsweise schlicht und
ergreifend nicht hergibt.
Aber Programme in dieser Größenordnung sind ja deiner Ansicht nach
sowieso keine "typischen 8-Bit-Anwendungen" mehr und sollten deswegen
gar nicht erst in Erwägung gezogen werden ;-)
Und dass man für eine halben Euro mehr einen ATmega168 mit der doppelten
und für einen ganzen Euro mehr sogar einen ATmega328 mit der vierfachen
Flash-Kapazität bekommt, kann nur auf einen Fehler der Produktmanager
bei Atmel zurückzuführen sein.
Mach einfach weiter so, wie du es schon immer getan hast, und vermeide
es geflissentlich, irgendetwas Neues dazuzulernen, aber versuche bitte,
bitte nicht immer wieder, auch andere von dieser Lebensphilosophie zu
überzeugen.
A. K. schrieb:> Ist sogar andersrum -> immer die gleiche Basis langweilt mich und als Hobbyist kann ich mir> diese Neugierde leisten.
Genau das allerdings ist absolut legitim.
Genau das kann man problemlos akzeptieren.
Mein Punkt ist aber ein ganz anderer:
Mich interessiert zuerst die simple Lösung.
Erst dann die Wege dahin.
Fazit: AVR und Asm reichen (noch lange).
Da steckt jede Menge Power drin.
A. K. schrieb:>> Und da kommen sicher auch die AVRs in Frage...>> Ja. Nicht ohne Kritik freilich,
Atmel nehme ich beispielsweise persönlich übel, dass sie bis heute
keinen Befehl für atomare Manipulation des Stackpointers eingebaut
haben. Das ist geradezu Sabotage an C, wenn man nicht grad IAR heisst
und Var-Stack und Return-Stack trennt.
Moby A. schrieb:> Lothar M. schrieb:>> Gerade wegen C kann ich Programmschnipsel unter den 5 Prozessorwelten>> von 8 bis 32 Bit, in denen ich unterwegs bin, einfach austauschen.> Mir fehlt zwar nun jede Vorstellung, welchen Sinn ein solcher Austausch> denn haben könnte
Entwicklung und Test auf dem PC und anschließender Einsatz auf einem
68332 uC ist sinnvoll.
Es gibt eben mitnichten nur 1 uC Familie und wenn man eine portable
Programmiersprache kennt, dann traut man sich eher mal einen Wechsel auf
einen, der optimale Ressourcen mitbringt. Und zwängt sich und sein
Design nicht unbedingt in die einzige uC Familie deren Assembler man
gerade kennt...
Yalu X. schrieb:> genügt es auch nicht, die> Register einfach nur in andere Register umzukopieren, da diese ja> genauso vom Hauptprogramm überschrieben werden können.
Das ist eine Frage der Konvention. R10-R15 sind für schnelle
Interruptbehandlung reserviert. Und ich habe diese "minderwertigeren"
Register auch noch nicht vermisst. Stacksicherung kostet Flash, RAM und
dauert.
> Ein sinnvoller Kompromiss wäre, die Entprellung und die Messung der> Dauer in der Interruptroutine und den Rest im Vordergrund laufen zu> lassen.
Du mußt die von mir angestrebte totale Unabhängigkeit von solchen
"Serviceaufgaben" etwas weiter gefaßt sehen. Als Konzept, was Aufgaben
trennt, Nebenwirkungen beseitigt, Übersichtlichkeit schafft. Was weniger
auf Ressourcensparung denn aufs Möglichmachen komplexerer Programme
abzielt.
> Ich kann mit diesem Ergebnis sehr gut leben, du auch?
Natürlich nicht, weil da noch eine Menge drin ist.
Ich möchte allerdings Deine Zeit auch nicht unnötig in Beschlag nehmen.
Eine weiter optimierte Version kommt auf alle Fälle noch in die Projekte
und Dein Programm wird auf Herz und Nieren geprüft. Die einzige
C-Kreatur, die je meine AVR Flash-Speicher bevölkerte ;-)
> Mit den restlichen 95% kann man in C noch> so viele nützliche Dinge erledigen, an die du als Assemblerprogrammierer> gar nicht zu denken wagst, weil das deine Arbeitsweise schlicht und> ergreifend nicht hergibt.
Sinn und Zweck des Programmierens ist nicht, 100% vollzucodieren,
sondern mit Asm viel Platz für a) Erweiterungen und b) Daten aller Art
zu haben oder vielleicht mit einem kleinen Tiny statt Mega
auszukommen...
> Aber Programme in dieser Größenordnung sind ja deiner Ansicht nach> sowieso keine "typischen 8-Bit-Anwendungen" mehr und sollten deswegen> gar nicht erst in Erwägung gezogen werden ;-)
Wo hast Du die Größenbeschränkung typischer 8-Bit Anwendungen
aufgeschnappt?
Meine größte hat 18KB optimierten Reincode und leistet eine Menge. Das
ist längst noch nicht vollendet bzw. problemlos erweiterbar.
> auch andere von dieser Lebensphilosophie zu> überzeugen.
Hier gehts nicht um Lebensphilosophie sondern Fakten, Fakten, Fakten.
>Hier gehts nicht um Lebensphilosophie sondern Fakten, Fakten, Fakten.
Nein Moby. Die ignorierst Du.
>Sinn und Zweck des Programmierens ist nicht, 100% vollzucodieren,>sondern mit Asm viel Platz für a) Erweiterungen und b) Daten aller Art>zu haben oder vielleicht mit einem kleinen Tiny statt Mega>auszukommen...
Cleverer aus Deiner Sicht wäre es gewesen, mindestens das "mit Asm"
wegzulassen.
Aber trotzdem. Diese Aussage war sehr interessant. Wenn ein µC eine
bestimmte Funktion übernehmen soll, geht es dir als Ziel darum ASM zu
nutzen. Ok.
Allen anderen hier geht es darum, diese Funktion mit möglichst geringem
zeitlichen Aufwand umzusetzen.
Das ist der Unterschied und deshalb wirst du die Vorteile von
Hochsprachen (egal welche) nie verstehen. Du hast ja zugegeben, das du
deine Zeit damit verplemperst, Schleifen in asm selbst zu bauen, anstatt
einfach for(...) hinzuschreiben und zu wissen, das funktioniert.
Das erklärt auch diese Aussage:
>> Ich kann mit diesem Ergebnis sehr gut leben, du auch?>Natürlich nicht, weil da noch eine Menge drin ist.>Ich möchte allerdings Deine Zeit auch nicht unnötig in Beschlag nehmen.>Eine weiter optimierte Version kommt auf alle Fälle noch in die Projekte
Welchen sinnvollen Grund gäbe es, da noch weiter rumzufrickeln? Das
Programm tut was es soll, es passt in den Flash und fertig. Wenn jetzt
zwei Bytes weniger vom Flash verwendet wurden... wen interessierts?
A. K. schrieb:> die der Sprache C fremde Adressraumtrennung
Witzigerweise gab es die PDP-11 ja auch mit "Split I&D", was damals
den effektiven Adressraum (pro Task) verdoppelt hat. So fremd ist
das also eigentlich für C gar nicht …
Problem beim AVR ist ja nur, dass konstante Daten auf diese Weise
sowohl Platz im RAM als auch Flash brauchen würden. Das war bei der
PDP-11 nicht so das Thema, denn an welcher Stelle der Platte nun die
vorzuladenden Konstanten liegen, ist da ziemlich schnuppe.
Jörg W. schrieb:> Witzigerweise gab es die PDP-11 ja auch mit "Split I&D", was damals> den effektiven Adressraum (pro Task) verdoppelt hat.
Konnte man auf der PDP-11 explizit Daten im I-Space adressieren? Denn
nur dann wäre das vergleichbar.
Andernfalls hat man damit nur das normale und unproblematische AVR
Datenmodell, bei dem alle Daten im RAM liegen und ggf. vom Startupcode
aus dem Flash ins RAM kopiert werden. Oder eben vom Loader des
Betriebssystem aus dem Exe-File in den D-Space.
Trennung von Funktions- und Datenadressen war nie ein Problem. Mehrere
getrennte Datenadressräume aber schon.
Ja, schon klar, das Problem beim AVR entsteht ja nur dadurch, dass
alle Konstanten naturgemäß in einem der beiden Adressräume liegen
müssen (im Flash), und dass es daher wünschenswert ist, sie gleich
in diesem Adressraum als Daten ansprechen zu können.
Trotzdem ist es natürlich allemal kurios, dass C eigentlich auf einer
Harvard-Maschine gewachsen ist, sie uns (aufgrund der Randbedingungen)
dennoch beim AVR dann so viele Bauchschmerzen bereitet.
Jörg W. schrieb:> Meiner Erinnerung nach gab es ein "move from previous instruction> space" oder dergleichen … yep:
Nur sind diese Befehle eigentlich dafür gedacht, den Useradressraum
durch Kernelcode ansprechen zu können.
Ausserdem lese ich in einem Handbuch von 1979: "When MFPI is executed
and both previous mode and current mode are User, the instruction
functions as though it were MFPD.". MFPI ist demzufolge nicht
geeignet, um in User-Programmen auf den eigenen I-Space zuzugreifen.
A. K. schrieb:> MFPI ist demzufolge nicht geeignet, um in User-Programmen auf den> eigenen I-Space zuzugreifen.
Ah, OK. Solche Details waren mir nicht mehr bewusst. Damit ist
natürlich klar, dass für ein normales User-Programm in der Tat beide
Adressräume völlig getrennt waren.
Jörg W. schrieb:> Trotzdem ist es natürlich allemal kurios, dass C eigentlich auf einer> Harvard-Maschine gewachsen ist, sie uns (aufgrund der Randbedingungen)> dennoch beim AVR dann so viele Bauchschmerzen bereitet.
Das Problem ist ja weniger die Harvard-Architektur an sich, sondern beim
AVR die Harvard-Architektur in Kombination mit der Verwendung des
Programmspeichers als alleinigen nichtvolatilen Speicher (neben dem
EEPROM, das sich aber ebensowenig für direkte Datenzugriffe eignet).
Bei einem klassischen Computer sind beide Adressräume mit RAM belegt,
und die nichtvolatilen Daten werden von einem externen Massenspeicher
geladen. Damit belegen die Const-Daten in den CPU-Adressräumen nur
einmal Platz. Dass diese Daten zusätzlich auch noch Platz auf dem
Massenspeicher brauchen, stört nicht so sehr.
Moby A. schrieb:> Karl H. schrieb:>> Aber erst mal muss er den Fehdehandschuh aufgreifen. Mal sehen, obs so>> kommt wie es immer kommt, wenn ich sowas anbiete :-)>> Den greife ich natürlich nicht auf, weil ich für solche Späße keine Zeit> investiere.
Schade. Mit handfesten konkreten Argumenten hätte ich mich überzeugen
lassen :-)
Aber eigentlich hab ich auch nichts anderes erwartet.
> Ja, da müsste ich wohl ob konkret sinnvoll oder nicht mit anderen> MCs arbeiten- und aus Gründen der dann nötigen Portabilität auch> mit Hochsprachen. So aber ist der Hobbyist in einer komfortablen Lage:> Er kann das Einfachste nehmen. Und dabei bleiben.
Nur ist aber gerade für eine Hobbyisten Assembler nicht "das
Einfachste". Es gibt viel zu viele Fallstricke, in denen er sich
stunden- oder tagelang verfangen kann, und die ihm ein Compiler locker
und problemlos abnehmen kann. Du widersprichst dir ständig selbst und
merkst es noch nicht einmal.
Du du gefragt hast, wer hier aller Assembler kann:
So ziemlich die meisten der regelmässig hier Helfenden. Meiner einer
inklusive. Ist zwar schon teilweise lange her, aber Z80, IBM360, VAX,
68000 und (no, na) AVR Assembler ist keineswegs wie du zu denken
scheinst, ein Buch mit 7 Siegeln. Die meisten, die heute Hochsprachen
einsetzen können passabel bis gut Assembler. Und gerade weil sie das oft
und lange genug gemacht haben, benutzen sie heute eine "Hochsprache".
Wobei man diskutieren kann, an welcher Stelle der Skala "Assembler ->
Hochsprache" C tatsächlich anzusiedeln ist.
Ist schon lustig: auf der einen Seite lehnst du jegliche Demonstration
der vermeintlichen Vorteile ab, weil du die Zeit dafür nicht hast. Und
auf der anderen Seite lehnst du alle Hilfen ab, die dir massiv Zeit in
der Entwicklung einsparen könnten ohne dass du etwas dafür bekommst.
Ich hab hier im Forum schon so manchem sein Programm mehr oder weniger
brennfertig geschrieben. Das geht, weil ich das zwischen ein paar
Compilerläufe in meiner eigentlichen Arbeit einschieben kann. In
Assembler würde ich das nie machen, weil das (wie du richtig sagst) viel
zu zeitaufwändig und auch viel zu fehleranfällig wäre.
Und da gehst noch nicht mal darum, irgendeine Behauptung mit Fakten zu
stützen oder zu beweisen, sondern rein um den Spass an der Freude.
Komisch: die C Programmierer können das, die Assembler Programmierer
anscheinend nicht. Zumindest hat sich noch nie ein militanter
Assembler-über-alles Verfechter auf einen derartigen Wettstreit
eingelassen. Ob uns das was sagen sollte?
Karl H. schrieb:> Komisch: die C Programmierer können das, die Assembler Programmierer> anscheinend nicht.
Weils einfach viel zu viel Arbeit ist, sich in ein ellenlanges (fremdes)
Assembler-Programm einzulesen, um es zu verstehen, den Fehler zu finden
und es darüber hinaus auch noch zu fixen.
> Zumindest hat sich noch nie ein militanter> Assembler-über-alles Verfechter auf einen derartigen Wettstreit> eingelassen. Ob uns das was sagen sollte?
Er weiß genau, dass er verliert.
Frank M. schrieb:> Er weiß genau, dass er verliert.
Gewonnen hat zuallererst eins: Die funktionierende Lösung.
An den Vorteilen von Asm gibts nichts zu deuteln.
Karl H. schrieb:> Schade. Mit handfesten konkreten Argumenten hätte ich mich überzeugen> lassen :-)
Wie scheinheilig ;-)
Du hast nämlich auch so die Möglichkeit das Gegenteil zu beweisen.
Da war ein anderer Mod hier aber ehrlicher.
> Aber eigentlich hab ich auch nichts anderes erwartet.
Nun, ich auch nicht.
> Nur ist aber gerade für eine Hobbyisten Assembler nicht "das> Einfachste". Es gibt viel zu viele Fallstricke, in denen er sich> stunden- oder tagelang verfangen kann, und die ihm ein Compiler locker> und problemlos abnehmen kann.
Also ich hab mehr Overhead in Gestalt von Compilern und und den vielen
Hochsprachelementen in der AVR-Entwicklung nie vermisst.
> Du du gefragt hast, wer hier aller Assembler kann:> So ziemlich die meisten der regelmässig hier Helfenden. Meiner einer> inklusive.
Dann auf gehts Karl Heinz.
In der Codersammlung wartet schon mein nächstes Projekt.
Das ist eine wirklich ganz ganz einfache Ausgabe eines seriellen
Datenstroms. Mach das kürzer. Mach es schneller.
So hocheffizient und zeitsparend die C-Entwicklung ja sein soll- dann
ist das doch schnell erledigt!
> Ist schon lustig: auf der einen Seite lehnst du jegliche Demonstration> der vermeintlichen Vorteile ab, weil du die Zeit dafür nicht hast.
Diese Deine Demonstration lehne ich gewiss nicht ab und auch Mod Yalus
Programm ist mir eine genaue Analyse wert.
> Zumindest hat sich noch nie ein militanter> Assembler-über-alles Verfechter auf einen derartigen Wettstreit> eingelassen. Ob uns das was sagen sollte?
Also erstens bin ich nicht militant sondern ein äußerst friedfertiger
Mensch. Zum anderen läuft Dein großspuriger Wettstreit auf die bloße
Demo von Zeitersparnis und ggf. noch ein paar Asm-Rechenschwächen
hinaus.
Daß die Demonstration von Codeersparnis und mehr Speed idealerweise
zugunsten von Asm ausfallen muß wirst auch Du wissen. Ggf. spekulierst
Du aber noch mit ein paar meiner Flüchtigkeitsfehler ;-)
Moby A. schrieb:> In der Codersammlung wartet schon mein nächstes Projekt.> Das ist eine wirklich ganz ganz einfache Ausgabe eines seriellen> Datenstroms. Mach das kürzer. Mach es schneller.
Sag mal, willst Du uns verarschen? Was hast Du an Nicht-Blink-LED-Level
nicht verstanden?
Kanst Du nur solche Micky-Maus-Programme, die keiner braucht?
Frank M. schrieb:> Sag mal, willst Du uns verarschen? Was hast Du an Nicht-Blink-LED-Level> nicht verstanden?>> Kanst Du nur solche Micky-Maus-Programme, die keiner braucht?
Ich merk schon auf dieses Deine Niveau und diese Deine Absichten ist es
nicht weiter wert einzugehen. Vermutlich ist Dir Dein IRMP zu Kopf
gestiegen... Warte mal auf mein nächstes Projekt. Da wird gezeigt wie
eine simple IR-Ausgabe ausschauen kann ;-)
>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>zugunsten von Asm ausfallen muß wirst auch Du wissen
Das hat auch nie jemand hier bestritten.
>Mach das kürzer. Mach es schneller.
Das ist in Hochsprachen ganz einfach. Wärend da einfach
1
uint16_tu16Loop=0;
2
while(u16Loop<12345)
3
{
4
..
5
u16Loop++;
6
}
in zehn Sekunden hingeschrieben ist, benötigst Du wielange dafür? Ein
Testen der reinen Schleife ist auch nicht nötig. Sie funktioniert dank
Compiler immer, egal wie das Konstrukt "Schleife" beschaffen ist. Du in
ASM musst viel Zeit investieren, um die Infrastruktur (die Schleife)
erstmal zu erzeugen und zum laufen zu bekommen. GEschweige denn, das was
in der Schleife geschehen soll.
"höhere" Hochsprachen wie C#/C++ gehen ja noch weiter und bieten ein
1
foreach(arrray...)
2
{}
wo über ein komplettes Array iteriert werden kann. Egal wie das Array
beschaffen ist. Schaffst Du das auch in ASM in zwei Sekunden
hinzuschreiben, was über jedes beliebige Array läuft, egal welchen
Typs/Länge das Array hat?
Moby A. schrieb:> Daß die Demonstration von Codeersparnis und mehr Speed idealerweise> zugunsten von Asm ausfallen muß wirst auch Du wissen.
??? Kapier ich nicht, das ist doch hier jetzt des öfteren widerlegt
worden. Langsam wirst du albern.
Moby A. schrieb:> Warte mal auf mein nächstes Projekt. Da wird gezeigt wie> eine simple IR-Ausgabe ausschauen kann ;-)
Ich hoffe, Du verstehst unter einer "simplen IR-Ausgabe" nicht, dass Du
nun eine IR-LED statt einer normalen LED blinken lässt. Das wäre nicht
witzig, sondern eher ein Witz.
Also: Korrekte Modulation und ein echter IR-Code (z.B. NEC), mit dem man
ein real existierendes Gerät schalten kann? Das ist schon interessanter.
Muss mich hier im Augenblick wieder verabschieden...
Nicht gleich als Rückzug missverstehen Karl Heinz ;-)
Melde mich später wieder und gehe auf weitere Beiträge ein. Der
Diskussionsbedarf scheint endlos ;-(
Moby A. schrieb:> Warte mal auf mein nächstes Projekt.
Nö, Moby. Wir warten nicht, sondern machen inzwischen lieber an
unseren eigenen, nicht-simplen Projekten weiter. Vielleicht finde
ich ja endlich mal Zeit, die Bediensteuerung meiner PTS250 zu Ende
zu bekommen. Die Backends (Ansteuerung eines VFD, Ansteuerung einer
kleinen Matrixtastatur, Ansteuerung der PTS250 selbst über
speicheradressierte parallele Schieberegister) sind alle schon da,
aber die Bedienerführung braucht noch ein bisschen Gehirnschmalz,
bevor man überhaupt ans Programmieren gehen kann.
900ss D. schrieb:> Moby A. schrieb:>> Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>> zugunsten von Asm ausfallen muß wirst auch Du wissen.>> ??? Kapier ich nicht, das ist doch hier jetzt des öfteren widerlegt> worden. Langsam wirst du albern.Matthias L. schrieb:>>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>>zugunsten von Asm ausfallen muß wirst auch Du wissen>> Das hat auch nie jemand hier bestritten.
So, das musste noch sein ;-)
Moby A. schrieb:> Matthias L. schrieb:>>>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>>>zugunsten von Asm ausfallen muß wirst auch Du wissen>>>> Das hat auch nie jemand hier bestritten.>> So, das musste noch sein ;-)
Und den Rest ignorierst Du mal wieder?
Matthias L. schrieb:> Und den Rest ignorierst Du mal wieder?
Er liest nur das, was er lesen will. Die Rosinen - auch wenn sie stinken
wie die Pest - reichen ihm.
Matthias L. schrieb:>>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>>zugunsten von Asm ausfallen muß wirst auch Du wissen>> Das hat auch nie jemand hier bestritten.
Verstehe ich nicht Matthias. Ist doch hier bewiesen worden, dass C-Code
sogar kürzer sein kann. Nur in den aufgeführten Beispielen, kann man
natürlich nicht für alle Fälle annehmen.
Moby A. schrieb:> So, das musste noch sein ;-)
Ja der Widerspruch ist natürlich ein gefundenes Fressen für dich. Ist
irgendwie billig, aber gönn ich dir. :-)
Trotzdem ist eine pauschale Aussage bzgl. Codegröße einfach quatsch.
Aber ich will da mal lieber nicht näher drauf eingehen Moby, du siehst
nur, was du sehen willst. Machst dir aber sicher das Programmier-Leben
schwer, was du natürlich nicht weißt, weil du die "anderen" Seite nicht
kennst und deshalb nicht beurteilen kannst. Dass du C nicht verstehst
und du deshalb ASM bevorzugst, weil du auch keine Zeit investieren
willst, C zu verstehen, ok ist deine Entschweidung. Aber deine Mission
hier ist deshalb auch wirklich über und dir fehlt dafür die Kompetenz.
Nimm das Beispiel von Yalu oben und arbeite es durch. Du wirst viel
lernen und vielleicht bringt es dich dahin, das C auch für deine
Projekte durchaus eine gute Wahl sein könnte.
Nein, wir hier brauchen ASM nicht lernen, wie schon beschrieben, können
es die meisten ausreichend gut (ich auch).
Jörg W. schrieb:> sondern machen inzwischen lieber an unseren eigenen, nicht-simplen> Projekten weiter.
Ich mache aber auch kurz mal zwischendurch ein simples Programm... ;-)
Moby A. schrieb:> Daß die Demonstration von Codeersparnis und mehr Speed idealerweise> zugunsten von Asm ausfallen muß wirst auch Du wissen.
Und wenn dieses Ideal vom Assemblerprogrammierer nicht erreicht wird,
weil der Assemblerprogrammierer schon nicht ideal programmieren kann?
Oder wenn mehr Speed bedeutet, einen Tag/Woche/Monat früher und damit
rechtzeitig fertig zu sein?
> Daß die Demonstration von Codeersparnis und mehr Speed idealerweise> zugunsten von Asm ausfallen muß wirst auch Du wissen.
Klar stimmt das, weil sogar das optimalste C Programm, das sogar besser
ist als das beste vom Assemblerprogrammierer programmierte
Assemblerprogramm, leicht in Assembler überführt werden kann.
Und damit wäre für diesen überoptimalen C-Compiler bestenfalls
Gleichstand erreichbar, weil es ja immer ein gleich gutes
Assemblerprogramm gibt.
Ergo: dieses Argument ist unsinnig.
Lothar M. schrieb:> Ergo: dieses Argument ist unsinnig.
Yep. Man muss die Frage etwas anders formulieren: Nicht ob in C kürzere
Programme erstellt werden können als in Asm, sondern ob C-Programmierer
kürzere oder schnellere Programme zustande bringen als
Asm-Programmierer. Also Asm-Programmierer, die nicht klammheimlich Code
vom Compiler abschreiben. ;-)
A. K. schrieb:> Yep. Man muss die Frage etwas anders formulieren: Nicht ob in C kürzere> Programme erstellt werden können als in Asm ...
Ich würde in diese Frage unbedingt einschließen, wer schneller fertig
ist, und ob jemand anders den geschriebenen Code nachvollziehen und
ändern/anpassen/ergänzen/erweitern kann.
Denn darum geht es im richtigen Leben. Was bringt mir der optimalste
Code, wenn das Programm erst nach Markteinführung fertig ist, oder wenn
ich nach dem Weggang des Programmierers das Programm neu schreiben muss?
Matthias L. schrieb:>>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>>zugunsten von Asm ausfallen muß wirst auch Du wissen>> Das hat auch nie jemand hier bestritten.
Ja das Potential hat ASM freilich, aber zu welchen Preis? Das man mit
ASM nicht automatisch das bessere oder gar das beste Ergebnis erzielt,
hat dieser Thread eindeutig bewiesen. Nein, dazu braucht man Erfahrung,
leider kann bei ASM gelerntes Wissen nicht einfach so auf andere
Architekturen Übertragen, und man muss eine Menge Arbeit hineinstecken.
Für mich persönlich stimmt da einfach nicht mehr das Kosten/Nutzen
Verhältnis, auch als Hobbyist der die Zeit hätte. Mit C bin ich
schneller fertig und der Frustfaktor ist geringer. Mit dem Compiler kann
ich ohnehin kaum mithalten. ASM wird erst wieder interessant, wenn ich
wirklich alles aus der Maschine rausholen muss. Wie z.B. wenn der AVR
ein BAS Signal generieren muss (Zeitkritisch, Takte zählen!) oder wenn
der x86 Bootloader noch in die 420 Byte des ersten Sektors (FAT32)
passen muss. Das hat seinen Reiz. Aber wenn es darum geht ein paar Cent
für den nächst größeren µC zu sparen ist mir das einfach zu blöd (wenn
Hochsprache gleich größerer Ressourcenverbrauch überhaupt gelten würde).
Früher dachte ich immer Moby wäre ein Experte in Sachen ASM und arbeitet
an anspruchsvollen Projekten, wo jedes Byte und jeder Takt zählt. Denn
dann wäre seine Einstellungen noch irgendwo nachvollziehbar, auch wenn
er eine Menge Unsinn über Hochsprachen behauptet. Doch dann lässt er
sich bei dem 32-Bit Vergleich vom Compiler locker schlagen und sagt
sowas wie "Überlaufrumärgern ist mir bislang fremd." etc. . Da kommt mir
der Eindruck, dass die Komplexität seiner Programme gegen Null
konvergiert. Das endet dann in völliger Unverständnis, wenn man sich
ansieht, was er die letzten Jahre hier alles so für Aussagen und
Behauptungen abgelassen hat. Er verlangt immer Fakten, doch schafft er
selbst keine, höchstens welche die gegen ihn sprechen.
Über die Code-Geschwindigkeit kann man in Ausnahmefällen ja noch
streiten, aber über die Codegröße? In meinen Programmen macht der
eigendliche Code vielleicht 30% aus, der Rest sind Texte, Fonts,
Graphiken, etc. Ob der Code dann am Ende 25% oder 35% ausmacht, ist
sowas von irrelevant.
Was die Wiederverwertbarkeit angeht: wenn ich eine Graphik-Lib für ein
128*64-LCD habe und dieses auf ein320*240-LCD portieren will, dann
ändere ich in C den Index von uint8_t auf uint16_t. In Asm darf ich im
besten Fall die komplette Lib neu schreiben. Im schlechtesten nicht,
weil mein Chef mich vorher entlässt.
Als ich vor ca. 15 Jahren von Asm auf C umgestiegen bin, da war das eine
Erleuchtung. Die Rate der schweren Fehler ist schlagartig um 90%
gesunken, und die Produktivität ist extrem gestiegen. Daß das nicht nur
mir so geht, kann man selbst in diesem Thread sehen, siehe Mobys
Asm-Beispiel.
Sehr merkwürdig finde ich immer wieder, daß nur noch Hobby-Programmierer
die Asm-Fahne hochhalten. Wenn ich alle Monate einen Chip brauche, dann
ist es mir egal, ob ich den xxx8kbyte oder den yyy16kbyte für 0.25€ mehr
einkaufe. In der Industrie, wo es oft um hohe Stückbzahlen geht, würde
dagegen niemand im Traum auf die Idee kommen, in Asm zu schreiben, um
damit <vielleicht> kleineren Code zu produzieren.
Gruß, Stefan
Christopher C. schrieb:> Er verlangt immer Fakten, doch schafft er selbst keine, höchstens welche> die gegen ihn sprechen.
Dabei wäre es ja ein Leichtes gewesen, passend zum Thema des Threads
Horst mit einem optimierten Assemblerprogramm zu helfen, für das
es ja immerhin schon eine Vorlage gab. :) Aber nein, stattdessen
lässt er sich die Butter vom Brot nehmen, indem Horst bereits nach
5 Stunden eine C-Version seines Codes hat, die 10 % unter seiner
alten Assemblerversion im Codeverbrauch liegt …
Das frustrierende an Asm ist doch:
Kleine Programme bekommt man wirklich sehr gut hinoptimiert. In einigen
Fällen sogar heute noch besser als mancher C-Compiler.
Werden die Programme richtig komplex, dann verliert man schnell den
Überblick: welche Register zerstört die Funktion xyz? In welchen
Registern wird welcher Wert übergeben? Wird der Stack vor dem
Funktionsende wieder korrekt freigeräumt?
Im Ergebnis sinkt die mögliche Optimierung bei Asm mit größer werdendem
Programm immer mehr. Der C-Compiler optimiert dagegen immer gleich gut.
Gruß, Stefan
Moby A. schrieb:> Warte mal auf mein nächstes Projekt. Da wird gezeigt wie> eine simple IR-Ausgabe ausschauen kann ;-)
Formuliere doch schon mal die Anforderungen für Dein nächstes Projekt,
zum Beispiel so:
Aufgabe: Senden eines IR-NEC-Frames
Plattform: AVR-µC: ATTiny25/45/85
PWM-Pin: PB0, also OC0A
Modulation: 38kHz
IR-Protokoll: NEC, IR-Adresse 0xFF, Kommando-Code 0xA0
Stefan K. schrieb:> Werden die Programme richtig komplex, dann verliert man schnell den> Überblick: welche Register zerstört die Funktion xyz? In welchen> Registern wird welcher Wert übergeben? Wird der Stack vor dem> Funktionsende wieder korrekt freigeräumt?
Wobei man sich das in einem Assemblerprojekt genauso definieren
könnte, wie es ein C-Compiler halt machen muss.
Ich habe auch schon größere Assemblerprojekte hier gesehen, vor deren
Komplexität ich durchaus den Hut ziehe (Heizungs-Thermostat-Steuerung),
aber irgendwo verkriecht sich halt da drin noch eine kleine Wanze oder
zwei, aber die zu suchen gleicht einer Suche nach der Nadel im
Heuhaufen.
Jörg W. schrieb:> Wobei man sich das in einem Assemblerprojekt genauso definieren> könnte, wie es ein C-Compiler halt machen muss.
Klar, wobei z.B. eine Funktionsdefinition in C selbsterklärend ist. In
Asm musst Du in der Doku nachsehen, daß R15 der X-Index und R14 der
Y-Index ist, und R13/R12 von der Funktion zerstört werden. Sprich: Asm
ohne Kommentare geht gar nicht, gut geschriebenes C kommt an den meisten
Stellen auch ohne Kommentare aus.
Um Asm sicher zu coden, musst Du einfach viel mehr Aufwand treiben. Und
gerade den sehe ich bei vielen Asm-Propheten leider gar nicht.
Viele Grüße, Stefan
Stefan K. schrieb:> Asm musst Du in der Doku nachsehen, daß R15 der X-Index und R14 der> Y-Index ist,
In einem guten Assembler kannst du wahlweise global oder innerhalb der
Asm-Funktion Registern auch Namen geben.
Wenn du R15 jetzt "X_Index" taufst, musst du aber trotzdem noch wissen,
daß du R15 nicht einfach für etwas anders nehmen solltest :-)
Um in einem großen Programm so etwas im Griff zu haben, muss man schon
Profi sein, und da gibt es hier nur einen!
Klaus W. schrieb:> Wenn du R15 jetzt "X_Index" taufst, musst du aber trotzdem noch wissen,> daß du R15 nicht einfach für etwas anders nehmen solltest :-)
Wenn man das macht, dann sollte man für den Bereich der benannten
Register keine Originalregisterbezeichnung verwenden. Entweder man
verwendet darin konsequent logische Namen, oder direkt die Register.
Dieser Bereich ergibt sich per Konvention. Ohnehin blickt man bei
grösseren Programmen nur noch durch, wenn man klarstellt, welche
Register überhaupt von Unterprogrammen verändert werden dürfen, da passt
das gut mit hinein.
Natürlich ist der Umfang an Detaildoku in Asm wichtiger. Aber man kann
auch Asm-Programmierung mit geeigneten Werkzeugen deutlich erleichtern,
sowohl in Form eines geeigneten Assemblers wie auch durch Knowhow. Wobei
Atmel verständlicherweise nicht sehr viel Aufwand in den Assembler
investiert. Der wird von der Systemphilosophie her nur für kleine
Programme benötigt.
Umgekehrt stellt die Notwendigkeit zu systematischem und übersichtlichem
Vorgehen eine Chance des Compilers dar. Der hat diese Zwänge nicht in
gleichem Masse und kann strunzschaurigen aber effizienten Code
generieren, solange er funktioniert. Ein Asm-Programmierer, der später
noch durchblicken will, der wird das eher vermeiden wollen.
A. K. schrieb:> Klaus W. schrieb:>> Wenn du R15 jetzt "X_Index" taufst, musst du aber trotzdem noch wissen,>> daß du R15 nicht einfach für etwas anders nehmen solltest :-)>> Wenn man das macht, dann sollte man für den Bereich der benannten> Register keine Originalregisterbezeichnung verwenden. Entweder man> verwendet darin konsequent logische Namen, oder direkt die Register.
Kann man machen.
Dann landest du aber bei nicht-kleinen Programmen auch recht schnell in
der Situation, dass die Register nicht mehr reichen.
Solange man Programmgrößen hat, in denen alles in sein jeweils eigenes
Register passt und noch ein paar zur freien Verwendung übrig bleiben,
geht das ja noch. Nur ist das Ende dieser Fahnenstange recht schnell
erreicht.
Mir scheint Moby hatte noch nie den Fall, mal etwas Größeres zu
programmieren.
Karl H. schrieb:> Mir scheint Moby hatte noch nie den Fall, mal etwas Größeres zu> programmieren.
Tja, ist halt nicht nötig bei "typischen" Anwendungen :-)
Falls doch, hast du halt nur die falschen Probleme!
Karl H. schrieb:> Mir scheint Moby hatte noch nie den Fall, mal etwas Größeres zu> programmieren.
Deshalb schrieb ich ja: Mobys Mikrokosmos. Da ist die Welt noch einfach.
Eine Ameise schleppt Blätter auf den eigenen Schultern. Wofür braucht
man da einen Schubkarre oder gar einen LKW? Sie könnte damit auch gar
nichts anfangen.
Karl H. schrieb:> Dann landest du aber bei nicht-kleinen Programmen auch recht schnell in> der Situation, dass die Register nicht mehr reichen.
Kannst das auch mit Variablen auf dem Stack so halten, wenn zu wenig
Register.
Aber auch hier ist der Compiler im Vorteil, weil er die
Registerverwendung innerhalb einer Funktion variieren kann. Also für
verschiedene Variablen das gleiche Register verwenden kann, je nachdem
wie häufig die Var an welcher Stelle der Funktion genutzt wird. Bei
Asm-Programmierung läuft man dann in Gefahr, den Überblick zu verlieren.
Jörg W. schrieb:> Moby A. schrieb:> Warte mal auf mein nächstes Projekt.>> Nö, Moby. Wir warten nicht,
Du warst doch gar nicht angesprochen.
> sondern machen inzwischen lieber an unseren> eigenen, nicht-simplen Projekten weiter. Vielleicht finde ich ja> endlich mal Zeit, die Bediensteuerung
Natürlich. Da sollte und muß man Prioritäten haben.
Deshalb lasse ich mich auch nicht auf irgendeinen Wettkampfquatsch ein
wenn konkrete Angebote längst auf dem Tisch liegen.
> braucht noch ein bisschen Gehirnschmalz, bevor man überhaupt ans> Programmieren gehen kann.
Ein ganz wichtiger Gesichtspunkt: Die Sache bis zum Ende durchdenken
bevor es ans Programmieren geht.
900ss D. schrieb:> Ja der Widerspruch ist natürlich ein gefundenes Fressen für dich. Ist> irgendwie billig, aber gönn ich dir. :-)
Das ist nicht billig sondern ganz symptomatisch für eine Diskussion, die
die Vorteile von Asm auf Teufel komm raus und mit allen Mitteln
abzustreiten sucht.
Spätestens beim nächsten Experten, der lange Erfahrung (wobei auch
immer) als Argument an sich angibt, allerspätestens aber wenn es nur
noch zu abwertenden Bemerkungen (unter der Gürtellinie) langt, dann kann
das jeden, der erfolgreich mit Asm unterwegs ist, eigentlich nur
nachdrücklichst bestätigen ;-)
Moby A. schrieb:> Dann auf gehts Karl Heinz.> In der Codersammlung wartet schon mein nächstes Projekt.> Das ist eine wirklich ganz ganz einfache Ausgabe eines seriellen> Datenstroms.
Du meinst das hier
1
systemint6: sbrc SIC,0
2
rjmp systemint8 ;Clock H->L
3
4
lsl A2HO3 ;DATABIT-OUTPUT
5
rol A2LO2
6
rol A1LO1
7
brcs systemint7
8
cbi PORTB,0
9
rjmp systemint8
10
systemint7: sbi PORTB,0
11
12
systemint8: sbi PINB,2 ;Clock generation
13
systemint9: inc SIC
14
15
ireturn: reti
Ja, hast du schön gemacht.
> Mach das kürzer. Mach es schneller.
:-)
Das gesteh ich dir gerne zu, dass das so nicht geht.
Aber jetzt mach du mal dasselbe mit einer Ausgabe von 40 Bytes.
Und wenn wir schon dabei sind: ich hätte gerne 32 Samples pro
Mittelungs-Durchgang und nicht 8
na wie schnell hast du die Änderung gemacht?
> So hocheffizient und zeitsparend die C-Entwicklung ja sein soll- dann> ist das doch schnell erledigt!
Ist hier doch gar nicht notwendig. Ob das Ding ein paar Takte mehr oder
weniger braucht, interessiert doch keinen. Ist doch sowieso Timer
gesteuert.
A. K. schrieb:> Aber auch hier ist der Compiler im Vorteil, weil er die> Registerverwendung innerhalb einer Funktion variieren kann. Also für> verschiedene Variablen das gleiche Register verwenden kann, je nachdem> wie häufig die Var an welcher Stelle der Funktion genutzt wird.
Das kann man mit Asm genauso.
Im Übrigen hat ein AVR ausreichend Register, um auch einen gewissen
Reservierungsumfang zu ermöglichen.
> Bei> Asm-Programmierung läuft man dann in Gefahr, den Überblick zu verlieren.
Läuft man mit einer gewissen Systematik eben nicht.
Dazu ist die AVR-Architektur zu einfach ;-)
Moby A. schrieb:>> Bei>> Asm-Programmierung läuft man dann in Gefahr, den Überblick zu verlieren.>> Läuft man mit einer gewissen Systematik eben nicht.> Dazu ist die AVR-Architektur zu einfach ;-)
Ach Moby.
Wir reden doch nicht von der Architektur.
Wir reden von Programmen, die vom Umfang her nicht mehr in die Kategorie
Micky Mouse fallen. Eben das, was bei uns täglich anfällt.
Programme, bei denen du deine 8 Variablen Größen nicht mehr in Registern
halten kannst. Programme, in denen auch mal eine Datenstruktur vorkommt.
Programme, die auch mal ein wenig flexibel anpassbar sein müssen - und
das ohne großen Aufwand.
Wie vorhin schon geschrieben: Ändere dein Programm mal um auf eine
andere Anzahl an Samples. Die Hälfte deiner Tricks in diesem Assembler
Programm bricht dann sofort zusammen. Mach mehr als 2 ADC Kanäle und
schon wieder hast du massive Änderungen.
Karl H. schrieb:> Das gesteh ich dir gerne zu, dass das so nicht geht.
Prima.
> Aber jetzt mach du mal dasselbe mit einer Ausgabe von 40 Bytes.> Und wenn wir schon dabei sind: ich hätte gerne 32 Samples pro> Mittelungs-Durchgang und nicht 8>> na wie schnell hast du die Änderung gemacht?
Langsamer als in C.
Deshalb gilt es die Anforderungen vorher zu durchdenken. Die
Flexibilität von C wird nun aber gerade mit der Tatsache erkauft, daß
der Code nicht so effizient an die Hardware angepasst ist und damit
größer ist / langsamer läuft als nötig.
Klar- dieser Nachteil muß nicht in jedem Projekt entscheidend sein. Aber
er ist vorhanden und darum geht es mir hier. Von meiner (subjektiven)
Abneigung gegen sprachgewaltige, komplex ausgedrückte abstrakte
Programmiererbevormundung mal ganz abgesehen.
> Ist hier doch gar nicht notwendig. Ob das Ding ein paar Takte mehr oder> weniger braucht, interessiert doch keinen. Ist doch sowieso Timer> gesteuert.
Das interessiert erstens durchaus, wenn noch mehr Funktionalität
hinzukommen soll und ich vielleicht bei meinen 128kHz Takt bleiben
möchte. Und zweitens steht für Erweiterungen mehr Platz zur Verfügung.
Hochsprache initiiert:
Man nehme einfach meht MHz...
Man nehme einfach einen größeren Flash...
Man wechsele einfach auf 32-Bit!
Ist doch so schön einfach...
Moby A. schrieb:>> na wie schnell hast du die Änderung gemacht?>> Langsamer als in C.
Siehst du. Genau darum gehts im wirklichen Leben.
> Deshalb gilt es die Anforderungen vorher zu durchdenken.
Da helfen dir die Anforderungen nicht viel.
Dieses Programm ist so spezifisch auf genau diese Aufgabenstellung
zugeschnitten, dass du bei der kleinsten Änderung alles wegwerfen
kannst.
> Die> Flexibilität von C wird nun aber gerade mit der Tatsache erkauft, daß> der Code nicht so effizient
Noch mal.
Die Effizenz interessiert keinen, solange es schnell genug ist. Du hast
nichts davon, wenn der µC 2 Takte früher mit der ISR fertig ist.
> er ist vorhanden und darum geht es mir hier. Von meiner (subjektiven)> Abneigung gegen sprachgewaltige, komplex ausgedrückte abstrakte> Programmiererbevormundung mal ganz abgesehen.
Es tut mir leid Moby.
Aber die meisten Programme sind nun mal nicht in der Kategorie, die du
hier immer wieder zum besten gibst. Die sind deutlich komplexer.
> Das interessiert erstens durchaus, wenn noch mehr Funktionalität> hinzukommen soll
wenn mehr Funktionalität hinzukommen soll, dann wirds aber mit deinen
Registern schnell ganz eng. Und das bedeutet: du musst umbauen.
Moby A. schrieb:> Das interessiert erstens durchaus, wenn noch mehr Funktionalität> hinzukommen soll
Sei Dir gewiss: Bei Dir kommt nicht mehr Funktionalität dazu.
> Und zweitens steht für Erweiterungen mehr Platz zur Verfügung.
Welche Erweiterungen? Dann wirds doch viel zu komplex für Dich...
> Hochsprache initiiert:> Man nehme einfach meht MHz...> Man nehme einfach einen größeren Flash...> Man wechsele einfach auf 32-Bit!
Das ist nur in Deinem kleinen Köpfchen so! Weißt Du eigentlich, dass es
auch ATmegas und nicht nur ATTinys mit 1KB Flash gibt?
> Ist doch so schön einfach...
In Newsgroups würde man Dich nun merkbefreit nennen. Seufz.
Karl H. schrieb:> Kategorie> Micky Mouse
ist eben nur in Asm realisierbar ;-)
Und mit etwas Systematik sehr viel mehr.
Das beste Pferd im Stall heißt hierfür AVR.
Karl H. schrieb:> Eben das, was bei uns täglich anfällt.> Programme, bei denen du deine 8 Variablen Größen nicht mehr in Registern> halten kannst. Programme, in denen auch mal eine Datenstruktur vorkommt.> Programme, die auch mal ein wenig flexibel anpassbar sein müssen.
Ja, flexibel sollte alles sein.
Genau das verursacht aber auch Aufwand und macht die Dinge
komplizierter. Deshalb: Anforderungen der konkreten App analysieren und
erst dann über die Umsetzung befinden.
Moby A. schrieb:> Hochsprache initiiert:> Man nehme einfach meht MHz...> Man nehme einfach einen größeren Flash...> Man wechsele einfach auf 32-Bit!> Ist doch so schön einfach...
Genau das bedeutet es eben nicht.
Auch nicht auf einem AVR
Nur weil man eine Hochsprache benutzt bedeutet das nicht, dass man
hirnlos an die Sache rangeht. Aber es bedeutet, dass ich mich nicht um
jeden Kleinkram selber kümmern muss. Das kostet manchmal ein wenig
Leistung, aber selten mehr als 5%. Und sobald die Programme größer
werden dreht sich das Verhätlnis oft sogar um. Denn dann kannst du als
Assembler Programmierer gar nicht mehr alles so ausnutzen (zumindest
nicht im überschaubaren Kostenrahmen), weil du in mehr als 20 Codeseiten
nicht mehr überblicken kannst, welche Register du an welcher Stelle
gefahrlos benutzen kannst und welche du wo pushen und popen musst. Mit
dem Effekt, dass du in Basisfunktionen immer alle temporären Register
pushen und popen wirst. Und genau dasselbe macht ein Compiler auch.
Du bist in einer Programmgröße unterwegs, wo du noch alles getrennt und
sauber in Register unterbringst. Das geht und das ist auch gut so. Aber
es bringt dir nichts, weil es niemanden interessiert, ob da ein paar
Takte mehr oder weniger drauf gehen.
Moby A. schrieb:> Karl H. schrieb:>> Kategorie>> Micky Mouse>> ist eben nur in Asm realisierbar ;-)
Micky Mouse geht auch in C. In einem Bruchteil der Zeit, die ein
ASM-Programmierer dafür braucht.
> Und mit etwas Systematik sehr viel mehr.
Zeig doch mal endlich! Zeig doch mal endlich ein Programm, dessen
Binärgröße über 1k bis 2k geht! Hast Du nicht, kannst Du nicht.
> Genau das verursacht aber auch Aufwand und macht die Dinge> komplizierter. Deshalb: Anforderungen der konkreten App analysieren und> erst dann über die Umsetzung befinden.
Es gibt Leute, die verschwenden bei Deinen kleinen Progrämmchen noch
nichtmals einen Gedanken für die Umsetzung. Was Du bereits "Projekt"
nennst, ist für andere C-Programmierer ein laues Lüftchen.
Moby A. schrieb:> Karl H. schrieb:>> Kategorie>> Micky Mouse>> ist eben nur in Asm realisierbar ;-)> Und mit etwas Systematik sehr viel mehr.> Das beste Pferd im Stall heißt hierfür AVR.>> Karl H. schrieb:>> Eben das, was bei uns täglich anfällt.>> Programme, bei denen du deine 8 Variablen Größen nicht mehr in Registern>> halten kannst. Programme, in denen auch mal eine Datenstruktur vorkommt.>> Programme, die auch mal ein wenig flexibel anpassbar sein müssen.>> Ja, flexibel sollte alles sein.> Genau das verursacht aber auch *Aufwand*
Es verursacht eben nicht Aufwand
Wenn ich in deinem Programm in C geschrieben ein
1
#define NR_SAMPLES 8
gegen ein
1
#define NR_SAMPLES 12
austausche, dann verursacht das eben keinen wirklichen Aufwand.
Der Compiler sucht sich bei
1
ADCSumme/=NR_SAMPLES;
dann schon die richtige Methode raus, um das sauber umzusetzen. Da
braucht niemand ein
1
lsr A1H ;AINP1SUM/8
2
ror A1LO1
3
lsr A1H
4
ror A1LO1
5
lsr A1H
6
ror A1LO1
schreiben. Hab ich NR_SAMPLES auf 8 gesetzt, dann wird der Compiler mit
einer ähnlichen Lösung kommen. Ist sie 12, dann benutzt er eine andere
Variante. Je nach Zahlenwert hat er Strategien mit, wie er die Division
umsetzt. Und zwar so, dass mich als Programmierer das überhaupt nicht
kümmern muss
> und macht die Dinge> komplizierter.
Auch nicht
Deine Systematik, mit der du in SIC einzelne Bits dazu benutzt um
festzustellen, in welcher Phase des Programmlaufs du dich gerade
befindest, das ist komplex und schwer zu warten. Wie gesagt: nimm 2
weitere ADC dazu und dein Programm bricht zusammen wie ein Kartenhaus.
Alles wegwerfen und neu anfangen lautet dann die Devise.
Karl H. schrieb:> wenn mehr Funktionalität hinzukommen soll, dann wirds aber mit deinen> Registern schnell ganz eng. Und das bedeutet: du musst umbauen.
Unfug. Du hast das unabhängige Bausteinprinzip noch nicht ganz
verstanden. Oder willst das nicht zur Kenntnis nehmen. Was glaubst Du
was man im noch gar nicht existenten Hauptprogramm so alles anstellen
könnte? Das läuft nämlich dann bewußt und wunderbar entkoppelt von der
schon vorhandenen Funktionaliät.
Moby A. schrieb:> Karl H. schrieb:>> wenn mehr Funktionalität hinzukommen soll, dann wirds aber mit deinen>> Registern schnell ganz eng. Und das bedeutet: du musst umbauen.>> Unfug. Du hast das unabhängige Bausteinprinzip noch nicht ganz> verstanden.
Ui.
So wie du programmierst, solltest du das Wort 'Baustein' lieber nicht in
den Mund nehmen.
> Oder willst das nicht zur Kenntnis nehmen. Was glaubst Du> was man im noch gar nicht existenten Hauptprogramm so alles anstellen> könnte? Das läuft nämlich dann bewußt und wunderbar entkoppelt von der> schon vorhandenen Funktionaliät.
SO.
Dann zeig mal.
Mach eine Tabelle rein, in der Uhrzeiten stehen und je nach Uhrzeit wird
eine von 2 Sets von ADC gesampelt. Von 6:00 Uhr bis 9:30 will ich den
ADC0 und den ADC3, von 9:30:01 bis 14:05:20 soll es ADC1 und ADC0 sein,
von 14:05:21 bis Mitternacht den ADC4 und den ADC5. Ich mach es dir
einfach und sage mal, es soll über den Tag verteilt 25 Zeiträume geben.
Karl H. schrieb:> SO.> Dann zeig mal.> Mach eine Tabelle rein, in der Uhrzeiten stehen und je nach Uhrzeit wird> eine von 2 Sets von ADC gesampelt. Von 6:00 Uhr bis 9:30 will ich den> ADC0 und den ADC3, von 9:30:01 bis 14:05:20 soll es ADC1 und ADC0 sein,> von 14:05:21 bis Mitternacht den ADC4 und den ADC5. Ich mach es dir> einfach und sage mal, es soll über den Tag verteilt 25 Zeiträume geben.
Und weils so schön ist, soll mit gleicher Zeittabelle (zusätzlicher
Eintrag) auch noch ein Ventil angesteuert werden.
Moby, wir alle haben schon Assembler programmiert. Durchwegs größere
Programme als so etwas. Und wir alle haben gesehen, dass man als
Programmierer mit seinen Fähigkeiten dann ganz schnell am Ende ist. Was
bei einem 200 Zeilen Programm noch funktioniert, geht bei 20000 Zeilen
dann eben nicht mehr. Das überblickt kein Mensch mehr in der Art und
Weise wie du das suggerierst: nämlich dass er jeden einzelnen
überflüssigen Taktzyklus herausoptimieren könnte. Ganz im Gegenteil,
ganz im Gegenteil. Compiler leisten da einen viel besseren Job als es
ein Mensch je könnte.
Matthias L. schrieb:> Moby ist in seiner Welt gefangen und kann nur innerhalb dieser> argumentieren.
Alles andere ist, per definitionem, „unnütz groß, 32 bit,
Verschwendung“. :-)
Dabei hat er immer noch nicht kapiert, dass der Thread damit begann,
dass innerhalb von gerade mal 5 Stunden das C-Programm 10 % kleiner
war als Horsts ursprüngliches Assemblerprogramm (welches er gewiss
nicht mit Absicht so schlecht geschrieben haben wird). Kein Moby war
da, etwas Vergleichbares mit dem Assemblercode zu tun um zu zeigen,
dass es in Assembler wirklich kleiner oder schneller geworden wäre.
Matthias L. schrieb:> Mittlerweile sollten wir alle verstanden haben, das es sinnlos> ist
... die offensichtlichen Vorteile von Asm in typischen 8-Bit Apps zu
bestreiten. Ganz richtig Matthias.
> Moby ist in seiner Welt gefangen und kann nur innerhalb dieser> argumentieren.
Wenn Du die Fokussierung auf die tatsächlichen Bedürfnisse solcher Apps
auf AVRs kleine Welt nennen willst dann mach das.
Karl H. schrieb:> Dann zeig mal.> Mach eine Tabelle rein, in der Uhrzeiten stehen und je nach Uhrzeit wird> eine von 2 Sets von ADC gesampelt. Von 6:00 Uhr bis 9:30 will ich den> ADC0 und den ADC3, von 9:30:01 bis 14:05:20 soll es ADC1 und ADC0 sein,> von 14:05:21 bis Mitternacht den ADC4 und den ADC5. Ich mach es dir> einfach und sage mal, es soll über den Tag verteilt 25 Zeiträume geben.
Für dieses Projekt sind schon hardwaremäßig nur 2 ADCs vorgesehen und
damit basta.
Eine Softwareuhr zu implementieren ist jedenfalls kein Problem. Je nach
Uhrzeit bestimmte Dinge zu erledigen auch nicht. Du kannst jetzt die
Anforderungen so hoch schrauben wie es Dir passt, um Deine hochgelobte
Flexibilität unter Beweis zu stellen.
Aber dazu noch was: Wer diese Flexibilität wirklich braucht hat die
eigentliche Aufgabe vorab nicht gründlich genug auf ihre Anforderungen
hin durchdacht ;-)
Jörg W. schrieb:> Kein Moby war da,
... um anderer Leute Arbeit zu erledigen?
Die C-Programmierer waren gefragt.
Und sie haben herausgefunden daß dieses Asm-Programm grottig
programmiert sein muß ;-)
Moby A. schrieb:> Für dieses Projekt sind schon hardwaremäßig nur 2 ADCs vorgesehen und> damit basta.
Ah ja.
Na wenn du das sagst.
Da sind noch ein paar Dinge drinnen
1
SYSTEMINT:movr18,SIC
2
movr17,SIC
3
andir17,$30
4
brnesystemint6
die $30 funktionieren nur, weil du genau 3 Bytes raustaktest.
Wenn ich auf mehr als 2 ADC bestehe, dann bricht auch der Teil der
Steuerung ob gemessen oder ausgegeben werden soll, in sich zusammen.
> Eine Softwareuhr zu implementieren ist jedenfalls kein Problem. Je nach> Uhrzeit bestimmte Dinge zu erledigen auch nicht.
Na dann mach.
4 verschiedene ADC, unterschiedliche Eingänge, Zeittabelle.
Das eine bringt dich in das Problem, das dir die Register ausgehen. Das
andere bringt dich in das Problem, dass deine ausgeknobelte Logik den
Bach runter geht.
Das allerdings muss ich dir lassen: die Logik in der ISR ist schon
ausgeknobelt.
> Du kannst jetzt die> Anforderungen so hoch schrauben wie es Dir passt, um Deine hochgelobte> Flexibilität unter Beweis zu stellen.
Tja. Profis müssen ihre Programme eben auch wartbar halten. Wenn auf
eine Änderung der Anforderungen ein 'und damit basta' kommt, dann bist
du deinen Job los.
> Aber dazu noch was: Wer diese Flexibilität wirklich braucht hat die> eigentliche Aufgabe vorab nicht gründlich genug auf ihre Anforderungen> hin durchdacht ;-)
Ich hab meine Anforderungen gründlich durchdacht. Und das hat zum
Ergebnis gebracht, dass ich 4 ADC Eingänge brauche und eine
Zeitsteuerung dazu. Da dein ASM-Programm ja so wunderbar funktioniert,
dachte ich eigentlich ich könnte das als Basis benutzen. Schliesslich
ist das ja der Sinn der Codesammlung, dass man dort Programme findet,
die obwohl sie nicht 100% auf die eigene konkrete Anforderung passen,
dann doch als Basis dienen können und leicht auf diese anpassbar sind.
Das funktioniert eigentlich mit fast allen Programmen. Nur scheinbar mit
deinen nicht. Wer nicht 100% dieselben Anforderungen hat wie du, der
steht dann im Regen. Oder wie? Ich würde eher sagen, das ist dann ein
wenig sinnlos. Denn wann hat schon jemand genau diese Anforderungen,
dass er 2 ADC plus 2 Eingänge hat, die er dann auch noch codiert in 3
Bytes getaktet übertragen muss. Und zwar GENAU so und nicht anders. Jede
kleinste Abweichung davon - Pech gehabt. Dann stehen massive Analysen
und Änderungen an.
Karl H. schrieb:> Moby, wir alle haben schon Assembler programmiert. Durchwegs größere> Programme als so etwas.
Größere Programme. Tatsächlich? Gibts sowas?
> Und wir alle haben gesehen, dass man als> Programmierer mit seinen Fähigkeiten dann ganz schnell am Ende ist.
Merkwürdig. Für alle typischen MSR Aufgaben die bei einer
Haussteuerung so anfallen langte mir bisher ein kleiner AVR mit Asm. Ob
das auch damit zusammenhängt, daß man viele ihrer Funktionen dezentral
realisiert?
Moby A. schrieb:> Merkwürdig. Für alle typischen MSR Aufgaben die bei einer> Haussteuerung so anfallen langte mir bisher ein kleiner AVR mit Asm.
Tja. Och weiss ja nicht, was du unter Haussteuerung verstehst.
Moby A. schrieb:> das auch damit zusammenhängt, daß man viele ihrer Funktionen dezentral> realisiert?
Wie willst du denn zb eine Heizungssteuerung, die auf
* Aussentemperatur
* Innentemperatur
* Vorlauftemperatur
* Uhrzeit
* Wochentag
* Temperaturprofile je nach Wochentag und Uhrzeit
aufbaut, samt Menüsteuerung, dezentralisieren?
Karl H. schrieb:> Moby A. schrieb:>>> das auch damit zusammenhängt, daß man viele ihrer Funktionen dezentral>> realisiert?>> Wie willst du denn zb eine Heizungssteuerung, die auf> * Aussentemperatur> * Innentemperatur> * Vorlauftemperatur> * Uhrzeit> * Wochentag> * Temperaturprofile je nach Wochentag und Uhrzeit> aufbaut, samt Menüsteuerung, dezentralisieren?
Edit: genau dafür könnte ich deine Sensorplatine gut brauchen.
Aussentemperatur, Innentemperatur, Vorlauftemperatur und Helligkeit
draussen per ADC messen und für die digitalen Inputs fällt mir auch noch
was ein :-)
Aber leider, leider. Geht ja nicht. Die Software ist dazu zu unflexibel.
Aber dafür ist sie schnell. Kein Taktzyklus wird verschwendet. Hilft mir
nur nichts. Werd ich mir doch in 10 Minuten ein C Programm dafür
schreiben müssen. Das verbraucht zwar pro ISR Aufruf 10 Takte mehr, aber
dafür kann ich mit 3 Tastendrücken noch einen 5ten ADC mit dazunehmen
und in 2 Jahren den Windsensor vom noch zu bauenden Wintergarten auch
noch anschliessen.
Karl H. schrieb:> die $30 funktionieren nur, weil du genau 3 Bytes raustaktest.>> Wenn ich auf mehr als 2 ADC bestehe, dann bricht auch der Teil der> Steuerung ob gemessen oder ausgegeben werden soll, in sich zusammen.
Da bricht gar nichts zusammen weil das genau so beabsichtigt ist.
> Eine Softwareuhr zu implementieren ist jedenfalls kein Problem. Je nach> Uhrzeit bestimmte Dinge zu erledigen auch nicht.>> Na dann mach.
Die wird hier nicht gebraucht (und wäre ohnehin umständlich zu stellen).
> 4 verschiedene ADC, unterschiedliche Eingänge
Hier gibt es:
2 ADU und 2 Digital-Eingänge. Nix anderes.
> Das eine bringt dich in das Problem, das dir die Register ausgehen.
Da geht höchstens irgendwann mal Flash und RAM aus.
> andere bringt dich in das Problem, dass deine ausgeknobelte Logik den> Bach runter geht.
Bitte versteh doch: Hard-und Software ist von Anfang an auf EIN Ziel
fokussiert. Ist das so schwierig? Deine Flexibilität erübrigt sich
damit. Meine Flexibilität besteht darin, im Rahmen dieser Gegebenheiten
weitere Funktionalität hinzuzufügen. Punkt und Aus und kein Problem.
> Tja. Profis müssen ihre Programme eben auch wartbar halten. Wenn auf> eine Änderung der Anforderungen ein 'und damit basta' kommt, dann bist> du deinen Job los.
Ja ja ist schon in Ordnung.
Ich verzichte aber im Rahmen typischer 8-Bit Apps auf Hochsprache. Die
muß hier ganz objektiv nicht sein. Damit nehme ich deren Nachteile nicht
in Kauf- und die Zeitersparnis relativiert sich durch Erfahrung und eine
große Codebasis.
> Ich hab meine Anforderungen gründlich durchdacht. Und das hat zum> Ergebnis gebracht, dass ich 4 ADC Eingänge brauche und eine> Zeitsteuerung dazu. Da dein ASM-Programm ja so wunderbar funktioniert,> dachte ich eigentlich ich könnte das als Basis benutzen.
Nein kannst Du nicht. Die ist für genau dieses Projekt und für nix
anderes (außer sich vielleicht was abzuschauen).
> Wer nicht 100% dieselben Anforderungen hat wie du, der> steht dann im Regen. Oder wie?
Ach was. Je zwei 10-Bit ADC und Digitaleingänge seriell über eine
längere Leitung zur Verfügung gestellt lassen sich doch vielseitig
nutzen.
Wenn ich mehr brauche denke ich daran vor dem Projekt-Design ;-)
> Wie willst du denn zb eine Heizungssteuerung, die auf> * Aussentemperatur> * Innentemperatur> * Vorlauftemperatur> * Uhrzeit> * Wochentag> * Temperaturprofile je nach Wochentag und Uhrzeit> aufbaut, samt Menüsteuerung, dezentralisieren?>> Edit: genau dafür könnte ich deine Sensorplatine gut brauchen.
Nö. Dafür ist sie aber nicht gedacht und gemacht.
Meine Güte. Dafür tut sie das wofür sie gut ist optimal und einfach.
> und in 2 Jahren den Windsensor vom noch zu bauenden Wintergarten auch> noch anschliessen.
Man merkt Dir an diesen Gedanken Deinen Jahrgang an. Entschuldige wenn
ich das so sage.
Das ist ja noch das alte Mainframe-Denken mit Zentral-CPU, um die sich
alle Sensorik und Aktoren zu scharen haben ;-)
Moby A. schrieb:> Hier gibt es:> 2 ADU und 2 Digital-Eingänge. Nix anderes.
Dann ist das Programm für 99,9% der typischen Anwender sinnlos.
Damit erfüllt es weder den Anspruch einer Weiterverwendung, noch hat es
etwas in der Codesammlung zu suchen, da für die Allgemeinheit
unbrauchbar. Ich plädiere daher dafür, dass ein Mod es aus der
Codesammlung verschiebt.
Und das witzigste daran: Es ist damit auch kein typisches
AVR-Programm, worauf Moby immer so pocht. Ein unbrauchbares Programm ist
lediglich ein Moby-Programm, aber keinesfalls eine typischeAVR-Anwendung.
Das ist einfach nur unverwertbarer Schrott.
Moby A. schrieb:> Wenn ich mehr brauche denke ich daran vor dem Projekt-Design ;-)
Schön.
Und andere denken eben in der Design Phase schon darüber nach, wie sie
eine im Rahmen bleibende Variationsmöglichkeit einbauen können, wenn sie
das zu moderaten Kosten bekommen können.
Frank M. schrieb:> Das ist einfach nur unverwertbarer Schrott.
Darf ich dann mein "grottiges" Programm in die Codesammlung als
"universeller Betrachter von PS2-Mausprotokollen auf'm PC" einstellen?
Und wenn ja, mach ich das dann in C oder in Assembler?
Moby A. schrieb:> Hier gibt es:> 2 ADU und 2 Digital-Eingänge. Nix anderes.
Und Mittelwert über 8 Samples.
Hast du vergessen. Ist ebenfalls ein integraler Bestandteil im Code, der
nicht so einfach tauschbar ist. Die ganze Taktung in der ISR baut darauf
auf.
Frank M. schrieb:> Das ist einfach nur unverwertbarer Schrott.
Da denke ich eher an solche unterirdischen Beiträge ;-(
Karl H. schrieb:> Und andere denken eben in der Design Phase schon darüber nach, wie sie> eine im Rahmen bleibende Variationsmöglichkeit einbauen können, wenn sie> das zu moderaten Kosten bekommen können.
Einverstanden.
Karl H. schrieb:> Und Mittelwert über 8 Samples.>> Hast du vergessen. Ist ebenfalls ein integraler Bestandteil im Code, der> nicht so einfach tauschbar ist. Die ganze Taktung in der ISR baut darauf> auf.
Das ist richtig. Und langt aus!
Moby A. schrieb:> Jörg W. schrieb:>> Kein Moby war da,>> ... um anderer Leute Arbeit zu erledigen?
Du hättest zumindest mal deine immer wieder proklamierten Vorzüge
der Assemblerprogrammierung unter Beweis stellen können.
> Die C-Programmierer waren gefragt.
Die waren im Gegensatz zu dir ja auch da. Ach so, nicht ganz korrekt:
du warst ja dann auch da, aber nur, um die Vorzüge zu proklamieren.
Nicht etwa, um wirklich was beizutragen, was Horst geholfen hätte.
> Und sie haben herausgefunden daß dieses Asm-Programm grottig> programmiert sein muß ;-)
Dummerweise haben sie ganz nebenbei auch noch rausgefunden, dass deine
ach so tollen Codeschnipsel, die du uns bislang präsentiert hast,
mindestens genauso grottig programmiert sind.
Horst S. schrieb:> Darf ich dann mein "grottiges" Programm in die Codesammlung als> "universeller Betrachter von PS2-Mausprotokollen auf'm PC" einstellen?
Wenn der Schwerpunkt auf "universell" liegt, warum nicht?
> Und wenn ja, mach ich das dann in C oder in Assembler?
Wenn beide Versionen laufen, kannst Du auf jeden Fall beide Versionen
einstellen. Dann hat jeder was davon.
Aber Programme, wo die Hardware-Anforderungen ans beschränkte Programm -
nur um total genial auszusehen - angepasst werden und nicht umgekehrt,
sind für die Allgemeinheit sinnlos und haben in der Codesammlung nichts
zu suchen.
Was nützt mir ein Taschenrechner, der nur 2 und 2 addieren kann, weil
man das total abgefahren in Assembler programmieren kann? Nichts.
Horst S. schrieb:> Darf ich dann mein "grottiges" Programm in die Codesammlung als> "universeller Betrachter von PS2-Mausprotokollen auf'm PC" einstellen?> Und wenn ja, mach ich das dann in C oder in Assembler?
Nicht Dein Programm als solches ist schlecht sondern die Asm-Version.
Bewusst falschverstanden?
Natürlich stellst Du nun die verbesserte C-Version in die Codesammlung.
Moby A. schrieb:> Frank M. schrieb:>> Das ist einfach nur unverwertbarer Schrott.>> Da denke ich eher an solche unterirdischen Beiträge ;-(
Sieh der Wahrheit einfach ins Auge: Ein nicht wiederverwendbares bzw.
nicht erweiterbares Programm ist nur für eine konkrete Konstellation
gedacht, die keine typische Anwendung ist. Damit ist es unbrauchbar.
Moby A. schrieb:> Aber dazu noch was: Wer diese Flexibilität wirklich braucht hat die> eigentliche Aufgabe vorab nicht gründlich genug auf ihre Anforderungen> hin durchdacht ;-)
Das kannst Du in Deinem Hobby zuhause sagen. Kunden, die Entwicklungen
in Auftrag geben, denken nicht so genau. Und wenn den dann einfällt,
Moby A. schrieb:> Hier gibt es:> 2 ADU und 2 Digital-Eingänge. Nix anderes.
Doch noch drei weitere ACUs und Digitaleingänge ergänzt werden müssen...
Was dann?
Alles neu Schreiben, wo bei C einfach die Arraygröße erhöht wird...
Frank M. schrieb:> Sieh der Wahrheit einfach ins Auge: Ein nicht wiederverwendbares bzw.> nicht erweiterbares Programm ist nur für eine konkrete Konstellation> gedacht, die keine typische Anwendung ist. Damit ist es unbrauchbar.
Ergänzung:
.... unbrauchbar für die Allgemeinheit.
Und der Rest.
Nun ja, sowas
1
ldi r16,8 ;SYSTEMINT-Init (TIMER 0 Compare INT)
2
out OCR0A,r16 ;ca.115 kHz / (SYSINT-Teiler 8+1
3
ldi r16,2 ; * Vorteiler 64)= ca.200Hz
4
out TCCR0A,r16
5
ldi r16,3
6
out TCCR0B,r16
7
ldi r16,4
8
out TIMSK0,r16 ;Enable Timer0 Compare-INT (SYSINT)
9
10
ldi r16,$22 ;PB5,PB1-> PULLUP!
11
out PORTB,r16
12
ldi r16,$5
13
out DDRB,r16 ;PB0,2-> OUTPUT!
14
15
ldi r16,$18 ;Init ADU
16
out DIDR0,r16
17
ldi r16,2
18
subi r16,AINP1REF
19
out ADMUX,r16
20
ldi r16,$e0
21
out ADCSRA,r16
22
23
ldi r16,$20
24
out MCUCR,r16 ;SLEEP Mode Enable
ist ein Beispiel dafür, wie man es nicht macht.
Ich wollte nichts sagen, denn sonst heisst es wieder ich lenke auf
'Kleinigkeiten' ab.
Und im übrigen hat Moby ja klar gemacht, dass seine Programme so zu
nehmen sind wie sie sind und davon wird keinen Millimeter abgewichen.
Horst S. schrieb:> Moby A. schrieb:>> Nicht Dein Programm als solches ist schlecht sondern die Asm-Version.>> Was genau ist an der Assembler-Version schlecht?
Du verbrauchst vier CPU-Takte und drei Bytes RAM mehr als Mobys perfekte
Lösung.
Jörg W. schrieb:> Du hättest zumindest mal deine immer wieder proklamierten Vorzüge der> Assemblerprogrammierung unter Beweis stellen können.
Die sind viel schneller und effektiver an den kleinen Sachen
demonstriert.
> Die waren im Gegensatz zu dir ja auch da.
... weil nicht sein kann was nicht sein darf?
Nein- im Ernst, mir fällt kein Zacken aus der Krone die vielen
Hilfswilligen einschließlich der Mods hier auch mal zu loben.
> Dummerweise haben sie ganz nebenbei auch noch rausgefunden, dass deine> ach so tollen Codeschnipsel, die du uns bislang präsentiert hast,> mindestens genauso grottig programmiert sind.
Nun ja, ich kenne ja die zugrundeliegenden Kriterien: Flexibilität und
Wartbarkeit ;-) Danke.
Horst S. schrieb:> Moby A. schrieb:>> Nicht Dein Programm als solches ist schlecht sondern die Asm-Version.>> Was genau ist an der Assembler-Version schlecht?
Dass es größer als das C-Programm ist. Damit fällt es durch Mobys
Qualitätsprüfung. Da braucht er sich das Programm noch nichtmals
anzuschauen. Kein Wunder, das wäre ja Arbeit - jedenfalls was Assembler
betrifft. Kein Mensch will sich die Lektüre eines größeren ASM-Codes
antun, wenn er auch noch von einem anderen Menschen programmiert wurde.
Da braucht man fürs sinnentnehmende Lesen und Verstehen ja genauso lange
wie fürs Programmieren.
Genau aus diesem Grunde sind ASM-Programme, die über Mobys 3-Zeiler
hinausgehen, nicht mehr wartbar durch Dritte.
Moby A. schrieb:> Jörg W. schrieb:>> Du hättest zumindest mal deine immer wieder proklamierten Vorzüge der>> Assemblerprogrammierung unter Beweis stellen können.>> Die sind viel schneller und effektiver an den kleinen Sachen> demonstriert.
Aber eben leider auch nur dort.
Ein Papierflieger ist technologisch auch viel einfacher als eine Cessna.
Wobei zugegebenermassen der Zielbereich von AVR Assembler schon recht
weit reicht.
> Nun ja, ich kenne ja die zugrundeliegenden Kriterien: Flexibilität und> Wartbarkeit ;-) Danke.
Einen hast du vergessen:
Schnelligkeit in der Entwicklung.
Frank M. schrieb:> Da braucht man fürs sinnentnehmende Lesen und Verstehen ja genauso lange> wie fürs Programmieren.
Ich behaupte mal: länger
Ich gebs zu, ich hab fast 20 Minuten an
1
SYSTEMINT:movr18,SIC
2
movr17,SIC
3
andir17,$30
4
brnesystemint6
gebrütet, bis ich raus hatte, warum $30, ob das korrekt ist oder nicht
und welche Konsequenzen es für den Rest des Codes hat.
Karl H. schrieb:> wie man es nicht macht.
Gut. Ich machs trotzdem so und bekomme maximale Funktionalität in den
Controller ;-)
> davon wird keinen Millimeter abgewichen
So schauts aus.
Im Übrigen kann jeder den Quelltext nach Herzenslust erweitern ;-)
Karl H. schrieb:> unbrauchbar
sind Dinge, die nicht funktionieren.
Meine Zwecke erfüllt die Sensorplatine hervorragend!
Ich hätte dich ja gerne eingeladen, etwas sinnvolles zu tun und am
Assembler Tutorial mitzuarbeiten. Themen gäbe es ja noch genug.
Abere solange du nicht verstehst, was an
1
ldi r16,$22 ;PB5,PB1-> PULLUP!
2
out PORTB,r16
schlecht ist, und warum
1
ldi r16, (1<<PB5) | (1<<PB1)
2
out PORTB, r16
besser ist UND VOR ALLEN DINGEN, warum deine Technik bei
Moby A. schrieb:> Im Übrigen kann jeder den Quelltext nach Herzenslust erweitern ;-)
Hast Du es immer noch nicht kapiert? Dein Quelltext ist nicht
erweiterbar. Er funktioniert nur für die von Dir beschriebene
Konstellation.
Da kommt mir der Verdacht hoch, Du passt die Hardware-Konstellation an
Deine Programme an und nicht umgekehrt. "Ich kann nur 2 ADCs, also
benutze ich nur 2".
Das ist für Dritte nicht erweiterbar und deshalb unbrauchbar. Daher
hat es nichts in der Codesammlung zu suchen.
Moby A. schrieb:> Karl H. schrieb:>> Einen hast du vergessen:>> Schnelligkeit in der Entwicklung>> Den hatte ich schon relativiert ;-)
Ach so?`
Bis jetzt hast du dich immer gesträubt, mal etwas anspruchsvollere
Aufgaben in Angriff zu nehmen.
So, jetzt hab ich zwei Flapps-Antworten und Mobys Meinung zu meinem
Assembler-Projekt immer noch nicht.
Nochmal, Moby: Was ist schlecht an meinem Assembler-Projekt?
Karl H. schrieb:> Bis jetzt hast du dich immer gesträubt, mal etwas anspruchsvollere> Aufgaben in Angriff zu nehmen.
Du meinst für Deinen Test?
Das ist doch ausführlich begründet.
Auch wenn mir eine Codebasis helfen mag bedeutet das noch lange keine
Mühen ;-)
Zeitmangel fürs Hobby ist freilich der Hauptgrund.
Da bist Du als Mod und hauptberuflicher MC Entwickler ganz sicher in
einer besseren Lage ;-)
Moby A. schrieb:> Karl H. schrieb:>> Ich gebs zu, ich>> ... brüte an obigen C-Texten auch noch ;-)
Ich weiss nicht, welche C Texte du meinst.
Aber nur mal so
Der Anfang deines Sensorprogramms würde (in deiner SChreibweise) so
aussehen
1
intmain(void)
2
{
3
OCR0A=8;
4
TCCR0A=2;
5
TCCR0B=3;
6
7
TIMSK0=4;
8
9
PORTB=0x22;
10
DDRB=5;
11
DIDR0=0x18;
12
13
ADMUX=2+AINP1REF;
14
ADCSRA=0xE0;
15
16
MCUCR=0x20;
17
SIC=0;
18
19
sei();
20
21
while(1)
22
{
23
}
24
}
Das ist doch nicht sonderlich schwer.
Links vom Zuweisungs-= steht, wo etwas hin soll, rechts davon was dort
hin soll.
1
OCR0A=8;
ist vollkommen äquivalent zu
1
ldi r16,8
2
out OCR0A,r16
und wird vom Compiler auch genau dazu umgesetzt (mit dem einen kleinen
Unterschied, dass es mich in der C Version nicht interessiert, welches
Register der Compiler nimmt um die Konstante zu laden). Der Endeffekt
ist derselbe: das Bitmuster für 8 landet im Register OCR0A. Das ist der
entscheidende Punkt und nicht welches Register zum Transfer benutzt
wird. In der C Version sehe ich das auch nicht. Da sehe ich nur das, was
tatsächlich relevant ist: nämlich dass die 8 ins OCR0A bugsiert wird.
Wie, das ist Sache des Compilers - ein Detail dass mir völlig wurscht
ist. Und wenn das OCR0A auf einem Prozessor nicht mittels OUT erreichbar
ist, dann ist mir das ebenfalls wurscht - Sache des Compilers die
Operation mit einem STS in die Wege zu leiten. In diesem Sinne hilft mir
der Compiler mich auf das Wesentliche zu konzentrieren: warum 8, wo
kommen die her, kann ich die Konsante so formulieren, dass da nicht 8
als Zahlenwert steht sondern für alle nachvollziehbar dort steht wie
sich die 8 berechnen?
Das sind die Dinge um die ich mich kümmere und nicht welche Register da
benutzt werden.
Ich gebe zu, dass die ISR nach deinem Prinzip nicht so elegant
formulierbar ist, weil du natürlich ein paar Dinge heftig ausnutzt.
Unter anderem dass du die Bits aus einem Register ins nächste schieben
kannst und dann das dabei ins Carry fallende Bit für einen bedingten
Sprung benutzen kannst, während sich die Register dabei gleichzeitig
wieder auf 0 setzen. Klar, das geht so in C nicht.
Horst S. schrieb:> Nochmal, Moby: Was ist schlecht an meinem Assembler-Projekt?
Nein nicht nochmal Moby. Meine Antwort hast Du bereits. Im übrigen habe
ich gar keinen Grund zu weiteren höflichen Antworten Dir gegenüber.
Karl H. schrieb:> Ich gebe zu, dass die ISR nach deinem Prinzip nicht so elegant> formulierbar ist, weil du natürlich ein paar Dinge heftig ausnutzt.> Klar, das geht so in C nicht.
Wenigstens ein paar Leute hier die versuchen, meinen Aussagen auf den
technischen Grund zu gehen. Danke.
Moby A. schrieb:> Wenigstens ein paar Leute hier die versuchen, meinen Aussagen auf den> technischen Grund zu gehen. Danke.
Och, das können praktisch alle hier. Schon vergessen? Die meisten haben
einen durchaus respektablen Assembler Background.
Nur ist es eben vergleichsweise mühsam in 4 oder 5 aufeinanderfolgenden
Assembler-Anweisungen alle Abläufe und Nebenbedingungen herauszulesen,
die da tatsächlich ablaufen und für das Programm relevant sind.
Um wieviel einfacher ist da C. Ein
1
ADC1OH<<=1;
hat genau die eine Aufgabe, die Bits um 1 Stelle nach links zu
verschieben. Nicht mehr und nicht weniger. Die verschobenen Bits werden
zwar an anderer Stelle etwas bedeuten, aber es gibt in der abstrakten C
Maschine keine derartigen impliziten Bedeutungsübertragungen von einer
Anweisung zur nächsten. Und das ist viel leichter zu verfolgen.
Überhaupt wenn der Code länger wird. Wenn es möglich ist, Nebeneffekte
von einer Anweisung zur nächsten 'mitzunehmen', dann können die Compiler
das schon.
Dafür kann ich aber die Operation auch auf zb Portregister anwenden,
wenn ich das will
1
PORTB<<=1;
ohne mich darum kümmern zu müssen, erst mal ein Register frei haben zu
müssen, dort dann mittels IN den aktuellen Portwert einzulesen, die Bits
zu verschieben und mit einem OUT wieder alles auf den Port zu schreiben.
Gleiches Prinzip: Ich kümmere mich um die höhere Ebene, dass die Bits
verschoben werden müssen. Wie das auf Prozessorebene umzusetzen ist, ist
Sache des Compilers. Ich will mich nicht darum kümmern müssen.
Moby A. schrieb:> Frank M. schrieb:>> Er weiß genau, dass er verliert.>> Gewonnen hat zuallererst eins: Die funktionierende Lösung.> An den Vorteilen von Asm gibts nichts zu deuteln.
Welche Vorteile sollten denn das sein? Das Programm vom TO war bereits
nach kurzer Zeit in C kürzer und lesbarer als seine Assembler-Lösung,
Dein erstes Assembler-Programm hatte trotz seiner extrem überschaubaren
Größe einen ziemlich dicken Fehler. Dein zweites Programm, obwohl
erkennbar mit der Intention entworfen, es einem Compiler (oder dem, was
Du Dir darunter vorstellst) so schwer wie möglich zu machen, hat Yalu
mit einem kürzeren C-Code mit besser Funktionalität widerlegt, woraufhin
Du plötzlich neue, vorher unbekannte Anforderungen aus dem Hut zaubern
mußtest. Bei dem 32-Bit-Vergleich war der Code, den der Compiler
generiert hat, ebenfalls besser als das, was Du produziert hast.
Ich stelle also fest: trotz Deines angeblichen Genies und der
angeblichen Vorteile von Assembler hast Du es nicht geschafft, auch nur
einen einzigen der Diskutanten von Deinen kruden Ansichten zu
überzeugen. Deine ständige Wiederholung der angeblichen Vorteile von
Assembler können keine Argumente ersetzen, an größere Aufgabenstellungen
als ein paar Taster und blinkende LEDs traust Du Dich offensichtlich
nicht heran, und der Code, den Du uns bislang präsentiert hast, war
kaputt, unelegant, stilistisch schlecht und in keinem Fall wirklich
besser als das, was der C-Compiler generiert hat.
Von den angeblichen Vorteilen von Assembler, die Du behauptest, hast Du
kein einziges beweisen können. Im Gegenteil haben alle Beteiligten hier
gesehen, daß man in C schneller zum Ziel kommt, und der C-Code les- und
wartbarer, erweiterbarer, fehlerärmer und die damit erzeugten Resultate
meist sogar kleiner und performanter als Dein Assembler sind.
Assembler hat heute überhaupt keine Vorteile mehr gegenüber C, außer in
einer einzigen, winzig kleinen Nische: nämlich, wenn es um taktgenaues
Timig geht. Daß Assembler ansonsten nur Nachteile gegenüber C hat, dafür
aber unübersichtlich, kompliziert zu schreiben, zu lesen, und zu warten
ist, das hast nicht nur Du hier mehrmals bewiesen, sondern das erkennen
sogar die Anfänger hier, die deswegen mehrheitlich zu C neigen.
Das Einzige, was Du jetzt noch ins Feld führen kannst, ist Dein eigener
Unwille, Dich mit C und seinen enormen Vorteilen zu beschäftigen, weil
Du vor 18 Jahren an einem C-Programm für die DOS-Kommandozeile
gescheitert bist. Das ist aber Dein ganz ureigenes, höchstpersönliches
Problem, und für andere Menschen auf der Welt kein Maßstab. Und es ist
sicher keine Rechtfertigung dafür, daß Du hier ständig Threads zu
Sprachen kaperst, obwohl die Dich angeblich gar nicht interessieren, und
sie mit Deinem penetranten, halt- und hirnlosen Gesülze vollschmierst.
Zu den Assembler-Threads dieses Forums, beispielsweise den beiden, in
denen zwei Assembler-Programmierer dringend Hilfe bei der Ansteuerung
von LCD-Displays gesucht haben, hast Du übrigens auch nichts beitragen
können. Daß Du angesichts Deiner miserablen und blamablen Performance
immer noch wagst, von den "Vorteilen von Assembler" zu schwadronieren,
nötigt mir zwar einen gewissen Respekt vor Deiner Chuzpe ab, zeugt aber
am Ende doch nur von Ignoranz und Realitätsverlust oder einer armseligen
Befriedigung daran, anderen den Spaß an diesem Forum zu verderben.
Laß' es gut sein, Ritter von der traurigen Gestalt. Die Windmühlen haben
gewonnen, und Sancho Pansa zeigt Dir den Weg zu Deiner Dulcinea. :-)
Karl H. schrieb:> Nur ist es eben vergleichsweise mühsam in 4 oder 5 aufeinanderfolgenden> Assembler-Anweisungen alle Abläufe und Nebenbedingungen herauszulesen,> die da tatsächlich ablaufen und für das Programm relevant sind.
Oder anders ausgedrückt:
Warum soll ich mich 20 Minuten da durchquälen, um alle Nebeneffekte
dieser paar Anweisungen im Kontext des Programms herauszufinden, wenn
ich in C das komplette Programm in 10 Minuten neu schreiben kann? Auch
dieses Programm wird funktionieren und seine Aufgabe perfekt erfüllen,
möglicherweise einen Tick langsamer und mit einem Tick mehr Flash
Verbrauch (*), die aber hauptsächlich dem geringen Umfang der
Problemstellung geschuldet sind. Mit dem Bonus, dass dann auch 4 ADC
keinerlei Probleme mehr aufwerfen sondern nur im Ändern eines
Zahlenwertes bestehen?
(*) was aber in der Praxis kein wirkliches Problem darstellt. Denn für
nicht verbrauchtes Flash krieg ich kein Geld zurück. Dafür spar ich mir
aber Zeit in der Entwicklung, die ich für sinnvolleres als dem Suchen
nach dem letzten Register Trick benutzen kann, der mir dann sowieso bei
einer möglichen Erweiterung erst recht wieder auf den Schädel fällt.
Moby A. schrieb:> Matthias L. schrieb:>> Moby A. schrieb:>>>Daß die Demonstration von Codeersparnis und mehr Speed idealerweise>>>zugunsten von Asm ausfallen muß wirst auch Du wissen>>>> Das hat auch nie jemand hier bestritten.>> So, das musste noch sein ;-)
Das mag zwar idealerweise so sein, praxisch gibt es aber weder eine
"Codeersparnis" noch "mehr Speed". q.e.d.
Nimm es hin, gegen die Maschine hast Du keine Chance. Ein Kran kann mehr
heben, ein Bestückungsautomat besser bestücken, und ein Compiler besser
optimieren als Du. Einfache, monotone Tätigkeiten können Maschinen nun
einmal besser als Menschen, und genau deswegen gewinnen Schachcomputer
regelmäßig gegen die besten Schachspieler der Welt.
Jörg W. schrieb:> Klaus W. schrieb:>> und da gibt es hier nur einen!>> Lass mich raten: den GCC. :-)
Ich hätte da eher an Johann und Dich gedacht. Ehre, wem Ehre gebührt.
;-)
Moby A. schrieb:> Nein nicht nochmal Moby. Meine Antwort hast Du bereits. Im übrigen habe> ich gar keinen Grund zu weiteren höflichen Antworten Dir gegenüber.
Doch, den hast Du.
Moby A. schrieb:> Ich kenne diesen Ausgang der Geschichte schon:> Immer dann wenn die Argumente ausgehen ;-)
DEINE WORTE
(Dazu sag ich mal nur: Wer gegen den Wind pisst, darf sich nicht
wundern, wenn er nass wird)
Sheeva P. schrieb:> Laß' es gut sein, Ritter von der traurigen Gestalt. Die Windmühlen haben> gewonnen, und Sancho Pansa zeigt Dir den Weg zu Deiner Dulcinea. :-)
Ich war erst versucht, Deinen wunschdenkenden Beitrag falschen Satz für
falschen Satz auseinanderzunehmen. Verschiedene Dinge sind so gar nicht
in Dein Bewußtsein gedrungen oder ganz blockiert. Da aber nun auch die
Absicht sooo eindeutig formuliert ist überlasse ich Dich besser Deiner
immerhin schönen, blühenden Phantasie ;-)
Karl H. schrieb:> Denn wann hat schon jemand genau diese Anforderungen,> dass er 2 ADC plus 2 Eingänge hat, die er dann auch noch codiert in 3> Bytes getaktet übertragen muss. Und zwar GENAU so und nicht anders. Jede> kleinste Abweichung davon - Pech gehabt. Dann stehen massive Analysen> und Änderungen an.
Wie würde das Programm eigentlich aussehen, wenn Mobys Sensorplatinchen
an das Programm "SerialComInstruments"
(Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle") angebunden werden soll,
welches Moby so toll findet...?
Moby A. schrieb:> Karl H. schrieb:>> Moby A. schrieb>>> Eine Softwareuhr zu implementieren ist jedenfalls kein Problem. Je nach>>> Uhrzeit bestimmte Dinge zu erledigen auch nicht.>>>> Na dann mach.>> Die wird hier nicht gebraucht (und wäre ohnehin umständlich zu stellen).
In C wäre die nicht umständlich zu erstellen, sondern ganz einfach.
Siehst Du die Vorteile des großartigen C gegenüber dem unflexiblen,
komplizierten und unleserlichen Assembler?
Sheeva P. schrieb:> Wie würde das Programm eigentlich aussehen, wenn Mobys Sensorplatinchen> an das Programm "SerialComInstruments"> (Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle") angebunden werden soll,> welches Moby so toll findet...?
Wahrscheinlich würde ein weiteres Platinchen mit einem Tiny13 dazu
kommen, welches das Originalprotokoll auseinandernimmt, die 4
Inforamtionseinheiten wieder extrahiert und per UART auf den Weg
schickt.
Nur bloss nichts ändern.
Sheeva P. schrieb:> Moby A. schrieb:>> Karl H. schrieb:>>> Moby A. schrieb>>>> Eine Softwareuhr zu implementieren ist jedenfalls kein Problem. Je nach>>>> Uhrzeit bestimmte Dinge zu erledigen auch nicht.>>>>>> Na dann mach.>>>> Die wird hier nicht gebraucht (und wäre ohnehin umständlich zu stellen).>> In C wäre die nicht umständlich zu erstellen
der Fairness halber: er schrub 'stellen' und nicht 'erstellen'.
Spielt aber keine wirkliche Rolle. Denn wenn die Aufgabenstellung
erfordert, dass ein Zeitprofil abgearbeitet werden muss, dann gibts da
nichts zu diskutieren. Dann eignet sich seine Vorlage eben nicht dazu,
diese "Sensorplatine mit erweiterter Funktionalität" daraus zu
entwickeln. Fangen wir eben wieder bei 0 an.
Das ist eben die Krux an 'optimalen' Lösungen (so wie Moby sie
versteht). Sie sind für genau einen Zweck und nur für diesen einen Zweck
optimal. Kleine Abweichungen sind nicht drinn. Ganz krass ist natürlich,
wenn diese kleinen Abweichungen nicht nur das Optimalitätskriterium
verletzten sondern schlicht ohne massiven Aufwand nicht machbar sind.
Karl H. schrieb:> per UART auf den Weg schickt.
UART? Seit wann hat ein ATtiny13 sowas? Der hat doch nichtmal eine
USI … Daher kann sich Moby ja auch so schöne eigene Protokolle
ausdenken, mit einer 2-Bit-Prüfsumme und so. Klar, das schlägt
kein C-Programmierer, der würde zur Datensicherung wohl eher zu
einer ordentlichen CRC greifen (schon deshalb, weil's dafür ja ein
passendes Headerfile gibt :).
Sheeva P. schrieb:> Wie würde das Programm eigentlich aussehen, wenn Mobys Sensorplatinchen> an das Programm "SerialComInstruments"> (Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle") angebunden werden soll,> welches Moby so toll findet...?
Die Platine muss nicht angebunden werden.
Die Aufgabenstellung war vorher klar definiert, eine Anbindung war nicht
vorgesehen.
Ihr C-ler immer mit eurer "Flexibikität", die im Hobby doch eh nicht
notwendig ist.
Macht euch halt vorher mal Gedanken was ihr in eurem Projekt braucht...
Hachja, nach 5-monatiger MC.net Abstinenz fühl ich mich gleich wieder
wie zu Hause.
Köstliche Unterhaltung mit den bekannten Gesichtern.
Nur eines hat sich geändert: damals sah ich Moby als penetrante
Nervensäge, die aber fachlich was drauf hat. Immerhin arbeitet er seit
zig Jahren mit Assembler.
Nun aber, tut mir Leid, ist "Witzfigur" die einzig treffende
Bezeichnung.
Fachlich ne Niete (sorry, deine Programme sind lächerlich), noch
schlimmer aber in Punkto Sozialkompetenz.
Hauptsache zum x-ten Mal die Floskel der "typischen 8 Bit Anwendungen "
bemüht...
Oder auf "bockig" umgeschaltet (gibts nicht, Basta!)
Ich glaub langsam echt, wenn die Register nicht reichen wird lieber ein
neuer Tiny drangepappt bevor man sich über Stack etc. Gedanken machen
müsste...
Karl H. schrieb:> der Fairness halber: er schrub 'stellen' und nicht 'erstellen'.
Lass mal, das ist doch egal. Er versteht sowieso alles wie er es braucht
;-)
Karl H. schrieb:>> Wenigstens ein paar Leute hier die versuchen, meinen Aussagen auf den>> technischen Grund zu gehen. Danke.>> Och, das können praktisch alle hier
Wie man wohl zu diesem Eindruck gelangen kann?
Karl H. schrieb:> OCR0A = 8;> ist vollkommen äquivalent zu ldi r16,8> out OCR0A,r16> und wird vom Compiler auch genau dazu umgesetzt (mit dem einen kleinen> Unterschied, dass es mich in der C Version nicht interessiert, welches> Register der Compiler nimmt um die Konstante zu laden).
Tja nur dumm daß man 'OCR0A' in C genauso kennen muß.
Mit Asm wird der eigentliche Vorgang des Ladens zudem transparenter
dargestellt. Welches Register das nun nach Lust und Laune erledigt ist
wurscht solange LDI darauf angewendet werden kann.
> Und wenn das OCR0A auf einem Prozessor nicht mittels OUT erreichbar> ist, dann ist mir das ebenfalls wurscht - Sache des Compilers die> Operation mit einem STS in die Wege zu leiten.
Bei der überschaubaren AVR Typenpalette kennt man seine Schäfchen.
Und wenn nicht probiert man einfach OUT: Der Assembler meckert dann
schon!
> warum 8, wo> kommen die her, kann ich die Konsante so formulieren, dass da nicht 8> als Zahlenwert steht sondern für alle nachvollziehbar dort steht wie> sich die 8 berechnen?Das ist dem Blick ins Datenblatt überlassen.
Das bläht Quellcode nur auf.
Aber wenn eine Info aus irgendeinem anderen Zusammenhang für das
Verständnis der Funktion wirklich wichtig sein sollte- ja dann mach
ich halt einen Kommentar dazu.
le x. schrieb:> Ich glaub langsam echt, wenn die Register nicht reichen wird lieber ein> neuer Tiny drangepappt
Die haben noch immer gereicht!
Aufrüsten tut eher der C-ler ;-)
Jörg W. schrieb:> mit einer 2-Bit-Prüfsumme
Nun Jörg, dafür langte der Platz noch und die ist nicht nur besser als
nix sondern auch ausreichend. Ist natürlich nichts für
Sicherheitsfanatiker, das geb ich unumwunden zu ;-)
Moby A. schrieb:> Karl H. schrieb:>> OCR0A = 8;>> ist vollkommen äquivalent zu ldi r16,8>> out OCR0A,r16>> und wird vom Compiler auch genau dazu umgesetzt (mit dem einen kleinen>> Unterschied, dass es mich in der C Version nicht interessiert, welches>> Register der Compiler nimmt um die Konstante zu laden).>> Tja nur dumm daß man 'OCR0A' in C genauso kennen muß.
Hab ich was anderes behauptet?
Ich denke das hat hier noch nie irgendwer anders behauptet. Nur weil du
C programmierst, bedeutet das nicht, dass die entsprechenden "Register
Summary" Abschnitte im Datenblatt zum Altpapier wandern.
> Mit Asm wird der eigentliche Vorgang des Ladens zudem transparenter> dargestellt. Welches Register das nun nach Lust und Laune erledigt ist> wurscht solange LDI darauf angewendet werden kann.
Das wars.
Mir reichts. Du bist unbelehrbar. Ich versuch dir eine Brücke zu bauen
und du nimmst nichts an. Gar nichts. Du bist wie ein sturer Esel.
Aber ich warne dich: bei der nächsten 'Nimm doch Assembler' Meldung in
einem C Thread, wird gelöscht.
Karl H. schrieb:> Dann eignet sich seine Vorlage eben nicht dazu,> diese "Sensorplatine mit erweiterter Funktionalität" daraus zu> entwickeln. Fangen wir eben wieder bei 0 an.
Dann fängt man besser zuvor gar nicht erst mit meinem Projekt an...
Nennt sich Vorüberlegung. Oder steht der Anspruch auf
Nutzungsmöglichkeit in beliebigen Projekten etwa in den Forenregeln ?
;-)
Karl H. schrieb:> Sie sind für genau einen Zweck und nur für diesen einen Zweck> optimal.
Genau! Wobei das Funktions- Prinzip durchaus auch anderswo Verwendung
finden kann. Eine optimale- oder sagen wir besser dem Optimum
angenäherte Umsetzung und die Flexibilität von C- das beißt sich.
le x. schrieb:> Oder auf "bockig" umgeschaltet (gibts nicht, Basta!)
Hardware-Tatsachen sind so wie sie sind. Basta! ;-)
Moby A. schrieb:> Die haben noch immer gereicht!> Aufrüsten tut eher der C-ler ;-)
Echt jetzt?
In deinen zig-Jahren Assembler- und Avr -Entwicklung haben dir immer die
Register gereicht?!
Ist ja auch schön für dich und in Ordnung. Wirklich.
Aber dann erzähl doch bitte keine Weisheiten übers Programmieren.
Ich erzähl dir ja auch nix übers imkern...
Moby A. schrieb:> Das ist dem Blick ins Datenblatt überlassen.
Ah, der zwangsneurotische Sprachcomputer hat per Zufallsgenerator wieder
das Schlagwort "Blick ins Datenblatt" ausgewählt.
TASK WEITERPLAPPERN - 100%
Was ist jetzt mit meinem "schlechten" Assemblerprojekt?
Moby A. schrieb:> Tja nur dumm daß man 'OCR0A' in C genauso kennen muß.> Mit Asm wird der eigentliche Vorgang des Ladens zudem transparenter> dargestellt. Welches Register das nun nach Lust und Laune erledigt ist> wurscht solange LDI darauf angewendet werden kann.> Das ist dem Blick ins Datenblatt überlassen.> Das bläht Quellcode nur auf.
Selten so einen Stuss gehört. Am besten wir hören auf.
@ Karl Heinz (kbuchegg) (Moderator)
>Das wars.>Mir reichts. Du bist unbelehrbar. Ich versuch dir eine Brücke zu bauen>und du nimmst nichts an. Gar nichts. Du bist wie ein sturer Esel.
Mensch Karl Heinz, du hast aber auch eine VERDAMMT lange Leitung!
Ausdauer und Grundschullehrergeduld sind schön und gut, man sollte aber
dennoch keine Perlen vor die Säue werfen.
>Aber ich warne dich: bei der nächsten 'Nimm doch Assembler' Meldung in>einem C Thread, wird gelöscht.
;-)
Karl H. schrieb:> Du bist wie ein sturer Esel.
Sollte man auf diese Bezeichnung zurückgreifen wenn man nicht mehr
weiter weiß ? Welchen Wert haben Brücken zu suboptimalen, aufwendigeren
Lösungen? Warum sollten eigentlich mir manch C-ler hier nicht wie ein
sturer Esel erscheinen?
Karl H. schrieb:> Aber ich warne dich: bei der nächsten 'Nimm doch Assembler' Meldung in> einem C Thread, wird gelöscht.
Schade. Klingt schon wieder wie eine Kapitulationserklärung.
Asm vs. C wird in entsprechendem Zusammenhang immer ein Thema bleiben.
Matthias L. schrieb:> Selten so einen Stuss gehört. Am besten wir hören auf.
Du mußt Dich zu "Stuss" ja nicht äußern ;-)
Moby A. schrieb:> Asm vs. C wird in entsprechendem Zusammenhang immer ein Thema bleiben.
Bitte aber in deinen eigenen Threads.
Allein dieser Thread zeigt, dass deine Diskussionskultur keinerlei
Nutzen für den TE hat(te). Wenn du nicht gewillt bist, wirklich
jemandem zu helfen, dann halt' dich bitte aus fremden Threads fern.
Nein, ein pauschales „in Assembler geht das sowieso alles besser“ ist
keine Hilfe.
Moby A. schrieb:> Mit Asm wird der eigentliche Vorgang des Ladens zudem transparenter> dargestellt.
Was interessiert es dich wie die 8 ins OCR0A kommt? Wichtig ist ja
nur, dass sie drin steht. Wenn es hingegen wirklich wichtig ist, dass
das in einer genauen Anzahl Instruktionszyklen passiere, wäre ASM
angebracht.
> Welches Register das nun nach Lust und Laune erledigt ist> wurscht solange LDI darauf angewendet werden kann.
Genau deswegen kann man das auswählen auch dem Compiler überlassen.
Vllt. findet er auch noch eines wo "zufällig" seit 20 Zeilen schon eine
8 drinsteht.
Moby A. schrieb:> Warum sollten eigentlich mir manch C-ler hier nicht wie ein> sturer Esel erscheinen?
Vielleicht weil viele "C-ler", im Gegensatz zu dir, auch die andere
Seite (ASM) kennen und fundierte Entscheidungen treffen können.
Du erinnerst mich irgendwie an einen ex-Schulkollegen der keinen Fisch
mag, er hatte ihn zwar noch nie probiert, er weiß es einfach...
Wie kommt es eigentlich, dass deine Aussagen kaum Unterstützung finden?
Sind so gut wie alle hier auf dem Irrweg, oder vielleicht doch du?
Stefan K. schrieb:> Sprich: Asm> ohne Kommentare geht gar nicht, gut geschriebenes C kommt an den meisten> Stellen auch ohne Kommentare aus.
Du meinst wenn Funktionen aussagekräftige Namen haben?
Das geht in Asm genauso. asm ist zunächst mal eines: Schlicht.
Eindeutig. Transparent. Keine ausschweifende Klammerwüste mit x Ebenen
und komplexen Ausdrücken in denen x Sprachelemente verwurstet sind ;-)
Rea L. schrieb:> Wie kommt es eigentlich, dass deine Aussagen kaum Unterstützung finden?
Nun, C mag durchaus von der Mehrheit angewendet werden. Viele können
wohl nur noch Hochsprache. Ist dann wohl irgendwie schmerzlich mit einer
effizienteren Programmierweise konfrontiert zu werden? Bei soviel
Emotion hier hat man ja fast das Gefühl, man läßt Welten zusammenstürzen
;-)
> Sind so gut wie alle hier auf dem Irrweg, oder vielleicht doch du?
Hatten wir das nicht schon? Wer eine funktionierende Lösung vorzeigt ist
nicht auf dem Irrweg. Hier geht es aber eher um technische Feinheiten
(mit hochemotionaler Begleitmusik allerdings).
Jörg W. schrieb:> Nein, ein pauschales „in Assembler geht das sowieso alles besser“ ist> keine Hilfe.
Daß alles besser geht hat auch niemand behauptet.
Berechnungen zum Beispiel. In Asm sind größere Sachen im Prinzip
aufwendiger.
Wenn MSR-Projekte größere Berechnungen nicht ständig benötigen fehlt
dieses Motiv zum Umstieg aber.
Moby A. schrieb:> Berechnungen zum Beispiel.
Komisch, mein Rechner ist zum rechnen da, nicht nur zum Daten schieben,
sonst wär's ja 'nen Schieber.
Was macht mein "schlechtes" Assemblerprogramm? Auswertung schon fertig?
Moby A. schrieb:> Viele können wohl nur noch Hochsprache.
Du solltest eigentlich mittlerweile gemerkt haben, dass das für viele
bis alle hier nicht zutrifft.
> Ist dann wohl irgendwie schmerzlich mit einer> effizienteren Programmierweise konfrontiert zu werden?
Meine Form einer effizienten Programmierung hat einmal darin bestanden,
mir für ein Projekt auf Z80 Basis einen sehr einfachen Compiler zu
stricken. Eigentlich eher ein Mix aus einer eigenen simplen Sprache und
Assembler. Damit das Programm besser les- und wartbar ist. Ist schon
etwas älter, brauchbares C für Z80 gab es nicht.
Der plz.y Quelltext hat übrigens 2 Compiler zwischen sich und dem
Programm, nämlich vorneweg einen Parser-Generator der C Quelltext
erzeugt:
Beitrag "Re: Gibt es eine Programmiersprache mit diesem Schleifentyp?"
Moby A. schrieb:> Nun, C mag durchaus von der Mehrheit angewendet werden. Viele können> wohl nur noch Hochsprache.
Moby, es ist dir mehrere Male klipp und klar gesagt (und auch mit
Codebeispielen gezeigt) worden: hier irrst du gewaltig. So gut wie
alle, denen du hier mehr oder weniger Unfähigkeit oder Faulheit
unterstellst, haben teils bessere Assemblerkenntnisse als du, haben
oft auch weit mehr Architekturen und Assembler benutzen dürfen, als
du dir auch nur ansatzweise vorstellen kannst. Trotzdem (oder gerade
deshalb) sehen sie darin kein Allheilmittel, für das sie andere
evangelisieren müssten.
Nochmal: wir werden eine derartige Vereinnahmung beliebiger Threads
durch dich in Zukunft nicht mehr dulden. Wenn du denkst, dass du
andere davon überzeugen musst, wieviel besser es ist, mit reinem
Assembler zum Ziel zu kommen, dann veröffentliche deine eigenen
Projekte oder eröffne anderweitig deine eigenen Threads.
Für diesen Thread ist alles gesagt worden, was zu sagen war. Horst
hatte nach wenigen Stunden ausreichend Hilfe, um selbst gegenüber
seiner ursprünglichen Lösung sich gut verbessern zu können. Damit
betrachtet er das Thema des Threads als abgeschlossen.
Jörg W. schrieb:> abgeschlossen
Schade, ich fand den Thread heute noch einmal richtig unterhaltsam,
wobei mir immerhin eines klar geworden ist:
Moby A. schrieb:> Zeitmangel fürs Hobby ist freilich der Hauptgrund.
Man zähle einfach mal seine Beiträge allein in diesem Thread. Da ist es
nicht verwunderlich, dass für die Assemblerprogrammierung kaum Zeit
bleibt :)