banksel so oder so schreiben?

OP #7381934
Lesenswert?

Hallo zusammen, ich habe folgende Unsicherheit:

Ich definiere "STROM", wie folgt: #define STROM LATB,7

Um "STROM" zu verändern, habe ich die folgende Möglichkeit: banksel LATB bcf STROM banksel .0

Besser würde mir gefallen, wenn ich schreiben könnte: banksel STROM bcf STROM banksel .0

Sind beide Schreibweisen gleichwertig?

OP #7381958
Lesenswert?

Problem gelöst:

Die folgende Schreibweise funktioniert nicht und erzeugt eine Fehlermeldung.

#define STROM LATB,7

banksel STROM bcf STROM banksel .0

D.h. der Assembler gibt die Meldung aus, "Illegal character (,)". Ich kann zwar kein Komma sehen, aber wenn das funktionieren würde, würde keine Fehlermeldung kommen.

Also muss ich weiterhin schreiben:

banksel LATB bcf STROM banksel .0

Danke für die Anregung, Andreas, die letztendlich zum Ziel geführt hat!

#7381993
Lesenswert?

Du musst das Teilen. #define StromPort LATB #define StromPin 7

Dann klappt

1
banksel StromPort
2
bcf StromPort,StromPin

Vorteil ist dabei das du beliebig Port und Pin ändern kannst und Banksel trotzdem stimmt. Bei deiner Methode ist Strom und Banksel entkoppelt, und wenn du mal was änderst oder einen Codeteil woanders nochmal benutzen willst knallts, weil du oben das define geändert hast, aber nicht dran gedacht das hier und da ein banksel auch angepasst werden muss.

OP #7382010
Lesenswert?

Hallo Jens,

das ist ja toll! Es gibt also doch eine Lösung, wie ich sie am liebsten hätte! Darauf wäre ich allerdings nie alleine gekommen! Hierzu fehlt mir mindestens die Erfahrung... Das werde ich gleich einmal ausprobieren, denn genau nach dem Ändern des Portes gab es Schwierigkeiten, wie Du sie erklärt hast! Wunderbar und vielen Dank für Deine Mühe!

Michael

OP #7382609
Lesenswert?

Hallo Peter,

ich kann das gerade nicht ausprobieren, aber dennoch die Fragen:

"xbanksel(x,y)" ist scheinbar selbst definiert.

Was bedeutet "(x,y)"? Ist "x" Platzhalter für "LATB"? Ist "y" Platzhalter für die "7"? Bei "Banksel x" ist dann "x" Platzhalter für "LATB"?

Was mir sehr gut gefällt, ist, dass man dann nur noch mit dem Label "STROM" arbeitet. Die ganze Lösung ist jedenfalls - wenn sie funktioniert - äußerst raffiniert und ich frage mich, was ich tun soll, um solche Lösungen künftig selbst zu finden! Herzlichen Dank für Deine Mühe und für die Idee!

Michael

#7382619
Lesenswert?

Falls das der C Präprozessor ist, müsste das nicht eher so aussehen:

1
#define xbanksel(x) xbanksel_eval(x)
2
#define xbanksel_eval(x,y) banksel x
3
#define  STROM  LATB,7
4
  xbanksel(STROM)
5
  bcf  STROM
6
  banksel  .0

(das xbanksel_eval, weil "STROM" erst dort aufgelöst wird, und klammern bei xbanksel(STROM), weil sonst macht das doch gar nichts).

1
$ gcc -P - -E <<EOF
2
#define xbanksel(x) xbanksel_eval(x)
3
#define xbanksel_eval(x,y) banksel x
4
#define  STROM  LATB,7
5
  xbanksel(STROM)
6
  bcf  STROM
7
  banksel  .0
8
EOF
1
  banksel LATB
2
  bcf LATB,7
3
  banksel .0
OP #7382658
Lesenswert?

Hallo Daniel,

danke für den Hinweis. Ich muss aber gestehen, dass dies doch über mein Verständnis weit hinaus geht. Kannst Du mir vielleicht erklären, was die folgenden beiden Zeilen bedeuten?

#define xbanksel(x,y) banksel x #define STROM LATB,7

Ist es so, dass "x" ein Platzhalter für "LATB" ist und "y" für "7"?

Michael

#7382711
Lesenswert?

Michael B. schrieb:

#define xbanksel(x,y) banksel x #define STROM LATB,7

Ist es so, dass "x" ein Platzhalter für "LATB" ist und "y" für "7"?

#define definiert ein Macro. Macros ersetzen Text. Wenn also irgend wo im Dokument STROM vorkommt, wird es durch LATB,7 ersetzt. Kommt irgend wo xbanksel(hello, world) vor, wird es durch banksel hello ersetzt (ja, x und y sind dort Platzhalter die wiederum ersetzt werden).

