Forum: Mikrocontroller und Digitale Elektronik cast auf 32 Bit Cortex


von Christian (Gast)


Lesenswert?

Hallo.

Ich blättere gerade im RTOS Projekt. Welchen Grund gibt es für so einen 
Cast auf einen 32Bit System(Cortex):

Konstante + (uint16_t)1;

Oder soetwas:
if(var1 == (unsigned short)0)

Könnte man den Cast Operator auch weglassen?

Danke

Christian

von uwe (Gast)


Lesenswert?

Da die Befehle 32Bit Breit sind kann dort keine 32Bit Konstante im 
Befehl (als Immediate) stehen. Also muß die Konstate vorher in ein 
Register geladen werden und diese Register kann auch nicht direkt 
geladen werden sondern muß über einen Offset auf eine Speicherstelle 
geladen werden. Immediate Befehle konnten glaube ich eine 16Bit 
Konstante enthalten, womit dieser ganze Zirkus entfällt.

von Arc N. (arc)


Lesenswert?

Christian schrieb:
> Hallo.
>
> Ich blättere gerade im RTOS Projekt. Welchen Grund gibt es für so einen
> Cast auf einen 32Bit System(Cortex):
>
> Konstante + (uint16_t)1;
>
> Oder soetwas:
> if(var1 == (unsigned short)0)
>
> Könnte man den Cast Operator auch weglassen?

Kommt drauf an...
Wenn die Operanden nicht ganz zusammenpassen, wandelt sie der Compiler 
erstmal nach den Regeln des Standards in Integer um (Integer Promotion), 
wenn dem kein Riegel vorgeschoben wird. Da die Compiler auf 32-Bit 
Systemen int normalerweise als 32-Bit ansehen, wären hier u.U. 
entsprechende Umwandlung fällig, die dazu führen können, dass das 
Ergebnis nicht ganz das gewollte ist.

von Programmierer (Gast)


Lesenswert?

Das ist Quatsch. Die Kodierung der Konstanten im Maschinencode hat 
nichts mit dem Typ von Literalen und casts in C zu tun. Alle Integer 
Literale sind, falls nicht explizit anders angegeben, von Typ "int", 
welcher in ARM Compilern 32Bit (signed) ist.

Christian schrieb:
> Konstante + (uint16_t)1;
Falls die Konstante vom Typ "int" ist (oder nicht "Konstante" sondern 
"Literal" gemeint war, und kein Typ angegeben ist, und somit vom Typ 
"int" ist) ist dieser cast absolut sinnlos. Die 1 wird danach wieder auf 
"int" promotet und die Rechnung auf "int" (32bit! ) durchgeführt.

Christian schrieb:
> if(var1 == (unsigned short)0)
Hier kommt es auf den Typ von var1 an. Handelt es sich um einen builtin 
Integer Typen, ist der cast sinnlos.

Nochmal: Der Compiler verwurstet alle Anweisungen und Literale mit 
Flussanalyse usw.. Wie sie im Code stehen hat keinen Einfluss auf die 
Kodierung im Maschinencode. Dafür sind Compiler Flags zur Optimierung 
zuständig (zB -Os vs -O3 im GCC).

von Uwe Bonnes (Gast)


Lesenswert?

Welcher Cortex? Zumindestens bei Cortex M kann man manche Muster, 
darunter auch (uint32_t) 1 immediate in ein Register laden. Fuer 
Cortex-M ist der cast oben m.e.a. ueberfluessig. Das ganze nennt sich 
"Flexible second operand".

von Bernd K. (prof7bit)


Lesenswert?

Christian schrieb:
> Könnte man den Cast Operator auch weglassen?

Ja. Zumindest in den oben gezeigten zwei konkreten Fällen sind die 
komplett unsinnig.

von Bernd K. (prof7bit)


Lesenswert?

