PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : berechnungen...



Bluesmash
17.07.2005, 13:44
kann man in basom in einer programmzeile nicht mehrere operationen gleichzeitig ausführen?
z.B. so: X=Y-Z+200

muss man dass immer so machen?:
X=Y-Z
X=X+200

mfg bluesmash

Rodney
17.07.2005, 14:13
du kannst soviel in einer Zeile ausführen wie du willst

Marco78
17.07.2005, 14:29
Nein Berechnungen in BASCOM geht nur mit einer Operation pro Zeile!
Außer es ist in der aktuellen Version geändert wurden. in der .4 war es noch so!

Entweder so machen wie du gefragt hast oder


X=Y-Z : X=X+200

Bluesmash
17.07.2005, 14:49
wenn cih mich rechz erinnere hab ich die .7 version (bin leider nicht zu hause) und wenn ich mehrere operationn po zeile mache bekomme ich beim compilieren nen fehler...

mfg bluesmash

Marco78
17.07.2005, 15:23
Davon rede ich ja!

Es geht nur eine Operation pro Zeile. Außer wenn du mit : zwei Zeilen durchweg schreibst so wie ich es oben gemacht habe.

pebisoft
17.07.2005, 17:03
mit einem ":" kannst du die zeile verlängern, aber nicht mehrere rechnungen in einem ergebniswert.
mfg pebisoft

waste
17.07.2005, 17:22
Das ist aber schwach von Bascom, wenn man nicht mal x=y-z+200 in einer Zeile ausführen kann. Das kann doch nicht wahr sein. Ich glaub es nicht.

Gruss Waste

Rodney
17.07.2005, 18:10
is das jetzt nen Witz dass man nicht mehr Sachen in einer Rechnung bearbeiten kann?
Ich kenne Basecom nicht, Basic aber schon und hab deswegen einfach mal so geantwortet, sorry.
Wenn das wirklich so ist, bin ich ja vollkommen überzeugt -> Basecom nein danke, C ist schon was schönes

Marco78
17.07.2005, 18:28
So, dann mal an alle, die sich über BASCOM beschweren!

Wie würde so eine Rechenoperation denn bitteschön in Assembler aussehen?

Ja ne, is klar, da kann man auch mit 5 Operanten in einer Zeile arbeiten ;)

PicNick
17.07.2005, 19:14
Ihr müßt unterscheiden, was zur Run-Time ausgerechnet werden soll und was der Präcompiler rechnet.

Es ist ja auch nur eine Schreib-Komfort-Frage.

Tatsächlich sind die Rechnungen in jeder x-beliebigen Sprache so oder so aufgefädelt und dann noch byteweise, wenn's integer, long oder sonstwas sind. Was denkt ihr, was RISC heißt ? .....Richtig.

Rodney
17.07.2005, 19:19
Wie würde so eine Rechenoperation denn bitteschön in Assembler aussehen?

Ja ne, is klar, da kann man auch mit 5 Operanten in einer Zeile arbeiten ;)

Was ist das denn bitteschön für ein Vergleich ](*,)
Von einer Hochsprache wie Basic erwartet man eigentlich schon dass sie sowas beherrscht. Für den Compiler dürfte dass ja nun nicht wirklich ein Problem sein

hrei
17.07.2005, 19:19
So, dann mal an alle, die sich über BASCOM beschweren!

Wie würde so eine Rechenoperation denn bitteschön in Assembler aussehen?

Ja ne, is klar, da kann man auch mit 5 Operanten in einer Zeile arbeiten ;)

Marco,

ich mag Bascom ja auch, aber die Unfähigkeit mit mathematischen Ausdrücken zu arbeiten gibt es sonst bei keinem mir bekannten Hochsprachencompiler. Die Nachfrage wie man das denn in Assembler realisieren würde, läßt sich sich dann noch steigern durch "und wie macht man es in Microcode?".
Das ist Schwachsinn in Tüten. Eine Hochsprache nutzt man, um u.A. genau das zu vereinfachen.

Es bleibt derzeit nichts anderes übrig, als umfangreichere Berechnungen in Subroutinen/Funktionen auszulagern und dort die UPN anzuwenden (war mal sehr modern in den 70zigern). Glücklicherweise erlaubt Bascom ja die Benutzung lokaler Variablen, die nach Benutzung wieder freigegeben werden.

Für mich überwiegen die Vorteile von Bascom derzeit die Nachteile, wenn ich auch über die in letzer Zeit festzustellende Flaute in Bezug auf die Anpassung an neue µCs nicht besonders glücklich bin (die M168.def.dat funktioniert immer noch nicht richtig - Clock kann'se nich', RC5 auch nicht, obwohl das problemlos möglich wäre -es fehlt an den Aliasen für TCCR0A/B und TIMSK0/1/2).

