Hallo, hier mein Problem...
ich habe folgende Variablen
ziel 32 Bit
var1 16 Bit
var2 8 Bit
var3 8 Bit
nun will ich alle Variablen "varX" an eine bestimmte Position in die
Variable "ziel" kopieren. Dabei ist es wichtig, dass so wenig wie
möglich Rechenzeit benötigt wird.
so soll die Variable Ziel später aussehen (links Bits, rechts welche
Variable darin sein soll):
0-7 var3
8-15 var2
16-31 var1
billig und langsam:
1
ziel|var1;
2
ziel<<=8;
3
ziel|=var2;
4
ziel<<=8;
5
ziel|=var3;
gibt es eine Möglichkeit, z.B. var2 direkt in das zweite byte von "ziel"
zu schreiben, oder geht das nur in assembler (inline)?
Villeicht mit Zeigern ein Byte weiter, geht das?
Der Bereich ist sehr zeitkritisch und daher will ich ihn möglichst
optimieren, als ich gesehen habe was GCC aus den verschiebeoperationen
macht wird es einem aber ganz anders...
assembler kann ich zwar aber wenn würde ich das mit inline-assembler
machen, wovon ich keine Ahnung habe - Da ist mir C doch lieber
Hat wer ne Idee? :)
Gruß,
Kjartan
wenn ich mich nicht irre, kann ich mit der union hier nichts erreichen.
Mit einer union könnte ich doch auch nur von hinten auffüllen oder irre
ich mich da?
Bzw. wie soll ich eine 8Bit Variable (ohne Verschiebeoperationen) in das
zweite Byte einer Variable bringen?
super danke (allgemeinbildung++)
aber meine "Variablen" var1,var2,var3 sind Register von AVR Modulen -.-
Hat noch wer ne Idee, oder sollte ich mir besser inline-assembler zu
herzen nehmen?
Kjartan Ferstl schrieb:
>> aber meine "Variablen" var1,var2,var3 sind Register von AVR Modulen -.->>>> Hat noch wer ne Idee, oder sollte ich mir besser inline-assembler zu>> herzen nehmen?
Du bist offensichtlich ein absoluter Anfänger. Höre bitte auf,
Schlagwörter zu verwenden und lerne stattdessen!
Bernhard
Bernhard R. schrieb:
> Kjartan Ferstl schrieb:>>> aber meine "Variablen" var1,var2,var3 sind Register von AVR Modulen -.->>>>>> Hat noch wer ne Idee, oder sollte ich mir besser inline-assembler zu>>> herzen nehmen?>> Du bist offensichtlich ein absoluter Anfänger. Höre bitte auf,> Schlagwörter zu verwenden und lerne stattdessen!>> Bernhard
du bist offensichtlich ein absoluter "Profi". Also hör bitte auf,
Schalgwörter zu verwenden um Leute einzustufen. Wenn du Theads ansiehst
nur um andere zu kritisieren bist du hier (glaube ich) an der flaschen
Stelle.
Hättest du meine Angabe gelesen, so müsste dir klar sein, dass ich nicht
gefragt habe: wie lege ich meine Variablen am besten an um möglichst
viel Tricksen zu können.
Nein, ich fragte ob es möglich ist, eine 8-byte Variable auf das 2. byte
einer 32 bit Variablen zu schreiben.
Eine union ist aber alles andere als verschiedene Variablen.
Dass es sich im falle meiner "Variablen" um Speicherbereiche handelt,
welche für AVR Module reserviert sind sollte dabei keine Rolle spielen.
Aber nachdem du mir nichtmal einen Ansatz einer sinnvollen Version
spendieren konntest muss ich annehmen, dass du wohl der "Profi" bist.
Ich will hier ja keinen Prollo spielen ... aber nein, ich bin definitiv
kein Anfänger mehr.
Angesichts der Menge an Antworten werde ich mich wohl mal an die
Parameterübergabe von AVR GCC inline assembler machen.
Kjartan Ferstl schrieb:
> super danke (allgemeinbildung++)
++allgemeinbildung wäre sinvoller (erst erhöhen, dann den
erhöhten Wert benutzen), als den alten Stand zu nutzen.
Deshalb macht mich der Name C++ auch immer etwas misstrauisch.
++C fände ich vielversprechender.
Ich würde mal versuchen, die Quellvariablen, anstatt die Zielvariable zu
shiften:
quick and dirty:
1
uint8_t*temp=Uuint8_t*)&ziel;
2
3
ziel[0]=var1;
4
ziel[1]=var2;
5
ziel[2]=var3;
Abgesehen davon, dass die Variante mit der Union trotzdem geht. Muss
halt nur etwas nachdenken, und dann im Hauptprogramm im Beitrag von Tim
die 255 u. 65535 durch var 1 bis 3 ersetzen.
Klaus Wachtler schrieb:
> Kjartan Ferstl schrieb:>> super danke (allgemeinbildung++)>> ++allgemeinbildung wäre sinvoller (erst erhöhen, dann den> erhöhten Wert benutzen), als den alten Stand zu nutzen.>> Deshalb macht mich der Name C++ auch immer etwas misstrauisch.> ++C fände ich vielversprechender.
unvorstellbar was hier für sinnvolle themenorientierte Antworten
autauchen.
Kjartan Ferstl schrieb:
> Nein, ich fragte ob es möglich ist, eine 8-byte Variable auf das 2. byte> einer 32 bit Variablen zu schreiben.
Eine Variable mit 8 Byte auf ein Byte zu legen, geht nur mit
guter Kompression.
Aber davon abgesehen: was du m.E. wirklich willst, könnte so
aussehen:
1
uint32_tziel;
2
#define var3 (((uint8_t*)&ziel)[0])
3
#define var2 (((uint8_t*)&ziel)[1])
4
#define var1 (((uint16_t*)&ziel)[1])
5
...
6
var1=32000;// schreibt in die oberen 16 Bit von ziel
7
var2=120;// dto. 2. Byte von Ziel
8
var3=120;// dto. unterstes Byte von Ziel
Wahlweise int..._t statt uint..._t.
Die genannten Abhängigkeiten von Endianness etc. gelten
hierbei auch.
So ähnlich wird übrigens gelegentlich die angebliche
globale Variable errno definiert
(etwa #define errno (*(_get_address_of_blabla())) mit einer
Funktion, die die Adresse liefert)
Nachdem du nicht gesagt hast, in welcher Sprache du das
haben willst, könnte ich noch die FORTRAN-Anweisung EQUIVALENCE
in die Runde werfen, die macht genau das.
Aber das willst du wahrscheinlich auch nicht hören :-)
Klaus Wachtler schrieb:
> Nachdem du nicht gesagt hast, in welcher Sprache du das> haben willst,...
nur nie den ersten Post lesen
> ... Da ist mir C doch lieber ...
Klaus Wachtler schrieb:
> ok, verloren
Nö, da stand ja nur der Compilername (GNU Compiler Collection, aber
das ist ja ohnehin das Thema dieses Teilforums). GCC kann auch
FORTRAN, also liegst du gar nicht so daneben. ;-) Aber FORTRAN
bietet dafür noch andere Scheußlichkeiten, beispielsweise die
Benutzung von COMMON-Blöcken in zwei verschiedenen Modulen, die
dann in beiden verschieden definiert werden... Das kann man übrigens
beim GCC auch in C haben, da nicht initialisierte globale Variablen
standardmäßig ebenfalls in COMMON-Blöcken untergebracht werden (kann
man aber abschalten mit -fno-common). Das sieht dann ungefähr so
aus:
foo.c:
Jörg Wunsch schrieb:
> Nö, da stand ja nur der Compilername (GNU Compiler Collection, aber> das ist ja ohnehin das Thema dieses Teilforums).
Das hatte ich auch gelesen, aber ich traue mich nicht damit
zu argumentieren.
Schließlich hat er dann ja noch C erwähnt.
Außerdem bin ich mir nicht sicher, ob die Diskussion darüber
entspannt wäre.
> Das kann man übrigens beim GCC auch in C haben...
Stimmt.
Nur ist es in FORTRAN ausdrücklich so vorgesehen, wenn auch
dann nicht portabel.
Also eine explizit geduldete Schweinerei, während man in C nicht
darüber spricht.
Klaus Wachtler schrieb:
> Also eine explizit geduldete Schweinerei, während man in C nicht> darüber spricht.
Da der Linker zwischen beiden aber der gleiche ist, ist auch klar,
dass beides auf genau gleiche Weise funktioniert. ;-)
Zugegeben aber, das ist und bleibt eine typische FORTRAN-Lösung,
während die typische C-Antwort darauf halt die union ist. Die ist
auch nicht wirklich portabel, aber zumindest "portabel genug",
wenn man die durch endianess und alignment verursachten Probleme
im Blick behält.
Btw., diese COMMON-Block-Lösung ist auch in C eine der möglichen
zulässigen Implementierungsvarianten. Da es historisch so gehandhabt
worden ist, lässt der Standard eine derartige Implementierung nach
wie vor als konform durchgehen.