Ich glaube, ich verstehe die Frage nicht richtig.
Ohne das "mov" verliere ich den Wert im Register @0 beim "ldi", den ich
für mein "eori" verwenden möchte. Und beim "eor" würde ein unbestimmter
Wert aus temp2 verarbeitet werden.
Oder übersehe ich da was?
Ville schrieb:> Ohne das "mov" verliere ich den Wert im Register @0 beim "ldi", den ich> für mein "eori" verwenden möchte. Und beim "eor" würde ein unbestimmter> Wert aus temp2 verarbeitet werden.
Ja schon, aber warum nimmst du kein temporäres Register >= R16 und lädst
direkt darein?
Genau, man weiss ja nicht, welches Register @0 ist. Daher habe ich eins
kleiner gleich r15 für temp2 gewählt. Und "ldi" sichert ab, dass @0
grösser gleich r16 ist. Ein Überschreiben ist somit ausgeschlossen.
Jobst M. schrieb:> Und was überschreibt man sich bei:
Wenn @0 = temp2
Aber wenn man ernsthaft mit Macros arbeiten will, nicht bloss diesem
einen, dann sollte man mindestens 1 Register für Macros reservieren. Ist
sonst witzlos, denn oft hat man ein Register frei, was die push/pop
Befehle unnötig macht.
A. K. schrieb:> Wenn @0 = temp2
Nö. Das Problem hat er auch so. Wenn das Macro zu Ende ist, wird temp2
wieder vom Stack geholt und der alte Wert hergestellt.
Gruß
Jobst
Jobst M. schrieb:> ...wird temp2 wieder vom Stack geholt und der alte Wert hergestellt.
Richtig so. Es soll ja auf Register @0 ein XOR mit dem Wert @1
stattfinden und temp2 am Ende unverändert sein.
A. K. schrieb:> ...dann sollte man mindestens 1 Register für Macros reservieren.
Das habe ich mir schon gedacht. Dann werde ich das wohl so machen -
spart ja auch Programmspeicher, wenn ich die Pushs/Pops weglassen kann
(gerade, wenn man das Macro öfter im Code verwendet). Ich wollte nur
sicher gehen, dass es nicht vielleicht doch eine kleverere Lösung gibt.
Danke an alle!
Ville schrieb:> hin und wieder bräuchte ich auf dem Atmega8 ein XOR with immediate.
Man kann es auch übertreiben.
Für das doch eher seltene "hin und wieder" halte ich das Verstecken in
einem Makro für Blödsinn. Die Erwiderungen oben zeigen die Risiken
bezüglich der verwendeten Register auf.
"Hin und wieder" kann man den Assemblertext auch ausschreiben, und kennt
im konkreten Fall die nutzbaren Register.
Noch ein Risiko:
Dieses EORI Rx,K sieht in einem Assemblerlisting zunächst mal aus wie
ein einzelner CPU-Befehl. Deshalb übersieht man leicht, dass evtl. mal
ein
Interrupt genau in Macro "reinhauen" kann.
Das kann zu schwer zu findenden, weil nur sporadisch auftretenden
Fehlern führen. Ich hab selbst mal Tage damit verbracht, so einen blöden
Fehler zu finden. Ein Antrieb, der ansonsten sauber lief, "zuckte" so
etwa ein bis zwei mal pro Stunde ganz kurz. Ursache war ein kleines
Macro wie oben. Die Chance war klein, aber ein Interrupt schaffte es
trotzdem ab und zu, genau in den Macro und veänderte ein Register das
der Macro per PUSH gesichert hatte. Die Änderung war dann nach dem POP
verloren. Das auch für den Macro der Wert geändert wurde, war in diesem
Fall nicht tragisch.
Also nicht nur PUSH und POP sondern auch CLI und SEI. besonders, wenn
man das Macro öfters auch in späteren Projekten einsetzen will.
Führt natürlich zu dem neuen Problem, das man dem EORI nicht ansieht,
das wärend der Ausführungszeit die INTs gesperrt sind...
MfG Willi
Willi schrieb:> aber ein Interrupt schaffte es> trotzdem ab und zu, genau in den Macro und veänderte ein Register das> der Macro per PUSH gesichert hatte.
Da ist aber nicht das Macro schuld, sondern der Interrupt, der sich
nicht an die Regeln hält.
@Willi: Was du da schilderst, hat doch nichts mit Macros zu tun. Es ist
doch egal, ob der Code automatisch durch das Macro erzeugt wird, oder ob
ich ihn selbst eintippe.
Klingt mir eher danach, als hättest du die in der ISR verwendeten
Register nicht auf dem Stack gesichert. CLI und SEI sind hier nicht
notwendig.
Ville schrieb:> Richtig so. Es soll ja auf Register @0 ein XOR mit dem Wert @1> stattfinden und temp2 am Ende unverändert sein.
Und bei der Bedingung, dass @0 = temp2 ist @0 anschliessend unverändert.
Richtig so?
Gruß
Jobst
Jobst M. schrieb:> Ville schrieb:>> Richtig so. Es soll ja auf Register @0 ein XOR mit dem Wert @1>> stattfinden und temp2 am Ende unverändert sein.>> Und bei der Bedingung, dass @0 = temp2 ist @0 anschliessend unverändert.> Richtig so?
Kann nicht passieren,
schon im ersten Post steht doch das @0 nur die Register r15 bis r31
annehmen kann (wie bei immidate Befehlen üblich - ok könnte man noch per
if prüfen) temp2 aber Register r12 ist.
Sascha
Und ich sag wieder mal was ganz böses: Wer für so etwas basal simples
eine Frage in einem Forum stellen muss, versucht sich vielleicht besser
an etwas noch simplerem als 8 Bit Assembler.
Sascha W. schrieb:> schon im ersten Post steht doch das @0 nur die Register r15 bis r31> annehmen kann (wie bei immidate Befehlen üblich - ok könnte man noch per> if prüfen) temp2 aber Register r12 ist.
Man kann sich durch geeignete Randbedingungen das Leben so schwer wie
möglich machen. Also beispielsweise, indem man vorrangig jene Register
für temporäre Zwecke reserviert, die dafür am wenigsten geeignet sind.
Wie R0-15.
Ohne Reservierung eines geeigneten Registers gibt es schlicht keinen
wirklich kurzen eleganten Weg, den fehlenden Befehl zu ersetzen. Also
bleibt eigentlich nur, entweder ein Register für Makroverwendung zu
reservieren, oder auf den Makro zu verzichten.
Dazu kommt freilich auch, dass AVRs Assembler durch recht überschaubare
Leistungsfähigkeit glänzt. Assembler, die für umfangreiche
Makroprogrammierung konzipiert wurden, sehen anders aus. Atmel setzt
offenbar eher auf Programmierung in C.