Grüße
Henrik

hrei
17.07.2005, 19:25
Was denkt ihr, was RISC heißt ? .....Richtig.

Der nächste Blinde. Mann, nix richtig. RISC ist einfach nur weine Prozessorstruktur, die sich mit einem weniger umfangreichen Befehlssatz begnügt, dessen einzelne Befehle dafür aber im Idealfall mit einem Prozessortakt ausgeführt werden können.

Mit dem Compiler (BASCOM) hat das nix, aber auch gar nix zu tun.

Willst Du hier die Leute verarschen?

Henrik

Marco78
17.07.2005, 19:27
Ich kenne niemanden, der einen µC oder PC in Microcode programmiert. Der Vergleich wäre meine Meinung nach etwas überzogen.
Es nervt mich nur, das so viele auf BASCOM schimpfen ohne zu wissen über was sie da reden.
Ich beschwere mich nicht über C weil ich damit nicht programmiere. Wenn ich über Pascal ablästern würde, dürfte ich das weil ich weiss um was es da geht.

Der Vergleich der Rechenoperationen in BASCOM und Assembler sollte nur etwas zum nachdenken anregen und nicht gleich eine Diskussion auslösen. Das war nichtmeine Absicht. Deshalb siehe ich diese Aussage hiermit zurück!

Aber wer BASCOM nicht kennt sollte sich vielleicht lieber etwas zurückhalten bzw erstmal überprüfen ob die Aussagen auch stimmen die man trifft.

Marco78
17.07.2005, 19:28
Der nächste Blinde. Mann, nix richtig. RISC ist einfach nur weine Prozessorstruktur, die sich mit einem weniger umfangreichen Befehlssatz begnügt, dessen einzelne Befehle dafür aber im Idealfall mit einem Prozessortakt ausgeführt werden können.

Willst Du hier die Leute verarschen?

Reduced Instruction Set Computing

hrei
17.07.2005, 19:39
Reduced Instruction Set Computing

Nö...

Reduced Instruction Set Code
im Gegensatz zu:
CISC
Complex Instruction Set Code

Also das, was ich oben mit mehr Worten beschrieben habe. Computing, also das Rechnen selbst, hat in der Bezeichnung nix verloren.

Henrik

Marco78
17.07.2005, 19:42
Na wenn das so ist, geh mal ganz schnell zu Wikipedia und berichtige den Eintrag bevor noch andere den Glauben verfallen.
Und ein paar andere Seiten im Netz sollten auch mal upgedatet werden.
Ich will ja nicht sagen das du unrecht hast, aber irgendwoher muss diese Meinung/Bezeichnung ja kommen.

hrei
17.07.2005, 20:09
Na wenn das so ist, geh mal ganz schnell zu Wikipedia und berichtige den Eintrag bevor noch andere den Glauben verfallen.
Und ein paar andere Seiten im Netz sollten auch mal upgedatet werden.
Ich will ja nicht sagen das du unrecht hast, aber irgendwoher muss diese Meinung/Bezeichnung ja kommen.

Done :-)

Wiki ist eine gute Idee, leidet aber ebenso unter dem Mangel wie Foren, daß jeder Volltrottel alles und jedes hinschreiben kann, ohne das dies erst von einem fachkompetenten Redakteur überprüft wird. Das führt dann dazu, daß ähnliche Schwachmate den Murks abschreiben.

In der Überseztzung wird ja richtig von "Befehlsatz" gesprochen, die entsprechung ist halt "Code" und nicht "Computing -> Rechnen".

Leider ist auch vieles andere in dem Artikel falsch, so daß 'Pipelining' erst durch RISC ermöglicht wird. Woillte ich jeden Murks korrigieren, der in Wiki verbreitet wird, wäre das eine Lebensaufgabe.

Henrik

Marco78
17.07.2005, 20:16
Es muss ja nicht eine lebensaufgabe werden, aber vielleicht immer wenn du etwas zeit hast und dir mal danach ist. wikipedia wird immer mehr das Nachschlagewerk des Internets. Je mehr dort richtig steht desto mehr provitieren davon.

PicNick
17.07.2005, 20:19
Ein Wahnsinn, wenn man bedenkt, daß diese Leute dafür bezahlt werden.
Was man im Netz so alles findet, und keiner kennt Henrik

http://www.cs.washington.edu/homes/lazowska/cra/risc.html

Reduced Instruction Set Computers (RISC):
Academic/Industrial Interplay Drives Computer Performance Forward

William N. Joy
Co-Founder, and Vice President for Research
Sun Microsystems, Inc.

