Forum: Mikrocontroller und Digitale Elektronik wofür Makros?


von Danny P. (Gast)


Lesenswert?

Hi Zusammen!

Ich programmiere nun schon länger in Assembler aber eines ist mir bis
heute nicht richtig klar und ich habe auch keine antwort im net
gefunden:

Wofür Makros?

Ich habe bisher öfter verwendete Programmstücke immer als Subroutinen
angesprungen, somit wird der Code ja auch nur einmal programmiert...
Bei Makros wird meines Wissens nach an der Stelle des Aufrufes das sich
hinter dem Makro verborgene Programmstück eingeschoben, also benötigen
mehrere Aufrufe ja auch mehr Speicher (ok, bei kleinen Sachen eher zu
vernachlässigen)...

Welche Vorteile kenn ich noch nicht und wann ist es sinnvoll Makros zu
verwenden?

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Am einfachsten kannst du das verstehen wenn du dir mal ein paar
Beispiele anschaust:
http://www.mikrocontroller.net/articles/AVR_Assembler_Makros

Das Swap-Makro vertauscht 2 beliebige Register in 3 Zyklen. Die
Register werden über Parameter übergeben; aus SWAP r15,16 wird so zum
Beispiel:
1
        eor     r15, r16
2
        eor     r16, r15
3
        eor     r15, r16

Eine solche allgemeine SWAP-Subroutine für beliebige Register wäre
nicht möglich, oder nur mit sehr hohem Aufwand realisierbar (z.B. durch
Übergabe der Registeradressen über den Stack und indirekte Adressierung
der Register).

von Danny P. (Gast)


Lesenswert?

ich hab ja versucht es an Hand von beispielen zu verstehen :-)

aber... dies setzt doch voraus das die Daten bereits in den Registern
stehen (in deinem Beispiel R15,R16)

an der Stelle wo ich die Register tauschen möchte könnte ich doch auch
einen "rcall" machen. In der Subroutine werden die Register auch
getauscht und ich komm mit ret zurück.

So wie´s für mich bisher ausschaut spare ich lediglich 2 Takte (hin-
und rücksprung).
Oder wenn ich die Programmzeilen des Makros direkt an die Stelle
schreiben würde spare ich mir halt jeweils 2 Zeilen Text...

aber ist das echt schon alles? Ich dachte es gäbe noch mehr Vorteile
oder so die ich noch nicht erkannt habe....

thx
Danny

von A.K. (Gast)


Lesenswert?

Um Befehle zu realisieren, die man gerne hätte, die es aber nicht gibt.
Beispielsweise "branch if bit clear" auf AVR:

.macro bbrc
  sbrs  @0, @1
  rjmp  @2
.endmacro

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wenn du das in einer Subroutine implementierst musst du für jedes
Registerpaar das du vertauschen möchtest eine eigene Subroutine
schreiben.

Makros sind kein Wundermittel, sie sind einfach eine sinnvolle
Möglichkeit zur Abstraktion. Wer den Trick mit dem Vertauschen mit eor
nicht kennt wird erst mal dumm gucken wenn er den Code ohne Makros
ausgeschrieben sieht; "swap" dagegen versteht jeder.

von Danny P. (Gast)


Lesenswert?

oki, mit der eigene Routine pro Registerpaar hast du Recht.

Vielleicht programmier ich auch einfach noch nicht elegant genug um
soetwas öfter zu brauchen...
Meist habe ich die zu verarbeitenden Bytes eh in den selben Registern
(benutze immer 1 bis 4 "Standartarbeitsregister") von daher gabs bei
mir noch keine Probleme das ich mehrere "gleiche" Routinen schrieben
musste


thx
Danny

von Rahul (Gast)


Lesenswert?

Eigentlich geht es dabei doch nur darum, Programmcode leserleicher zu
gestalten. Weiterhin spart man sich mit der Verwendung eines Makro auch
wieder Schreibarbeit, da der Compiler für einen das Einfügen des
gesamten Marko-Codes erledigt.
Man kann so auch einfacher Änderungen vornehmen, die dann im
Programmcode allgemeingültig sind.

von Hannes L. (hannes)


Lesenswert?

Macros haben schon ihren Sinn, solange man sie nicht wegen der Macros
selbst benutzt. Ich möchte z.B. nicht auf meine PRINT-Macros verzichten
müssen, die die benötigten Register vorbereiten (push), die Daten
übergeben, die erforderlichen LCD-Unterprogramme aufrufen und danach
die alten Registerwerte wiederherstellen. Auch das locate-Macro zur
Positionierung der LCD-Ausgabe möchte ich nicht mehr missen.

Mit dem Macro "swap" habe ich aber so meine Bedenken. Gibt das keine
Konflikte mit dem AVR-ASM-Befehl "swap", welcher die Nibbles im
Register vertauscht? (wobei ich den Algorithmus für clever halte)

Der Aufruf einer Subroutine (incl. Rücksprung) dauert aber nicht 2
Takte sondern 7 Takte. In zeitkritischen Programmteilen ist es manchmal
"billiger" auf kleine Unterprogramme zu verzichten und diesen Code
mehrfach im Programm zu haben.

...

von Danny P. (Gast)


Lesenswert?

@HanneS: ja, mit den Takten hast natürlich recht... mal wieder
geschrieben ohne zu denken :)

wie gesagt, mag an meinem "uneleganten" Programmierstil liegen :-)
bisher waren die zu bearbeitenden Daten immer in den entsprechenden
Registern der Routine.
Und ob so, oder über den Stack zu schieben ist ja "fast gleich"

aber gut nachvollziehen kann ich die von euch genannte
Übersichtlichkeit im Programm und die allgemeingültige
Änderungsmöglichkeit

thx
Danny

von Andi K. (Gast)


Lesenswert?

Hier noch ein Beispiel eines Macros zur direkten 32Bit-Addition:

.macro AddIL
  subi  @0a,-@1&255
  sbci  @0b,-@1>>8&255
  sbci  @0c,-@1>>16&255
  sbci  @0d,-@1>>24&255
.endm

Aufruf erfolgt dann einfach mit

        AddIL   CDEF,278184

Dieses CDEF stellt 4 Register dar die ich per .def in der Macrodatei
für erweiterte "Pseudobefehle" definiert habe:

 .def CDEFa=r18
 .def CDEFb=r19
 .def CDEFc=r20
 .def CDEFd=r21

Im Endeffekt kann man das auch ganz normal im Code jedesmal eingeben
aber mit Macros geht´s halt einfacher und übersichtlicher.

MfG
Andi

von Danny P. (Gast)


Lesenswert?

so :-)   ich hab mir Eure Antworten mal zu Herzen genommen und mal ein
Programm überarbeitet...

Wenn ich das Resultat sehe ärgere ich mich das ich vorher den Wald vor
lauter Bäumen nicht gesehn habe :-)

diese ganzen : ldi akku, xx
               rcall SPI_send

wirken als Makroaufruf doch erheblich übersichtlicher und eleganter

Oder ChipSelect ausführen etc...


Vielen Dank für die Anregungen :-)

greetz
Danny

von Thomas Burkhardt (Gast)


Lesenswert?

Hallo alle,

da hier wieder ein paar nette Makros erschienen sind, möchte ich
bitten, ob diese in
http://www.mikrocontroller.net/articles/AVR_Assembler_Makros
eingetragen werden können oder ob die Erlaubnis zum Eintragen gegeben
wird, falls keine Lust besteht es selbst zu tun ;-)

Besten Dank und viele Grüße

von Andi K. (Gast)


Lesenswert?

@Thomas Burkhardt:
Nur zu!

Hätte allerdings ein komplett anderes Registersystem in Verbindung mit
den Macros.
Es gibt keine Register von R16 bis R25 und R0 bis R15 sondern A bis J
und T0 bis TF.
Das hat den Vorteil, das man 16Bit-Register einfach mit AB, BC oder CD,
24Bit-Register mit ABC, BCD oder CDE und 32Bit-Register mit ABCD BCDE
oder CDEF angibt.
Will man z. B. nach einer 16Bit-Addition mit "ADDIW AB,CD" mit dem
high-Byte weiterrechnen benutzt man einfach Register B und muß nicht
überlegen, welches das nun ist.
Natürlich kann man weiterhin R16 etc. benutzen aber in Verbindung mit
den Macros eben das oben erwähnte System.
Will man eigene Registerdefinitionen machen muß man darauf achten, das
bei 16 Bit ein L für low und ein H für high als letztes Zeichen steht
(16BITL=r16 und 16BITH=r17) bei 32 Bit ein Buchstabe A, B, C und D
(32BITA=r16, 32BITB=r17, 32BITC=r18 und 32BITD=r19).
Dann kann man einfach die Macros "ADDIW 16BIT,1234" oder "ADDIL
32BIT,1234" aufrufen.

Habe mir schon überlegt das in die WiKi einzutragen, ist aber ne menge
Zeugs und weicht wegen dem Registersystem völlig von der Norm ab.
Wenn niemand was dagegen hat, schreibe ich es rein.

MfG
Andi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.