PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Inline Assembler - Register



s.o.
20.05.2007, 14:56
Hallo,

meine Inline-Asm-Funktion Funktion arbeitet mit den Variablem wenn es ausgeführt wird, dabei bleibt aber nicht mehr der Ausganzustand der Register vorhanden.

Gcc jedoch meint, diese dann immer noch benutzen zu können, wie kann ich es ihm ausreden?

Anmerkung: Ich möchte sichern (sprich mov) gerne aus Zeitgründen vermeiden.

Danke

EDIT: Ich habe ein Arbeitsregister gemacht. Wenn jemand eine bessere Lösung hat, her damit!

SprinterSB
15.06.2007, 08:06
Da gibt es prinzipiell mehrere Möglichkeiten (siehe Link)

-- das Register als clobbered markieren
-- ne lokale C-Variable als output-Operand verwenden
-- das temporäre Register verwenden (R0)
-- man schreibt alles in eine Funktion und ruft die über nen Stub auf. als register hat man dann alle call clobberer register zur Verfügung


https://www.roboternetz.de/wissen/index.php/Inline-Assembler_in_avr-gcc

wkrug
15.06.2007, 10:48
Wenn Du in deinem Assembler Programm die benötigten Register und das SREG mit "PUSH" auf den Stack schiebst und am Ende deines Assembler Programms die Register + SREG mit "POP" wieder von Stack holst dürfte sich C nicht dran stören ?!
Bei 3 Registern sind das 10 zusätzliche Kommandos.
Register die "C" während Interruptroutinen dauerhaft verändert musst Du natürlich in Ruhe lassen.

SprinterSB
02.08.2007, 18:31
Wenn Du in deinem Assembler Programm die benötigten Register und das SREG mit "PUSH" auf den Stack schiebst...

...hat man das Henne-Ei-Problem. Denn SREG und andere SFR kann man nicht direkt pushen/poppen und muss stattdessen über ein normales Register gehen. Dies wiederum muss man verträglich mit der avr-gcc ABI machen (d.h. imEndefekt gcc die Registerberwaltung überlassen), damit man nicht irgendwelche Registerinhalte zerstört.

wkrug
02.08.2007, 19:25
d.h. imEndefekt gcc die Registerberwaltung überlassen), damit man nicht irgendwelche Registerinhalte zerstört.
Eins vorneweg, ich progge nicht mit GCC.

Da aber alle Compiler im Endeffekt Maschinencode erzeugen seh ich das nur bedingt so.
Als Register kann man natürlich nur solche verwenden die GCC nicht während eines Interrupts verändert - das ist klar.
Aber alle anderen Register sollten mit dieser Methode nutzbar sein.

z.B.
PUSH r16
IN r16,SREG
PUSH r16
....
POP r16
OUT SREG,r16
POP r16
RETI

sollte die verwendeten Register genauso wieder zurücklassen, wie Sie vor dem Aufruf waren.
Während eines Interrupts kann ohnehin kein zweiter Interrupt aufgerufen werden (Es sei denn GCC gibt das explizit frei ?! ).
Bei einem "normalen" Unterprogramm muss man halt gucken welche Register nutzbar sind, sprich durch GCC nicht selbstständig in Interruptroutinen verändert werden.

izaseba
02.08.2007, 20:26
@wkrug, das siehst Du zwar richtig, aber inlineassembler bei gcc ist so eine Sache.
Um sich die Vorüberlegungen zu sparen überläßt man die Wahl der Register dem Kompiler, man gibt nur an ob es ein unterer oder oberer Register sein soll, der Rest interessiert einen nicht mehr!

Der Sprinter hat doch einen super Artikel zum Thema geschrieben, der Link ist ein paar Beiträge drüber angegeben.

Gruß Sebastian

P.S.
Ich persönlich mag den gcc Inlineassembler nicht besonders,er hat einen ziemlich komischen Syntax, gut daß ich ihn persönlich sehr selten brauch...