hrei
17.07.2005, 20:35
Ein Wahnsinn, wenn man bedenkt, daß diese Leute dafür bezahlt werden.
Was man im Netz so alles findet, und keiner kennt Henrik

http://www.cs.washington.edu/homes/lazowska/cra/risc.html

Reduced Instruction Set Computers (RISC):
.

Du kleines überhebliches A:::: kannst ganz prachtvoll vermeinliche Quellen heraussuchen, scheinst aber den Unterschied zwischen Computing und Computer nicht zu kennen.

Hausaufgabe:

Erkläre die Unterschiede zwischen einem Rechner (Computer) dem Code (Befehlssatz) und einem Compiler , der sowohl den Computer als auch dessen Code benutzen muss. - Beachte hierbei die semantischen Unterschiede zwischen Computer und Computing.

Wollen wir nun diskutieren ob Wasser nass ist und 1+1 statt 2 nicht doch evtl. etwas dazwischen --- so 1,1 bis 1,9?

Henrik

17.07.2005, 21:48
Könnte bitte mal ein Moderator die Diskussion ein bisschen zusammenfassen?

Der Stil der Äußerungen wird dem Thema nicht gerecht. Wer wen zu recht oder zu unrecht als minderwertig ansieht, interessiert sonst keinen.

Ich hoffe auch, dass Teilnehmer die Kraftausdrücke benutzen wollen, den geeigneten Ort dafür finden.

Bluesmash
17.07.2005, 22:09
sitze gerade erschrocken vor meinem pc... ;) hätte nicht gedacht das eine so kleine frage gleich so eine diskussion auslöst! ich hoffe ihr habt euch wieder ein bisschen beruhigt...

mfg bluesmash

hrei
17.07.2005, 22:17
Könnte bitte mal ein Moderator die Diskussion ein bisschen zusammenfassen?

Der Stil der Äußerungen wird dem Thema nicht gerecht. Wer wen zu recht oder zu unrecht als minderwertig ansieht, interessiert sonst keinen.

Ich hoffe auch, dass Teilnehmer die Kraftausdrücke benutzen wollen, den geeigneten Ort dafür finden.

Na prima, feige auch noch :-) Gast...

Trotzdem:

1) Bascom kann nun mal keine mathematischen Ausdrücke verarbeiten. Basco scheitert nicht erst an hierarchisch strukturierten Ausdrücken, sondern bereits an Befehlszeilen wie:

LCD meine_variable + 1

Also muss man, wann immer dergleichen auftaucht, solchen Kladderadatsch auflösen.

z.B.

meine_variable = meine_variable + 1
LCD meine_variable

Bei Klammerrechnungen und anderen komplexen Aufgaben ist das Auslagern in eine SUB/FUNKTION sinnvoll. Zum Bleistift wenn man einen DS1621/1631 etc hochauflösend nutzen will:



Function Calc_temperature() As Word

'Value =(temperature * 100 - 25) +((slope - Counter_ds) * 100 / Slope)
Local Zwischen1 As Word
Local Zwischen2 As Word
Local Zwischen3 As Word

Temperature = Temperature * 100
Temperature = Temperature - 25

Zwischen1 = Slope - Counter_ds
Zwischen2 = Zwischen1 * 100
Zwischen2 = Zwischen2 / Slope

Zwischen3 = Temperature + Zwischen2

Calc_temperature = Zwischen3

End Function


Das ist lästig, aber kein Grund Bascom nicht zu nutzen.

2) Vergleiche mit Assembler zur Rechtfertigung dieser Rechenschwäche von Bascom zu gebrauchen ist unsinnig, da mit solchen Äpfel- und Birnenvergleichen jedwede Benutzung einer Hochsprache obsolet wäre.

3) RISC hat damit nun garnichts zu tun und lautet in der Langschrift nun mal Reduced Instuction Set Code. Keineswegs "Computing".

4) Es handelt sich hier bei den Punkten 1 (bezogen auf die Rechenschwäche) bis 3 nicht um "Meinungen" wie ein Moderator meinte mir mitteilen zu müssen, sondern schlicht um Tatsachen. Bezüglich der semantischen Seite der Angelegenheit gibt der Oxford Dictionary Auskunft. Demnächst würden wir uns dann eben auch darüber unterhalten müssen, wenn jeman der "Meinung" ist, die Erde sei eine Scheibe.

Henrik

pebisoft
17.07.2005, 22:17
ich habe auch ca 8 monate mit bascom gearbeitet, bin dann nach winavr-c umgestiegen. der grund: bacom geht zu grosszügig mit der umsetzung um.
7 oder 8 register werden bei der kleinsten aufgabe gepusht und gepopt, das ist sehr zeitintensiv. bei jedem kleinen sensor wird ein timer genutzt, obwohl das manchmal nicht immer nötig ist. der OC1A wird für ein ir-signal-sender genommen z.b., obwohl man den auch ohne proggen kann, habe ich in winavr-c bewiesen. bascom kann man zwar per interrupt steuern lohnt aber nicht, weil die sub-routinen zu lange dauern. es ist nicht für mehrere sensoriken am robby geeignet .
als anfängersprache gut, für ein halbprofi überfordert.
mfg pebisoft

chr-mt
17.07.2005, 23:41
als anfängersprache gut, für ein halbprofi überfordert.
Warscheinlich werden viel mehr professionelle Sachen in BASCOM programmiert als man glaubt ;)
Dem Kunden ist es schließlich vollkommen egal, welche Programmiersprache sein Gerät hat, ob sie sinnvoll mit Resourcen umgeht oder was auch immer.
Heutzutage zählt eben auch die schnelle Umsetzung eines Projektes.
Und mit Bascom kommt man sehr schnell zu einem Ergebniss.

Daß Bascom Schwächen hat ist klar, aber für mich überwiegen ebenfalls die Vorteile.
Bis jetzt habe ich noch jedes Projekt mit Bascom zum benötigten Zeitpunkt (manchmal sehr knapp :) ) und mit der geforderten Funktionalität zum laufen gekriegt.

Da ich nicht der große Crack im programmieren bin, ist Bascom für mich ideal.
Mit C oder anderen Programmiersprachen konnte ich mich nie anfreunden.
Habe zwar gerne auf dem 8051 Assembler gemacht, aber das ist lange her..

Gruß
Christopher

Frank
17.07.2005, 23:56
Dem kann ich mich auch anschließen, bei mir gabs auch noch keine Aufgabe die mit Bascom nicht optimal lösbar gewesen wäre. Es mag einzelne Libary Funktionen geben die man besser oder optimierter anlegen könnte, aber das ist bei GCC auch der Fall. Bis man ein mittelgroßes Projekt mit GCC realisiert hat, hat man in der Regel bereits zwei in Bascom entwickelt. Vorausgesetzt man hat sich etwas in die Sprache eingearbeitet.

Aber das mathematischen Formeln in mehrere Zeilen gesplittet werden müssen ist ohne Frage ein Bascom Nachteil, insbesondere auch für Einsteiger. Allerdings gewöhnt man sich an dieses Manko und es hat sogar den Vorteil das man oft etwas gedankenvoller programmiet. Und da diese Vorgehensweise etwas näher der Maschinensprache ist, dürfte der Compiler bei komplexen Rechnungen auch den besseren optimierteren Code erzeugen.
Angesichts der enormen Produktivität von Bascom nehme ich dieses kleine Manko gerne in Kauf.
Das schöne an Bascom ist auch das Projekte in eier einzigen BAS Datei realisiert werden. Schaut Euch mal dagegen ein C-Projekt an, viele Header-Dateien,C-Files, Projektdateien müssen angelegt werden. Sowas ist bei Mamut PC-Projekten ja manchmal ganz nett, aber bei einem kleinen Controllerprogramm nervt es mich doch erheblich.


@hrei Übrigens möchte Dich doch bitten den Tonfall vieler Deiner Postings nochmal zu überprüfen und zukünftig zu verbessern. So ein rauhen Ton mögen wir nicht so sehr im Roboternetz, das kann man auch anders formulieren.

Gruß Frank

chr-mt
18.07.2005, 00:06
Das schöne an Bascom ist auch das Projekte in einer einzigen BAS Datei realisiert werden.
Stimmt, das ist sehr angenehm.

Ich bin bei größeren Projekten allerdings dazu übergegangen, mehrere Dateien zu verwenden und die dann per
$include "xxxxx.bas" einzubinden.
Bei Fehlern öffnet Bascom die entsprechende Datei und zeigt den Fehler richtig an.
Das ganze ist sehr praktisch, hat allerdings den Nachteil, daß Bascom nur im jeweils geöffneten File suchen kann.
Wenn man also irgendwas sucht, muß man sich unter Umständen durch alle Files durchhangeln...

Gruß
Christopher

PicNick
18.07.2005, 10:29
..., muß man sich unter Umständen durch alle Files durchhangeln...

Is richtig, aber wenn du alles in einem Directory hast, kannst du dir das Windows-"Search" Fenster bereithalten.