Bei xbanksel(STROM) verhält es sich so, dass zuerst xbanksel() mit Parameter STROM ersetzt wird, und nicht zuerst STROM vor xbanksel. Bei der Definition oben ist das ein Argument zu wenig. Falls der Präprozessor es trotzdem zulässt, wird es mit banksel LATB,7 ersetzt werden, (Parameter x ist STROM und wird mit LATB,7 ersetzt).

Bei meinem Macro:

1
#define xbanksel(x) xbanksel_eval(x)
2
#define xbanksel_eval(x,y) banksel x

passiert in dem fall aber folgendes. xbanksel(STROM) wird zu xbanksel_eval(LATB,7) wird zu banksel LATB,7. Parameter x von xbanksel war wieder STROM, wurde aber durch LATB,7 ersetzt, bevor xbanksel_eval() ausgewertet wurde, dort wurde dann also effektiv xbanksel_eval(LATB,7) ersetzt, mit Parameter x als LATB und y als 7.

Das ganze funktioniert so hauptsächlich aus historischen gründen. Hatte sich damals wohl einfach so ergeben.

Und zum schluss noch, bei:

xbanksel STROM

Da ja xbanksel() und nicht xbanksel definiert wurde, sollte das eigentlich nicht ersetzt werden, aber ich weiss nicht, ob alle Präprozessoren das gleich behandeln. STROM würde aber trotzdem mit LATB,7 ersetzt.

PS: Es gibt da noch weitere Eigenheiten, und Tricks, wann was wie ersetzt wird. Muss man einfach wissen.

OP #7382900
Lesenswert?

Hallo Daniel,

herzlichen Dank für Deine ausführliche Erklärung und für die Zeit, die Du Dir genommen hast! Das ist ja ausgesprochen trickreich und Deine Bemerkung, dass das wohl aus "historischen Gründen" funktioniert, finde ich interessant. Gibt es eigentlich eine Textstelle, die man nachlesen könnte, um sich in diese Technik einzulesen?

Als Hobbyist, habe ich einmal nachgezählt, an wieviel Stellen meines Programmes ein relozierbarer Code nützlich wäre. Ich zähle nur 10 Stellen, die man natürlich auch so beherrschen kann. Außerdem ist es so, dass ich nur einmal den Controller / die Verdrahtung gewechselt habe. In der Folgezeit wird erst mal keine weitere Änderung stattfinden. Aber darum geht es ja nicht, sondern ich vermute, dass man mit dieser Technik noch ganz andere Sachen lösen könnte. Die Arbeit mit Macros erscheint mir an dieser Stelle ausgesprochen kompliziert und man muss schon Routine haben, sich darin fehlerfrei auszukennen.

Dennoch würde ich gerne hierüber etwas mehr erfahren und deshalb die Frage nach Textdokumenten, die zum Thema relozierbarer Code / Macros etwas aussagen.

Michael

#7382919
Lesenswert?

Daniel A. schrieb:

Das ganze funktioniert so hauptsächlich aus historischen gründen. Hatte sich damals wohl einfach so ergeben.

Das find ich interessant. Ich progge PICs schon seit 30 Jahren in Asm, aber den kannte ich noch nicht.

1
#define xbanksel(x,y) banksel x
2

3
#define STROM PORTA,7
4
#define WASSER TRISA,2
5
#define GAS BORCON,5
6

7
xbanksel(STROM)
8
bcf STROM
9
xbanksel(WASSER)
10
bsf WASSER
11
xbanksel(GAS)
12
bcf GAS

funzt bei mir in MPLAB 8.92 mit MPASM5.51 und einem ASM-Projekt für einen PIC16F1516. Nicht wegen der Namen und Register meckern, ich hab da nur schräge Werte reingekloppt damit ich das im Disasm erkenne. Die Version mit dem eval dagegen wirft Fehler.

#7382948
Lesenswert?

Jens M. schrieb:

Ich progge PICs schon seit 30 Jahren in Asm, aber den kannte ich noch nicht.

Ich habe jetzt nochmal im C Standard nachgesehen, was der dazu sagt. Ich kannte es bisher nur so wie es gcc und clang machen, aber es scheint nicht explizit definiert zu sein.

Zuerst dachte ich, es wäre in https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf Abschnitt 6.10.3 Paragraph 11, letzter Satz, beschrieben, aber dort ging es um Sachen wie MY_MACRO(#define Y\n). Dazu, in welcher Reihenfolge die 2 Typen von makros ersetzt werden, scheint nichts zu stehen...

Eventuell muss ich solche Sachen mal aus meinen Programmen raus nehmen. Dass es schon im Preprozessor UB drin haben könnte, auf die Idee bin ich vorher noch gar nie gekommen...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren