Guten Morgen! Ich kenne mich in der Makroprogrammierung nicht aus deshalb hoffe hier auf Unterstützung. Ich programmier 8051 derivate d.h. wenn jemand Macros Bsp. in AVR postet werd ichs wohl nicht verstehen. Ich wollte die Steuerung der Cursorpositon am LCD in Assembler vereinfachen und da dachte ich an Macros. Ich würde es gerne in dieser form haben wollen: cursor(x,y). Ich hab mich zwar schon etwas belesen aber ich komm damit nicht klar (Macro anlegen, parameterübergabe usw.). Das nächste problem ist das ich es gerne in andere Module verwenden möchte z.B. über PUBLIC bekannt geben. Kann mir jemand ganz einfach erklären wie ich so was realisieren kann? Worauf man achten soll usw. Gruss Norad
sowas sollte man nicht unbedingt als Makro programmieren, da es dann bei jedem Aufruf in der vollen Grösse mit verschiedenen Parametern ins Programm eingebunden wird. D.h., wenn du in deinem Programm 10x gotoxy(x,y) verwendest, steht auch der Code dafür 10mal in nur leicht abgewandelter Form in deinem Speicher. Das ist nicht effektiv und kann ganz schnell dazu führen, dass dir der Programmspeicher ausgeht. Dafür benutzt man Funktionen. Wie machst du das nun? Erstmal schreibst du ein Unterprogramm, das wird mit call aufgerufen und mit ret beendet. Bleibt die Frage der Parameterübergabe, dafür gibts etliche Varianten, alle mit Vor- und Nachteilen. -globale Variablen (feste Speicherplätze), meist von Anfängern benutzt, kaum Konfliktpotential, aber nicht sehr effektiv in der RAM-Nutzung -in deinem Fall mit nur 2 Byte in A und B -in den Registern, evtl. mit Registerbankwechsel -über den Stack (da muss man ziemlich aufpassen, aber otimale Ramnutzung) -einen Speicherbereich, adressiert über den DPTR Mit 8051-ASsemblerbeispielen kann ich dir nicht dienen, das ist zu lange her und würde wohl mehr Fehler als nutzbare Infos enthalten :-)
@crazy horse Vielen Dank für deine Infos! Also so vorteilhaft scheinen Makros doch nicht zusein, da bläst man seinen Code unnötig auf. Die Idee werd ich mal ganz schnell wieder verwerfen und werde mal das mit den Registern A und B versuchen oder über Stack. Nochmal vielen Dank Gruß Norad
Ich würde an deiner Stelle lieber mit den Registern arbeiten. Zumindest A wirst du ja im Unterprogramm wieder benötigen. mov R0, #10 //x-pos mov R1, #2 //y-pos acall cursor
moin moin, ;------------------------- mov R0, #10 //x-pos mov R1, #2 //y-pos acall cursor ;------------------------- das dann bitte aber auch als macro, bin nämlich schreibfaul. Je nach verwendetem Assembler sieht das dann so aus: PosXY macro x,y //die Definition mov R0, #x //x-pos mov R1, #y //y-pos acall cursor //auf Pos stellen EndM ;-------------------------- ; Nutzung als PosXY 1,10 Bei festen POS-Angaben ist das macro vorteilhaft. Welche Register genommen werden ist in der Macrodefinition und im UP Cursor festgelegt. Soll da was geändert werden, braucht nicht der ganze Quelltext durchgesucht werden. Ausserdem wird die Quelle übersichtlicher, bei mir stecken ganze Berechnungen in Macros. Sieht dann aus wie Hochsprache. Mit Gruß Pieter
Hallo Pieter! Genau sowas brauch ich aber bläst das nicht den code auf oder belegt den Speicher unötig wenn mans zu oft aufruft? sowie crazy horse meinte. Oder stimmt dass nicht? Wenn ichs richtig begriffen habe macht ein Macro so etwas wie ne Textersetzung. gruß norad
Das Makro von Pieter erleichtert dir einfach nur die Schreibarbeit. Alles, was in dem Makro definiert wird, müsstest du sowieso im Programmcode schreiben. Würdest du jetzt das acall cursor durch die Funktion selbst ersetzen, würde das natürlich den Programmcode unnötig aufblähen. Es erhöht dabei auch die Übersichtlichkeit. Wie crazy horse schon schrieb, wird das, was in dem Makro steht (vom Compiler) in den Quellcode kopiert. Du sparst also Tipparbeit...
moin moin, im laufe der Zeit habe ich eine Macro.INC-Datei zusammengeschrieben. Da gibt es u.a: ;-------------------------------------- ;Compare And Jump Equal CJE MACRO Register, Value, Target CJNE Register, Value, @@1 JMP Target @@1: ENDM ;-------------------------------------- ;Compare And Jump Less CJL MACRO Register, Value, Target CJNE Register, Value, @@1 @@1: JC Target ENDM ;-------------------------------------- ;Compare And Jump Less Or Equal CJLE MACRO Register, Value, Target CJNE Register, Value, @@1 SETB C @@1: JC Target ENDM ;-------------------------------------- ;Compare And Jump Greater CJG MACRO Register, Value, Target CJNE Register, Value, @@1 SETB C JNC Target @@1: ENDM ;-------------------------------------- ;Compare And Jump Greater Or Equal CJGE MACRO Register, Value, Target CJNE Register, Value, @@1 @@1: JNC Target ENDM ;-------------------------------------- als Ergänzug zum OP-Code die "fehlenden" bedingten Sprünge. Diese können nicht als Unterprogramm verwendet werden. Der Syntac ist mit CJNE identisch. Es geht bei Macros nicht vorrangig darum Code zu sparen, sondern um die Lesbarkeit einer Quelle. Mit Gruß Pieter
@Pieter Kann man ein Makro auch mit Public für andere Module sichtbar machen d.h. kann man ein Makro auch in einem anderem Modul nutzen? Hast Du dafür vielleicht ein Beispiel?
moin moin, mein Assembler ist Marke Eigenbau, daher kann ich zu anderen nichts sagen. Einfach mal ausprobieren. Mit Gruß Pieter
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.