Kjion
18.07.2005, 11:20
Es mag einzelne Libary Funktionen geben die man besser oder optimierter anlegen könnte, aber das ist bei GCC auch der Fall. Bis man ein mittelgroßes Projekt mit GCC realisiert hat, hat man in der Regel bereits zwei in Bascom entwickelt. Vorausgesetzt man hat sich etwas in die Sprache eingearbeitet.

Kommt immer auf das Projekt an. Ein Hello World hat man mit Bascom vermutlich schneller programmiert, sobald aber es aber darum geht eine komplexe Daten Ein-/Ausgabe mit mehreren Ringpuffer usw. zu realisieren ist man mit C schneller.

Außerdem kann man C mehr optimieren, da man sich mal eben den Assemblercode zu seinen C Quelltext anschauen kann. So kann man sehr schön sehen was schnell geht und was viel Platz verbraucht und es entsprechend umgestalten.

Beispiel:

void uart_put_hex(uint8_t data)
{
786: cf 93 push r28
788: 98 2f mov r25, r24
uint8_t hi, low;

/* Obere 4-bit */
hi = data & 0xf0;
hi >>= 4;
78a: 82 95 swap r24
78c: 8f 70 andi r24, 0x0F ; 15
hi += '0';
78e: 80 5d subi r24, 0xD0 ; 208
if ( hi > '9')
790: 8a 33 cpi r24, 0x3A ; 58
792: 08 f0 brcs .+2 ; 0x796
hi += 7; // A..F
794: 89 5f subi r24, 0xF9 ; 249

/* Untere 4-bit */
low = ( data & 0x0f ) + '0';
796: 9f 70 andi r25, 0x0F ; 15
798: c9 2f mov r28, r25
79a: c0 5d subi r28, 0xD0 ; 208
if (low > '9')
79c: ca 33 cpi r28, 0x3A ; 58
79e: 08 f0 brcs .+2 ; 0x7a2
low += 7; // A..F
7a0: c9 5f subi r28, 0xF9 ; 249

uart_putc(hi);
7a2: 0e 94 36 03 call 0x66c
uart_putc(low);
7a6: 8c 2f mov r24, r28
7a8: 0e 94 36 03 call 0x66c
7ac: cf 91 pop r28
7ae: 08 95 ret


Das schöne an Bascom ist auch das Projekte in eier einzigen BAS Datei realisiert werden. Schaut Euch mal dagegen ein C-Projekt an, viele Header-Dateien,C-Files, Projektdateien müssen angelegt werden. Sowas ist bei Mamut PC-Projekten ja manchmal ganz nett, aber bei einem kleinen Controllerprogramm nervt es mich doch erheblich.

Es spricht ja nichts dagegen das bei C auch zu tun. Aber wenn man eine einzige Datei mit über 2000 Zeile Code habe verliert man vollkommen die Übersicht.
Da ist es wesentlich angenehmer das Ganze aufzusplitten in verschiedene Dateien in denen jeweils zusammenhängender Code groupiert wird. Diese Dateien stellen dann bestimmt Funktionen als Schnittstelle zur Verfügung mit denen man den Ganzen Code nutzten kann ohne direkt verstehen zu müssen wie er im Einzelnen funktioniert :-)
Wenn man einmal das Prinzip dahinter verstanden hat und diese Feature sinnvoll nutzt lässt sich damit sehr gut programmieren...

MfG Kjion

PS: Um auch nochmal auf die ursprüngliche Frage einzugehen :

red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;
In C ist sowas kein Problem :-)

Frank
18.07.2005, 12:19
Kommt immer auf das Projekt an. Ein Hello World hat man mit Bascom vermutlich schneller programmiert, sobald aber es aber darum geht eine komplexe Daten Ein-/Ausgabe mit mehreren Ringpuffer usw. zu realisieren ist man mit C schneller.

Wiederspreche dir ja ungern, aber da liegst du falsch. Mehrere Ringbuffer habe ich schon mehrfach in Basom in Projekten programmiert, das gehört zu den einfachsten Dingen in Bascom. Immer diese Vorurteile ;-)


Es spricht ja nichts dagegen das bei C auch zu tun. Aber wenn man eine einzige Datei mit über 2000 Zeile Code habe verliert man vollkommen die Übersicht.

Genau das spricht dagegen. In C werden für gleiche Aufgaben eine Unmege mehr an Programmzeilen benötigt. Die Programmlänge (Programmzeilen) sidn durchaus 3 bis 5 mal so lang. Von dahe rbleibt einen da nix anderes übrig als aufzusplitten :-)


Da ist es wesentlich angenehmer das Ganze aufzusplitten in verschiedene Dateien in denen jeweils zusammenhängender Code groupiert wird. Diese Dateien stellen dann bestimmt Funktionen als Schnittstelle zur Verfügung mit denen man den Ganzen Code nutzten kann ohne direkt verstehen zu müssen wie er im Einzelnen funktioniert :-)

