Moby schrieb:
> den Thread zur Ruhe kommen lassen
Endlich!
Warum nicht gleich so.
:
Bearbeitet durch User
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:
1 | volatile
|
2 | struct
|
3 | {
|
4 | uint8_t u8CntFct; |
5 | void ( *apfct[8] ) (void); |
6 | //---------------------------------------------------------
|
7 | uint32_t u32TickMs; |
8 | uint32_t u32TickSec; |
9 | }
|
10 | scEsc_SysTick; |
11 | |
12 | |
13 | |
14 | |
15 | void SysTick_Handler(void) |
16 | {
|
17 | //-- TimeTick erhöhen -------------------------------------
|
18 | scEsc_SysTick.u32TickMs++; |
19 | |
20 | //-- UserFunktion aufrufen --------------------------------
|
21 | uint8_t u8Idx = 0; |
22 | uint8_t u8Max = (uint8_t) ( sizeof(scEsc_SysTick.apfct ) |
23 | / sizeof(scEsc_SysTick.apfct[0]) ); |
24 | while ( u8Idx != u8Max ) |
25 | {
|
26 | void ( *pfct ) (void) = scEsc_SysTick.apfct[u8Idx++]; |
27 | if ( pfct != 0 ) |
28 | {
|
29 | (*pfct) (); |
30 | }
|
31 | }
|
32 | //---------------------------------------------------------
|
33 | return; |
34 | }
|
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...
Matthias L. schrieb: > Ist das so? > > Wie sieht denn der asm Code für folgendes künstliche Konstrukt aus: > volatile > struct > { > uint8_t u8CntFct; > void ( *apfct[8] ) (void); > //--------------------------------------------------------- > uint32_t u32TickMs; > uint32_t u32TickSec; > } > scEsc_SysTick; > > void SysTick_Handler(void) > { > //-- TimeTick erhöhen ------------------------------------- > scEsc_SysTick.u32TickMs++; > > //-- UserFunktion aufrufen -------------------------------- > uint8_t u8Idx = 0; > uint8_t u8Max = (uint8_t) ( sizeof(scEsc_SysTick.apfct ) > / sizeof(scEsc_SysTick.apfct[0]) ); > while ( u8Idx != u8Max ) > { > void ( *pfct ) (void) = scEsc_SysTick.apfct[u8Idx++]; > if ( pfct != 0 ) > { > (*pfct) (); > } > } > //--------------------------------------------------------- > return; > } Ist doch einfach (ganz intuitiv runter geschrieben):
1 | .file "a.c" |
2 | __SP_H__ = 0x3e |
3 | __SP_L__ = 0x3d |
4 | __SREG__ = 0x3f |
5 | __tmp_reg__ = 0 |
6 | __zero_reg__ = 1 |
7 | .comm scEsc_SysTick,25,1 |
8 | .text |
9 | .global SysTick_Handler |
10 | .type SysTick_Handler, @function |
11 | SysTick_Handler: |
12 | push r28 |
13 | push r29 |
14 | rcall . |
15 | rcall . |
16 | in r28,__SP_L__ |
17 | in r29,__SP_H__ |
18 | /* prologue: function */ |
19 | /* frame size = 4 */ |
20 | /* stack size = 6 */ |
21 | .L__stack_usage = 6 |
22 | lds r24,scEsc_SysTick+17 |
23 | lds r25,scEsc_SysTick+17+1 |
24 | lds r26,scEsc_SysTick+17+2 |
25 | lds r27,scEsc_SysTick+17+3 |
26 | adiw r24,1 |
27 | adc r26,__zero_reg__ |
28 | adc r27,__zero_reg__ |
29 | sts scEsc_SysTick+17,r24 |
30 | sts scEsc_SysTick+17+1,r25 |
31 | sts scEsc_SysTick+17+2,r26 |
32 | sts scEsc_SysTick+17+3,r27 |
33 | std Y+1,__zero_reg__ |
34 | ldi r24,lo8(8) |
35 | std Y+2,r24 |
36 | rjmp .L2 |
37 | .L3: |
38 | ldd r24,Y+1 |
39 | ldi r25,lo8(1) |
40 | add r25,r24 |
41 | std Y+1,r25 |
42 | mov r24,r24 |
43 | ldi r25,0 |
44 | lsl r24 |
45 | rol r25 |
46 | subi r24,lo8(-(scEsc_SysTick+1)) |
47 | sbci r25,hi8(-(scEsc_SysTick+1)) |
48 | mov r30,r24 |
49 | mov r31,r25 |
50 | ld r24,Z |
51 | ldd r25,Z+1 |
52 | std Y+4,r25 |
53 | std Y+3,r24 |
54 | ldd r24,Y+3 |
55 | ldd r25,Y+4 |
56 | sbiw r24,0 |
57 | breq .L2 |
58 | ldd r24,Y+3 |
59 | ldd r25,Y+4 |
60 | mov r30,r24 |
61 | mov r31,r25 |
62 | icall |
63 | .L2: |
64 | ldd r25,Y+1 |
65 | ldd r24,Y+2 |
66 | cp r25,r24 |
67 | brne .L3 |
68 | nop |
69 | /* epilogue start */ |
70 | pop __tmp_reg__ |
71 | pop __tmp_reg__ |
72 | pop __tmp_reg__ |
73 | pop __tmp_reg__ |
74 | pop r29 |
75 | pop r28 |
76 | ret |
77 | .size SysTick_Handler, .-SysTick_Handler |
78 | .ident "GCC: (GNU) 4.8.1" |
79 | .global __do_clear_bss |
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.
:
Bearbeitet durch User
>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.
Matthias L. schrieb: > Und Du meinst, das das leserlicher ist? Hat dein Ironie-Detektor grad Urlaub?
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): Ist ja Schummel, Du hast die Optimierung ausgeschaltet. -Os:
1 | void SysTick_Handler(void) |
2 | {
|
3 | 32: cf 93 push r28 |
4 | 34: df 93 push r29 |
5 | //-- TimeTick erhöhen -------------------------------------
|
6 | scEsc_SysTick.u32TickMs++; |
7 | 36: 80 91 71 00 lds r24, 0x0071 |
8 | 3a: 90 91 72 00 lds r25, 0x0072 |
9 | 3e: a0 91 73 00 lds r26, 0x0073 |
10 | 42: b0 91 74 00 lds r27, 0x0074 |
11 | 46: 01 96 adiw r24, 0x01 ; 1 |
12 | 48: a1 1d adc r26, r1 |
13 | 4a: b1 1d adc r27, r1 |
14 | 4c: 80 93 71 00 sts 0x0071, r24 |
15 | 50: 90 93 72 00 sts 0x0072, r25 |
16 | 54: a0 93 73 00 sts 0x0073, r26 |
17 | 58: b0 93 74 00 sts 0x0074, r27 |
18 | 5c: c0 e0 ldi r28, 0x00 ; 0 |
19 | 5e: d0 e0 ldi r29, 0x00 ; 0 |
20 | uint8_t u8Idx = 0; |
21 | uint8_t u8Max = (uint8_t) ( sizeof(scEsc_SysTick.apfct ) |
22 | / sizeof(scEsc_SysTick.apfct[0]) ); |
23 | while ( u8Idx != u8Max ) |
24 | {
|
25 | void ( *pfct ) (void) = scEsc_SysTick.apfct[u8Idx++]; |
26 | 60: fe 01 movw r30, r28 |
27 | 62: ee 0f add r30, r30 |
28 | 64: ff 1f adc r31, r31 |
29 | 66: e0 5a subi r30, 0xA0 ; 160 |
30 | 68: ff 4f sbci r31, 0xFF ; 255 |
31 | 6a: 01 80 ldd r0, Z+1 ; 0x01 |
32 | 6c: f2 81 ldd r31, Z+2 ; 0x02 |
33 | 6e: e0 2d mov r30, r0 |
34 | if ( pfct != 0 ) |
35 | 70: 30 97 sbiw r30, 0x00 ; 0 |
36 | 72: 09 f0 breq .+2 ; 0x76 <__SREG__+0x37> |
37 | {
|
38 | (*pfct) (); |
39 | 74: 09 95 icall |
40 | 76: 21 96 adiw r28, 0x01 ; 1 |
41 | |
42 | //-- UserFunktion aufrufen --------------------------------
|
43 | uint8_t u8Idx = 0; |
44 | uint8_t u8Max = (uint8_t) ( sizeof(scEsc_SysTick.apfct ) |
45 | / sizeof(scEsc_SysTick.apfct[0]) ); |
46 | while ( u8Idx != u8Max ) |
47 | 78: c8 30 cpi r28, 0x08 ; 8 |
48 | 7a: d1 05 cpc r29, r1 |
49 | 7c: 89 f7 brne .-30 ; 0x60 <__SREG__+0x21> |
50 | (*pfct) (); |
51 | }
|
52 | }
|
53 | //---------------------------------------------------------
|
54 | return; |
55 | }
|
56 | 7e: df 91 pop r29 |
57 | 80: cf 91 pop r28 |
58 | 82: 08 95 ret |
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. :-)
Hmm, ist der hier...
1 | void SysTick_Handler(void) |
...und der hier...
1 | (*pfct) (); |
...nicht genau der, wo mir weiter oben nahegelegt wurde, ich solle das wegen fehlender Inline-Möglichkeiten lassen?
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.
:
Bearbeitet durch User
@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? ;-)
Yalu X. schrieb: > Assembler-Gott :-) Und ich hatte gerade an 'selbsternannter Assembler-Papst' gedacht.
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...
> Wenn die Absicht der abwertenden Kommentare nur nicht so > eindeutig wäre... tit for tat
:
Bearbeitet durch User
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):
1 | #define src_hi r25 |
2 | #define src_lo r24 |
3 | |
4 | ; 11 words, (14 + __strlen_P(src) * 8) cycles |
5 | |
6 | ASSEMBLY_CLIB_SECTION |
7 | .global _U(__strlen_P) |
8 | .type _U(__strlen_P), @function |
9 | _U(__strlen_P): |
10 | X_movw ZL, src_lo |
11 | .L_strlen_P_loop: |
12 | X_lpm r0, Z+ |
13 | tst r0 |
14 | brne .L_strlen_P_loop |
15 | ; return Z - 1 - src = (-1 - src) + Z = ~src + Z |
16 | com src_lo |
17 | com src_hi |
18 | add src_lo, ZL |
19 | adc src_hi, ZH |
20 | ret |
21 | .L_strlen_P_end: |
22 | .size _U(__strlen_P), .L_strlen_P_end - _U(__strlen_P) |
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...
:
Bearbeitet durch User
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.
Moby A. schrieb: > Hast Du schon gelesen? Meinst du das, was du hier... Beitrag "Re: C versus Assembler->Performance" ...geschrieben hast? War beim Schreiben meines Posts noch nicht da. Hab' bisschen getrödelt. Oder meinst du...
1 | ;Funktionalität: |
2 | |
3 | ;[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:
1 | 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("");}} |
Allerdings ist das nicht die Kategorie, in der irgendjemand eine ernsthafte Arbeit abliefern würde, egal ob Hobby oder Paywork.
:
Bearbeitet durch Moderator
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.
Habt ihr alle euer Tütü ordentlich angezogen? Dann ist ja gut ...
>Deshalb ist Asm ja auch so erfrischend einfach und übersichtlich
SChnell, ein Blick und Du kannst mir sagen, was das tut:
[asm]
temp1H = r17
temp1L = r16
temp2H = r19
temp2L = r18
faktor = r20
counter = r21
ascii = r22
;------- werte holen
mov r17, adch
mov r16, adcl
;------- temp puffer
movw temp2L, temp1L
;------- teile durch vier
clc ; clear carry flag
ror temp2H
ror temp2L
clc
ror temp2H
ror temp2L
;------- zusammenrechnen
add temp2L, temp1L
adc temp2H, temp1H ; in temp2 steht jetzt 1,25*adc
;------- ausgabe highbyte
mov ascii, -0x30 ; ascii für null
subi temp2H, ascii
UDR = temp2H ; über uart senden
UDR = ',' ; komma senden, warten auf udre einfügen
;------- lowbyte mal zehn,
ldi faktor, 10
ldi counter, 5 ; azahl nachkommastellen
loop:
mul temp2L, faktor
subi r0, ascii
UDR = r0 ; über uart senden, warten auf udre einfügen
mov temp2L, r1
;------ genug stellen ausgegeben?
DEC counter
BRNE loop;
;------- nu fertsch ;-)
[/asm]
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.
Nur mal so am Rande, zum Thema größere Assemblerprogramme: Erinnert sich noch jemand an Frank Ostrowskis GFA-Basic für den Atari ST?
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
1 | if(x < 1000000) { ... } |
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.
:
Bearbeitet durch Moderator
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:
1 | if(x < 1000000) { ... } |
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?
:
Bearbeitet durch User
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. ;-)
:
Bearbeitet durch User
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 ;-)
:
Bearbeitet durch User
Wenn du C schon als Hochsprache bezeichnest, was hälst du dann erst von Ada oder gar Rust?
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 ;-)
Bob schrieb: > was hälst du dann erst von > Ada oder gar Rust? Für völlig ungeeignet für AVRs und ihre typischen Anwendungen jedenfalls.
Moby A. schrieb: > Das glaub ich erst wenn mir jemand sagt, was die entsprechende > C-Konstruktion exakt an Takten frisst ;-) Basierend auf
1 | void f(long x) |
2 | {
|
3 | if (x < 1000000) |
4 | g(); |
5 | }
|
5-6 Takte für Vergleich+Sprungbefehl. Wenn du weniger brauchst: Wir kondolieren bestimmt alle, versprochen. ;-)
A. K. schrieb: > 5-6 Takte für Vergleich+Sprungbefehl. Na vielleicht auf nem 32-Bitter ... Veralbern kann ich mich allein.
Moby A. schrieb: > Na vielleicht auf nem 32-Bitter ... Nö, beim AVR. Bei einem 32-Bitter wärs oft 0,5 oder so, je nachdem wie man das rechnet.
:
Bearbeitet durch User
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_t Test_Mio(uint32_t val) |
2 | {
|
3 | return val < 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.
Ralf G. schrieb: > Nur: wenn's doch mal vorkommt, musst du da gleich die > Segel streichen!? Papperlapapp- Dann codiere ich den Vergleich halt.
Moby A. schrieb: > Dann codiere ich den Vergleich halt. Kanst du nicht, kannst du nicht, kannst du 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".
Tja A.K., du machst mich leider nicht neugierig auf die Lösung...
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.
@Moby Lass erstmal die Vergleich-1000000-Spinnerei liegen. Es gibt Wichtigeres: Beitrag "LCD Assembler" Da braucht jemand dringend deine Hilfe!
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.
:
Bearbeitet durch User
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 ;-)
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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. ;-)
:
Bearbeitet durch User
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ß.
:
Bearbeitet durch User
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 !!!! ;-)
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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: > Methode 1: Würde ich so nicht machen. Besser: > Teste A3 > B3 > Sprung falls A3 > B3 Sprung falls A3 < B3 > Teste A2 > B2 > Sprung falls A2 > B2 Sprung falls A2 < B2 > Teste A1 > B1 > Sprung falls A1 > B1 Sprung falls A1 < B1 > Teste A0 > B0 > Sprung falls A0 > B0
A. K. schrieb: > Würde ich so nicht machen. Was interessiert, ist ja allerdings: Wie macht's Moby? :-)
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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. ;-)
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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...
Moby schrieb: ...an Rufus... > Anfänger. Hauptsache große Klappe. Guck' an! Der Assembler-Papst! Jetzt wird er auch noch größenwahnsinnig!
Ralf G. schrieb: > Guck' an! Der Assembler-Papst! Jetzt wird er auch noch größenwahnsinnig! Ausser anspruchsloser Provokation bleibt ihm nichts mehr.
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.
A. K. schrieb: > Ausser anspruchsloser Provokation bleibt ihm nichts mehr. Dir bleibt nichts, die Vorteile von ASM zu bestreiten ;-)
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.)
:
Bearbeitet durch User
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
Realist schrieb: > einfach nur > overkill. Bei sowas kommen mir immer gleich die dicken C-Bücher und die Konfiguritis der Compiler in den Sinn ;-)
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.
:
Bearbeitet durch User
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
@Horst Der Text spricht für Dich, Kompliment. Ich kenne diesen Ausgang der Geschichte schon: Immer dann wenn die Argumente ausgehen ;-)
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:
1 | #include <stdint.h> |
2 | #include <avr/io.h> |
3 | |
4 | #define N_ADCs 4
|
5 | |
6 | uint8_t IC; |
7 | uint16_t ADUC[2 * N_ADCs]; |
8 | |
9 | void adu_init (void) |
10 | {
|
11 | ADMUX = (1 << REFS0); |
12 | ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADSC) | (0b111 << ADPS0); |
13 | }
|
14 | |
15 | void adu (void) |
16 | {
|
17 | uint8_t ic = ++IC; |
18 | uint8_t adc_num = 3 & (ic >> 6); |
19 | |
20 | uint16_t *adc = & ADUC[adc_num]; |
21 | uint16_t sum64 = adc[N_ADCs] += ADC; |
22 | |
23 | if (0 == ic % 64) |
24 | {
|
25 | adc[0] = sum64 >> 6; |
26 | adc[N_ADCs] = 0; |
27 | |
28 | uint8_t refs = (ic & 0x80) |
29 | ? (1 << REFS1) | (1 << REFS0) |
30 | : (1 << REFS0); |
31 | |
32 | ADMUX = refs | adc_num; |
33 | }
|
34 | }
|
== 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 :-(
:
Bearbeitet durch User
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 ;-(
900ss D. schrieb: > Hab ich jetzt was übersehen? Du schreibst, beides ist 40 Byte lang. 40 Befehle, nicht 40 Bytes.
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?
Wobei die Compiler - wenn man ihn lässt - zu Lasten von ein paar Befehlen mehr die mit 30 Takten langsame Shift-Schleife ersetzt, also aus:
1 | ldi XL,6 ;Every 320ms: |
2 | adu1: lsr YH ;average out |
3 | ror YL |
4 | dec XL |
5 | brne adu1 |
diesen mit 9 Takten doch wesentlichen schnellern Code produziert:
1 | clr __tmp_reg__ |
2 | lsl r24 |
3 | rol r25 |
4 | rol __tmp_reg__ |
5 | lsl r24 |
6 | rol r25 |
7 | rol __tmp_reg__ |
8 | mov r24,r25 |
9 | mov r25,__tmp_reg__ |