Hallo, was bedeutet diese Codezeile:? register unsigned char DATA[24]; vor allem was bringt das register davor... heißt das, dass die variable direkt mit einem Register verknüpft wird? Vielen Dank Gruß Martin
Was Deine Zeile bedeutet weiss ich nicht. :) Als Tip vielleicht: register unsigned char counter asm("r3"); Bedeutet, dass die Variable "counter" permanent in r3 bleiben soll. Vielleicht hilft das ja irgendwie weiter... Grüße Tobi
Woher hast Du denn die Codezeile? Normalerweise bedeutet register, der Variable immer ein Register zuzuweisen, d.h. sie kommt auch nie ins RAM. Der Zugriff ist entsprechend schnell. Aber in Deinem Beispiel ist ja ein ganzes Array zugeordnet. Da macht das keinen Sinn? Stefan
Die originale Zeile würde sich vom Compiler wünschen, das komplette Array DATA in Registern unterzubringen. Obwohl der AVR 32 Register hat, wird Dir der Compiler ohnehin kaum so viel bewilligen. ;-) `register' in seiner Originalform war für alte Compiler wichtig, um dem Compiler eine Hilfestellung zu geben, welche Variablen er vorzugsweise in Registern unterbringen soll. Aktuelle Compiler ignorieren das Schlüsselwort in aller Regel, da ihre Optimizer das selbst vernünftig entscheiden können.
Die Zeile stammt ürsprünglich aus einem Program für den Dunfield Development Systems Micro/C AVR compiler Ich hab das "register" jetzt einfach entfernt, und es funktioniert. Martin
@ Jörg Das stimmt so nicht ganz. Die Zeile, die ich oben geschrieben habe ist eine Vorschrift, d.h. der Compiler wird es so machen. Der Grund ist u.A. dass ich z.B. eine Assembleroutine schreiben kann und weiss, dass bestimmte Werte IMMER in diesen Registern stehen. D.h. auch, dass der Compiler sie nicht vorrübergehend anders belegen kann, da ja genau in diese Zeitraum der Interrupt ausgelösst werden könnte. Es gibt andere möglichkeiten, dem Compiler zu "empfehlen" bestimme Variabeln in Registern zu halten. Was er mit einer "empfehlung" macht ist seine Sache. Grüße tobi
> Die Zeile, die ich oben geschrieben habe ist eine Vorschrift, > d.h. der Compiler wird es so machen. Sorry, das ist Quatsch. Offensichtlicher Gegenbeweis: der GCC macht aus diesem Stück Code unsigned char foo(void) { register unsigned char foo[24]; return foo[3]; } folgendes (mit Optimierung, ohne Generierung irgendeiner Warnung): foo: push r28 push r29 in r28,__SP_L__ in r29,__SP_H__ sbiw r28,24 in _tmp_reg_,__SREG__ cli out _SP_H_,r29 out _SREG_,__tmp_reg__ out _SP_L_,r28 ldd r24,Y+4 clr r25 adiw r28,24 in _tmp_reg_,__SREG__ cli out _SP_H_,r29 out _SREG_,__tmp_reg__ out _SP_L_,r28 pop r29 pop r28 ret Die Berechnung des Stackoffsets ist gut zu erkennen, auch die Reservierung von 24 Bytes auf dem Stack. Zweitens: Zitat aus dem C-Standard: ``6.7.1 Storage-class specifiers ... A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.'' Nichts von wegen ,,Vorschrift''. `suggests' und `as fast as possible'. Das bezieht sich auf die originale, standardgemäße Form der register storage-class, aber darauf hatte ich ausdrücklich verwiesen. Der GCC-ismus des Ablegens in einem bestimmten Register ist beim GCC ordentlich dokumentiert und nicht ganz ohne Pferdefüße.
Hmm. Wenn ich mich recht erinnere ist der Unterschied allerdings, dass ich ein festes Regsiter zuweise und nicht empfehle, die Variable allgemain im Register zu halten. Zweitens kann ich schlecht ein Array auf beliebig viele Register verteilen. Drittens wird die Variable hier lokal angelegt, weswegen sie ausserhalb der Funktion sowieso ihre Gültigkeit verliert und somit der Registerplatz freigemacht werden muss. Und zu guter letzt steht in der Beschreibung des AVR-gcc ausdrücklich, dass die Variable so permanent an dieses Register gebunden wird. (siehe FAQ des AVR-gcc) Ich bestehe nur so darauf, da wir ein größeres Projekt besierend auf darauf aufgebaut haben, was auch wunderbar funktioniert. Grüße Tobi
Da steht's: This can be done with register unsigned char counter asm("r3"); See C Names Used in Assembler Code for more details. Und unter dem Verweiss findet man: With AVR-GCC you can specify the use of a specific register: void Count(void) { register unsigned char counter asm("r3"); ... some code... asm volatile("clr r3"); ... more code... } The assembler instruction, "clr r3", will clear the variable counter. AVR-GCC will not completely reserve the specified register. If the optimizer recognizes that the variable will not be referenced any longer, the register may be re-used. But the compiler is not able to check wether this register usage conflicts with any predefined register. If you reserve too many registers in this way, the compiler may even run out of registers during code generation. Was so viel heisst wie: Falls die Optimierung feststellt, dass das Register nicht mehr referenziert wird, DANN wird es anderweitig vergeben. Dies kann allerdings nicht geschehen, wenn es global definiert wird. Der nette Hinweis darunter verrät auch, dass der Compiler die Register nicht wegoptimieren kann, sonst könnten ihm die Register kaum ausgehen. Grüße Tobi
Nochmal: ich habe ausdrücklich über den standardmäßigen Gebrauch von `register' geschrieben, nicht über die GCC-Erweiterung.
Zitiat: "`register' in seiner Originalform war für alte Compiler wichtig, um dem Compiler eine Hilfestellung zu geben, welche Variablen er vorzugsweise in Registern unterbringen soll. Aktuelle Compiler ignorieren das Schlüsselwort in aller Regel, da ihre Optimizer das selbst vernünftig entscheiden können." und "Sorry, das ist Quatsch. Offensichtlicher Gegenbeweis: der GCC macht aus diesem Stück Code ..." So ausdrücklich war es vielleicht doch nicht. Zumindest sehe ich hier ein "...aktuelle Compiler..." und " ... der GCC macht ...". Wir haben wohl einfach aneinander vorbeigetextet. Ich hätte ja auch kenntlicher machen können, dass ich hier von avr-gcc rede. Grüße Tobi
Naja, insbesondere hast Du von der GCC-Erweiterung geredet, mit der man globale Variablen auf ein Register zuweisen kann. Das ist aber non-standard. Die Originalzeile war dagegen Standard-C -- und die ist in der Form ziemlich überflüssig. Auf einer UltraSPARC mit ihren vielen 64-Bit-Registern mag es ja der Compiler noch akzeptieren, 24 Zeichen in 3 Registern unterzubringen, aber auf einem Controller? :-)
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.