Wie gesagt bei sehr komplexen PC Programmen die immer wieder gleiche Routinen verwenden, stimme ich dir zu. Aber weniger bei Controllern, da die Programme einfach zu unterschiedlich sind. Insbesondere wenn man eine so umfangreiche Libary wie in Bascom nutzt, ist das selten notwendig. Mir persönlich ist eine einzige Quelldatei hier viel angenehmer und übersichtlicher. Aber auch das ist sicher etwas Ansichtssache

Kjion
18.07.2005, 12:27
Vielleicht sollten wir einfach mal Würfeln was besser ist. Beide Seiten werden sich vermutlich nicht so recht davon überzeugen lassen das der andere Recht hat :-)

Also belassen wir es mal dabei, es ging hier ja um was anderes.

MfG Kjion

PS: Auch wenn C natürlich viel besser ist :-)

JanB
18.07.2005, 12:42
Hi Kijon,
könntest du zu so einer C-Zeile wie z.B:
" red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;"
auch mal den erzeugten ASM-Code zeigen,
wie in deinem ersten Beispiel.
Den würde ich mir gern mal anschauen.

Gruß Jan

PicNick
18.07.2005, 13:35
" red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;"
sieht schlimmer aus, als es ist. Das ist ja gerade die c-Schwelle, wo viele kleben bleiben.
Interessant, daß er die Werte im Motorola-Format (network order?)angelegt hat.
Aber daß er "2*i" u. "*256" wirklich hinschreiben würde, kann ich kaum glauben.

JanB
18.07.2005, 14:55
Hi Robert,

sieht schlimmer aus, als es ist
Nee, ist schon klar :-) da hab ich kein Problem mit.

Ich hätte nur gern mal gesehen wie C einen etwas komlizierteren Ausdruck
in ASM übersetzt.
Speziell, wie C das mit dem notwendigen Zwischenspeicher regelt.
Wird alles durch den Stack geschoben, oder wird Speicher alloziert oder was ?

Das dürfte doch auch das Problem sein, das die BASCOM-Programmierer davon abhält,
einen ordentlichen Parser einzubauen, der auch komplexere Ausdrücke
in einer Anweisung zulässt.
Bei einem kleinen AVR mit nur 128Byte RAM oder so ist da nämlich schnell Ende.

Gruß Jan

PicNick
18.07.2005, 15:13
Ich hätte nur gern mal gesehen wie C einen etwas komlizierteren Ausdruck in ASM übersetzt.
Eigentlich kein Problem, er gibt ja eine Assembler-Liste her. Sehr lehrreich auch, wenn man erstmal den Optimizer abmurkst und dann "mit" vergleicht.
Es ist ja eigentlich mehr eine Arbeit für den Compiler, die innersten ausdrücke zu finden und dann gemütlich nach außen zu wandern.
Malloc wird er nicht nehmen, behaupt ich mal, er wird ja wohl deswegen keine Heap-Verwaltung starten. Wahrscheinlich stackt er sich eins.
Ich kann ja mal ein Programm zum Gucken stricken. Kann lustig sein.

Kjion
18.07.2005, 15:26
Ich hätte nur gern mal gesehen wie C einen etwas komlizierteren Ausdruck in ASM übersetzt.

kommt schon :-)


red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;
824: f7 01 movw r30, r14
826: 80 81 ld r24, Z
828: 99 27 eor r25, r25
82a: 98 2f mov r25, r24
82c: 88 27 eor r24, r24
82e: 21 81 ldd r18, Z+1 ; 0x01
830: 33 27 eor r19, r19
832: 82 2b or r24, r18
834: 93 2b or r25, r19
836: 95 95 asr r25
838: 87 95 ror r24
83a: 95 95 asr r25
83c: 87 95 ror r24
83e: 68 2f mov r22, r24

Der gcc optimiert sowas eigentlich ganz gut.

Wie man erkennt kann läd er zuerst die Adresse des Array boden_value_red0 in das Register Z. Darüber lädt er den ersten Teil des Ausdrucks in die Register r24,r25 den zweiten in r18,r19, löscht die entsprechenden Bytes und verodert beides und schiebt es zweimal nach rechts.
Dann wird das Ergebnis in r22 kopiert, in welchem der Wert für red0 gespeichert ist.

Sehr viel besser hätte ich das jetzt von Hand auch nicht hinbekommen ( zwei Befehle kann man einsparen, wer findet sie ? :-) )

MfG Kjion

PicNick
18.07.2005, 15:34
Und einmal ohne optimize, auch nicht so schlimm