Uwe Bonnes schrieb:
> umindestens bei Cortex M kann man manche Muster,
> darunter auch (uint32_t) 1 immediate in ein Register laden. Fuer
> Cortex-M ist der cast oben m.e.a. ueberfluessig. Das ganze nennt sich
> "Flexible second operand".

Siehst Du hier etwa irgendwo Assembler code? Ich nicht. Das scheint ganz 
normales C zu sein, da gibts kein "immediate" und dergleichen, da gibts 
nur den C-Standard und darüberhinaus für grenzwertige Sachen die 
implemntation-defined sind noch das jeweilige ABI.

Und weil nichts von den beiden Beispielen da oben je an einer 
"implementation defined" Grenze entlangschrammt reicht es allein den 
C-Standard zu betrachten.

von Christian (Gast)


Lesenswert?

Gemeint ist der Cortex-M. Die Casts tauchen immer wieder mal auf. Z.b. 
auch in der for-Schleife:

BaseType_t x;
for(x=(BaseType_t)0;x < (BaseType_t)Max_len;x++ )

BaseType ist abhängig von der entsprechenden Portierung, aber in diesem 
Falle ist es unsigned Long.

Christian

von Bernd K. (prof7bit)


Lesenswert?

Christian schrieb:
> BaseType_t x;
> for(x=(BaseType_t)0;x < (BaseType_t)Max_len;x++ )
>
> BaseType ist abhängig von der entsprechenden Portierung, aber in diesem
> Falle ist es unsigned Long.

Der Autor dieses Codes zieht sich wohl die Hosen mit glühenden 
Beißzangen an. Heraus kommt dann grundlos überproportional unleserlicher 
Code.

von Programmierer (Gast)


Lesenswert?

Bernd K. schrieb:
> Der Autor dieses Codes zieht sich wohl die Hosen mit glühenden
> Beißzangen an. Heraus kommt dann grundlos überproportional unleserlicher
> Code.

Außerdem grundlos ineffizient, denn long ist (vermutlich) 64bit, während 
MaxLen vielleicht kleiner ist, und somit unnötig 64Bit gerechnet werden 
muss (Cortex M kann das nicht in Hardware) , falls der Compiler das 
nicht sowieso durchschaut und wegoptimiert.
Insgesamt total sinnlos.Wenn schon aufwändig, dann bitte vom Typ von 
MaxLen abhängig:
1
for (decltype (MaxLen) i = 0; i < MaxLen ; ++i) ...
So wird die Arithmetik im größtnötigen Typ durchgeführt.

von Jim M. (turboj)


Lesenswert?

Programmierer schrieb:
> Außerdem grundlos ineffizient, denn long ist (vermutlich) 64bit

Nö, long ist 32 Bit bei Cortex M Compilern.

Die vom OP genannten Casts sind IMO auf Prozessoren nötig, deren int nur 
16 Bit breit sind. RTOS Projekte enthalten oft Code der auf 
verschiedenen Plattformen laufen muss.

von Andreas R. (andreasr)


Lesenswert?

Vermutlich stammt der Code aus FreeRTOS. Die werben mit größtmöglicher 
Portierbarkeit (8/16/32/64-Bit Maschinen) und Einhaltung aller 
MISRA-Regeln. Wahrscheinlich haben die casts damit etwas zu tun.

uups... Jim war schneller

von Programmierer (Gast)


Lesenswert?

Jim Meba schrieb:
> Nö, long ist 32 Bit bei Cortex M Compilern.
Ah okay, hatte ih falsch in Erinnerung..
> Die vom OP genannten Casts sind IMO auf Prozessoren nötig, deren int nur
> 16 Bit breit sind. RTOS Projekte enthalten oft Code der auf
> verschiedenen Plattformen laufen muss.
Klar, aber in dem Fall reicht es (und ist sowieso erforderlich! ) dem 
Schleifenzähler den richtigen Typ zu verpassen (der gleiche wie MaxLen). 
Die Casts sind dann unnötig, der Compiler macht bei Operatoren 
automatisch das richtige anhand des Typs der Variablen...

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.