Hi, mit Unterprogramm meine ich z.B.: UART_Ausgabe: ... ret Nun möchte ich an dieses "Unterprogramm" Parameter übergeben. Im Moment mache ich dies mit festen Stellen im SRAM und eben per LDS bzw. STS. Nun war meine Idee das ganze per PUSH und POP zu machen. Wenn ich's recht verstanden habe, geht das aber nicht. Denn wenn ich im "Unterprogramm" POP sage, bekomme ich ja die Rücksprung-Adresse, richtig?!? Wie kann man sonst noch Parameter geschickt und schnell übergeben? Per festem Register-Befehl geht auch nicht, da ich die Register von R16-R31 im Unterprogramm direkt brauche und die restlichen Register nur über Umwege und nicht über ldi beschrieben werden können. Danke schonmal! Sebastian
Normalerweise ist der Umweg über den Stack sinnlos, wenn man schon einen Prozessor mit so vielen Registern hat. Du kannst doch problemlos R0-R15 verwenden, das zusätzliche mov bei der Übergabe von Konstanten tut nicht weh (ldi r16, 'a'; mov r8, r16; rcall unterprogramm).
So sinnlos kann das mit dem übergeben der Parameter per Push und Pop nicht sein, besonders wenn die Register belegt sind oder nicht ausreichen. Dass du die betreffenden Parameter nicht mit Pop bekommst ist richtig, du kannst sie aber mit push auf den Stack legen und dann in deinem Unterprogramm mit: IN ZL, SP SUBI ZL, (-5) lesen. Dabei musst du die -5 natürlich evtl. anpassen. Der Vorteil ist einfach, das das Programm universeller wird. Nach der Routine nicht vergessen die Daten wieder vom Stack zu löschen, sonst läufter der irgendwann über. MfG Mike
"Wie kann man sonst noch Parameter geschickt und schnell übergeben?" Viele Wege führen nach ROM: Von Push würde ich abraten, da man zu sehr aufpassen muß, daß der Stack immer ausbalanciert ist. Außerdem ist doch "ldi r16, 1"+"mov r2,16" schneller als "ldi r16, 1"+"push r16". Du kannst aber auch die Register erst innerhalb der Funktion pushen, wenn Du sie brauchst. Wenn die Funktion öfter aufgerufen wird, ist das sogar effektiver. Schließlich kannst Du konstante Parameter einfach hinter den Aufruf plazieren ".db xxx"und dann per "lpm" auslesen. Mit "ijmp" springt man dann dahinter zurück. Das wird z.B. gerne gemacht, um Texte auszugeben, in AVRFReaks ist dazu eine Designnote. Dann kannst Du auch einen Pointer als Parameterstack reservieren und mit "st X+, r16" und "ld r16, -X" die Parameter reinladen bzw. abholen. Peter
Hi, danke erstmal für alle Antworten! :-) Ich stell' gerade fest, daß sowohl PUSH als auch POP ja je 2 Taktzyklen brauchen. LDI und MOV brauchen jeweils 1 Taktzyklus, also gibt sich das ganze ja dann die Hand. Ich werde die Register r2 bis r15 als generelle Übergabe-Parameter verwenden, r0 und r1 brauche ich schon für MUL. Vielen Dank nochmals für die tollen Ideen! :-) Sebastian
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.