.NOLIST
.INCLUDE "M16DEF.INC"
.LIST
INIT:
JMP L_0x0054
.............
L_0x0054:
CLR r1
OUT SREG,r1
LDI YL,0x5F
................
JMP L_0x008E
L_0x008A:
JMP INIT


unsigned char boden_value_red0[16];

void main()
{
unsigned short red0;
unsigned char i;

red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;
return;
}

L_0x008E:
LDI YL,0x5C
LDI YH,0x04
OUT SPH,YH
OUT SPL,YL
LDD r24,Y + 3
MOV r18,r24
CLR r19
MOVW r24,r18
ADD r24,r18
ADC r25,r19
MOVW ZL,r24
SUBI ZL,0xA0
SBCI ZH,0xFF
LDD r24,Z + 0
MOV r18,r24
CLR r19
LDI r24,0x00
LDI r25,0x01
MUL r18,r24
MOVW r20,r0
MUL r18,r25
ADD r21,r0
MUL r19,r24
ADD r21,r0
CLR r1
LDD r24,Y + 3
MOV r18,r24
CLR r19
MOVW r24,r18
ADD r24,r18
ADC r25,r19
MOVW ZL,r24
SUBI ZL,0x9F
SBCI ZH,0xFF
LDD r24,Z + 0
CLR r25
OR r24,r20
OR r25,r21
ASR r25
ROR r24
ASR r25
ROR r24
STD Y + 1,r24
STD Y + 2,r25

JMP L_0x00EA

L_0x00EA: ; return
RJMP L_0x00EA


In der Version sieht man, was sich so ein Compiler denkt bei der Arbeit

Beim Optimieren hat er ja dann gemerkt, daß er sich das Meiste ersparen kann.

PicNick
18.07.2005, 16:02
Ich hab's ein bißchen kommentiert, wenn das wen interessiert



red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;

L_0x008E:
LDI YL,0x5C
LDI YH,0x04
OUT SPH,YH
OUT SPL,YL ; work frame
LDD r24,Y + 3 ; get i
MOV r18,r24
CLR r19
MOVW r24,r18 ; --> r24
ADD r24,r18 ; * r18 ---> = *2
ADC r25,r19 ; vielleicht n'carry, weiß man ja nie
MOVW ZL,r24 ;
SUBI ZL,0xA0 ; + 96 = (&boden_value_red0[0])
SBCI ZH,0xFF ; + 96 = (&boden_value_red0[0])
LDD r24,Z + 0 ; r24 = boden_value_red0[2*i]
MOV r18,r24 :r18:r19
CLR r19
LDI r24,0x00 ;r24:r25 = 256
LDI r25,0x01
MUL r18,r24 ; * 256
MOVW r20,r0 ;-> r20
MUL r18,r25
ADD r21,r0
MUL r19,r24
ADD r21,r0 ;-> r21
CLR r1 ; heilige Kuh, muß null sein

LDD r24,Y + 3 ; get i
MOV r18,r24 ; s.o
CLR r19 ; s.o
MOVW r24,r18 ; s.o
ADD r24,r18 ; s.o
ADC r25,r19 ; * 2 (s.o.)

MOVW ZL,r24
SUBI ZL,0x9F ; + 95 = (&boden_value_red0[1])
SBCI ZH,0xFF

LDD r24,Z + 0 ; r24 = boden_value_red0[2*i + 1]
CLR r25

OR r24,r20 ; r24 | r20
OR r25,r21 ; r24 | r21

ASR r25 ; >> 1
ROR r24
ASR r25 ; >> 1
ROR r24
STD Y + 1,r24 ; store red0
STD Y + 2,r25

JMP L_0x00EA ; forEver
L_0x00EA:
RJMP L_0x00EA


Listig, daß er das +1 rechts gleich in das Tabellen-Offset eingebaut hat.

JanB
18.07.2005, 16:47
Hallo,
Danke, der erzeugte Code sieht wirklich ganz gut aus.
Schön ist auch, das C das mit Registern regelt, und nicht
stur das RAM benutzt. Wirklich interessant.

Das Array scheint allerdings ein Byte-Array zu sein,
denn er lädt nur Bytes.
Aber C behandelt die Werte ständig als INT. Deshalb
könnte man da deutlich mehr als zwei Befehle weglassen.

Gruß Jan

Hier mal mein Vorschlag:


