Forum: Compiler & IDEs register


von Martin Hofmann (Gast)


Lesenswert?

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

von Tobias Krühn (Gast)


Lesenswert?

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

von Martin Hofmann (Gast)


Lesenswert?

Vielen Dank, das hilft!

MArtin

von Stefan Kleinwort (Gast)


Lesenswert?

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

von Jörg Wunsch (Gast)


Lesenswert?

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.

von Martin Hofmann (Gast)


Lesenswert?

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

von Tobias Krühn (Gast)


Lesenswert?

@ 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

von Jörg Wunsch (Gast)


Lesenswert?

> 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.

von Tobias Krühn (Gast)


Lesenswert?

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

von Tobias Krühn (Gast)


Lesenswert?

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

von Jörg Wunsch (Gast)


Lesenswert?

Nochmal: ich habe ausdrücklich über den standardmäßigen Gebrauch von
`register' geschrieben, nicht über die GCC-Erweiterung.

von Tobias Krühn (Gast)


Lesenswert?

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

von Jörg Wunsch (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.