Forum: Compiler & IDEs Pointer auf Struct -> align problem


von Matthias Hüsch (Gast)


Lesenswert?

Hallo!

Ich stolpere gerade zum x-ten mal über das Problem mit
den aligned Speicherzugriffen vom ARM7 und deren Behandlung in GCC.
Ich versuche mal zu erklären was genau passiert:

Es gibt einen Buffer von 128 Bytes länge in den
ein Gerät von ausserhalb seine Datenstrukturen ablegt.
Auf das "wieviel aufeinmal" und wo habe ich dabei keinen Einfluss.
Es handelt sich dabei um eine wild gewürfelte linked-list, deren
Elemente wahlfrei verschieden lang und typisiert sind.
Diese Datenstrukturen will ich nun auswerten.
Der Einfachheit halber natürlich über entsprechende structs.
Die Strukturen sind jeweils aus 8 und 16bit Werten zusammengsetzt
und sind in sich durchaus aligned. Allerdings wandern die auf Bytes
ausgerichtet in diesen Puffer.
Der erste Block beginnt auf buffer[0] , der zweite beispielsweise
auf buffer[9].
Wenn ich aber nun schreibe:
1
char buffer[128]; // per DMA gefüllt
2
3
strukturname *pointer;
4
pointer = (strukturname*)&buffer[9];

geht das grandios in die Hose und er greift mit dem ersten
structure member auf Buffer[8] zu.
Und nicht wie erwartet etwa buffer[9].
Das er das mit einem WORD nicht können kann habe ich schon 
herausgefunden. In diesem Falle besteht die Struktur aber ausschließlich 
aus Bytes, was er Architekturbedingt können müsste.
Die Struktur selbst ist als typedef struct mit __attribute__((packed)) 
definiert. #pragma pack() habe ich auch schon versucht.

Wie überrede ich denn nun den Compiler dazu, dass er den Pointer
bitte nicht aligned setzten soll, sondern dahin wo ich ihn gerne hätte?

Tausend Dank schonmal!
Grüße,
  Matthias

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Matthias Hüsch wrote:

>
1
> char buffer[128]; // per DMA gefüllt
2
> 
3
> strukturname *pointer;
4
> pointer = (strukturname*)&buffer[9];
5
>
>
> geht das grandios in die Hose und er greift mit dem ersten
> structure member auf Buffer[8] zu.
> Und nicht wie erwartet etwa buffer[9].

Das sieht mir nach Compilerfehler aus... Wenn die Struktur nicht aligned 
ist (bzw. gcc nix über das Alignment weiß), dann sollte er 
8-Bit-Zugriffe machen, auch wenn das sehr ineffizienten Code gibt.

Evtl. ist eine Option aktiviert, die solche Transformationen als 
Optimierung nach sich zieht?

Die gesetzten Optionen sieht du mit -save-temps -fverbose-asm im 
erzeugten .s.

Fixen könntest das, indem aus dem Puffer rauskopierst in eine Union aus 
der Struktur und einem char-Puffer, wobei die Union aligned ist, etwa 
__attribute__((aligned)) falls es das für ARM gibt.

von Rolf Magnus (Gast)


Lesenswert?

>Das sieht mir nach Compilerfehler aus...

Nö. Das ist das ganz normale Verhalten.

> Wenn die Struktur nicht aligned ist (bzw. gcc nix über das Alignment
> weiß),

Das weiß er eigentlich nie. Er muß darauf vertrauen, daß das Alignment 
korrekt ist.

> dann sollte er 8-Bit-Zugriffe machen, auch wenn das sehr
> ineffizienten Code gibt.

Wenn man die haben will, muß man sie explizit hinschreiben.

> Fixen könntest das, indem aus dem Puffer rauskopierst in eine Union
> aus der Struktur und einem char-Puffer, wobei die Union aligned ist,
> etwa __attribute__((aligned)) falls es das für ARM gibt.

Wozu sollte man das brauchen? Korrektes Alignment wird automatisch 
eingehalten, wenn man es nicht explizit ausschaltet.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Und was ist dann das Problem??

Rolf Magnus wrote:
>>Das sieht mir nach Compilerfehler aus...
>
> Nö. Das ist das ganz normale Verhalten.

Ok, dann steht's irgendwo im ABI.

von Nischu (Gast)


Lesenswert?

Ich weiß, das ist wenig effizient, aber mach doch im Zweifel:
char align_buf[128]
memcpy(align_buf, &buffer[9], ...);
strukturname *pointer;
...

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.