red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;
824: f7 01 movw r30, r14
826: 80 81 ld r24, Z ;ersetzen durch "ld r25,Z"
828: 99 27 eor r25, r25 ;weglassen
82a: 98 2f mov r25, r24 ;weglassen
82c: 88 27 eor r24, r24 ;weglassen
82e: 21 81 ldd r18, Z+1 ;ersetzen durch "ldd r24, Z+1"
830: 33 27 eor r19, r19 ;weglassen
832: 82 2b or r24, r18 ;weglassen
834: 93 2b or r25, r19 ;weglassen
836: 95 95 asr r25
838: 87 95 ror r24
83a: 95 95 asr r25
83c: 87 95 ror r24
83e: 68 2f mov r22, r24

oder netto (und gleich r22 benutzt):
movw r30, r14
ld r18, Z
ldd r22, Z+1
asr r18
ror r22
asr r18
ror r22

macht 7 Befehle (und Takte) statt 14

PicNick
18.07.2005, 16:50
Jetzt hab ich den BasCom gequält (nur was für Erbsenzähler)



' red0 = (boden_value_red0[2*i]*256 | boden_value_red0[2*i + 1]) >> 2;

Dim Red0 As Word
Dim Boden_value_red0(16) As Byte
Dim I As Byte

Dim X1 As Byte

X1 = I * 2
Red0 = Boden_value_red0(x1) * 256
Incr X1
Red0 = Red0 Or Boden_value_red0(x1)
Shift Red0 , Right , 2

End

RED0 Word 0060 96
BODEN_VALUE_RED0 Byte (16) 0062 98
I Byte 0072 114
X1 Byte 0073 115


; X1 = I * 2
LDS r16,0x0072 ; r16 = i
LDI r20,0x02 ; r20 = "2"
MUL r16,r20 ; mul
LDI XL,0x73
LDI XH,0x00
ST X,r0 ; X1

; red0 = tab (X1) * 256
LDI XL,0x73 ; X1
LDI XH,0x00
LD r10,X+ ;
CLR r11 ;
LDI XL,0x61 ;
LDI XH,0x00
ADD XL,r10
ADC XH,r11 ; tab[X1]

LD r16,X+ ; r16:r17 = tab[X1]
CLR r17
LDI r20,0x00
LDI r21,0x01 ; r20:r21 = "256"
CALL L_0x012E ; multiply
LDI XL,0x60
LDI XH,0x00
ST X+,r16
ST X,r17 ; red0 = tab[i*2] * 256

; incr X1
LDI XL,0x73
LDI XH,0x00
LD r24,X
SUBI r24,0xFF
ST X,r24

; red0 = red0 OR tab(x1)
LDI XL,0x60 ;
LDI XH,0x00
LD r16,X+
LD r17,X ; r16:r17 = red0

LDI XL,0x73 ; s.o.
LDI XH,0x00
LD r10,X+
CLR r11
LDI XL,0x61 ; tab -offset
LDI XH,0x00
ADD XL,r10
ADC XH,r11
LD r20,X r20:r21 = tab(i*2 + 1)
CLR r21

OR r16,r20
OR r17,r21
LDI XL,0x60
LDI XH,0x00
ST X+,r16 ;red0
ST X,r17


; shift red0, right, 2
LDI r25,0x02 ; = "2"
LDI XL,0x60 ; &red0
LDI XH,0x00
CALL L_0x0158 ; shift right

;---------------END---------------
CLI

L_0x00EA:
RJMP L_0x00EA


;------------------- r16:r17 *= r20:r21 -----------
L_0x012E:
PUSH r0
MUL r16,r20
MOV r2,r0
MOV r3,r1
MUL r20,r17
ADD r3,r0
MUL r21,r16
ADD r0,r3
MOV r16,r2
MOV r17,r0
POP r0
RET

;-------- shift @(xL:xH) right r25 times
L_0x0158:
CPI r25,0x00
BREQ L_0x016C
LD r16,X+
LD r17,X
L_0x0160:
LSR r17
ROR r16
DEC r25
BRNE L_0x0160
ST X,r17
ST -X,r16
L_0x016C:
RET


Also ganz brav, er verwendet zum Multiplizieren und zum Shiften Library-Functions. Brauch dadurch mehr platz, aber dann hat er das ein für alle Mal.

PicNick
18.07.2005, 16:52
Er verwendet INT, weil das Zielfeld den Datentyp vorgibt.
Da müßt man ein bißchen "Casten", könnte nützen.

JanB
18.07.2005, 16:53
Uhh.. da haben wir wieder den guten alten Vergleich
BASCOM - C - ASM
Das hat noch nie zu einem eindeutigen Ergebnis geführt.

Aber was solls, ich bin auch mit Schuld...

Gruß Jan

PicNick
18.07.2005, 17:01
Genau. Was gibt er keine Ruhe.
Für jede Sprache gibt's Fans, und alle rufen jetzt "gewonnen"