Forum: Compiler & IDEs avr-gcc: Wie Daten alignen?


von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi,

gibt es eine Möglichkeit, in avr-gcc Daten, die im Flash stehen, auf 
gerade Adressen zu alignen?

Die Daten sollen nach Section .progmem.data, d.h. ich würde gerne so 
etwas machen:
1
const char Data[] __attribute__((aligned(1))) PROGMEM = 
2
{
3
   ...
4
};

Das Attribut wird angewarnt und ignoriert.

Ein
1
asm (".align 1");

funktioniert auch nicht, weil der Compiler die Reihenfolge nicht einhält
und das .align nicht an der richtigen Stelle ausgegeben wird.
Ein -fno-reorder-functions hilft auch net.

Weiß jemand, wie das geht?

Danke für Tipps!

Johann

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wofür brauchst du das denn?  Normalerweise fügt der Linkerscript
doch ein Füllbyte nach dem .progmem.data ein.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Wofür brauchst du das denn?

Erstens interessiert mich wie das geht. In meiner judendlichen 
Baläugigkeit dachte ich, sowas wäre per __attribute__((align(.))) 
machbar.
Das ist doch maschinenunabhäbgig? Aber avr-gcc emittiert kein .align ins 
.s, weder die 4.x noch die 3.x.

Zweitens wäre das ganz hübsch für ne bestimmte Optimierung, weil dann an 
Bit 0 der Adresse zu sehen ist, ob von einem geraden oder ungeraden 
Offset aus dem betreffenden Objekt gelesen wird, ohne den Index selbst 
mitzuschleifen.

Im betreffenden Falle hat ein Datensatz 9 Bit, mit dem Alignment-Wissen 
hätte er nur noch 8 Bit. Das Objekt würde dann 43% (7/16) kleiner 
ausfallen.

> Normalerweise fügt der Linkerscript
> doch ein Füllbyte nach dem .progmem.data ein.

Das alignt doch nur die Section, nicht die Objekte darin?
Ich brauch es nur für dedizierte Objekte.

Durch Rumprobieren hab ich folgendes gefunden:
1
SECTIONS 
2
{
3
    .text : 
4
    {
5
        *(.wall) 
6
        . = ALIGN(2);
7
        WALL = .;
8
    }  > text
9
}

und im C-File:
1
const uint8_t WALL[] __attribute__((section(".wall"))) =
2
{
3
   ...
4
};

Kannst du das bestätigen? ld ist so ne Sache, nach der Doc wären mir 
auch 1000 andere Formulierungen plausibel...

Wieso landet das in _edata?

Ausserdem verstehe ich das map-File nicht:
1
*(.fini0)
2
                0x00003094                _etext = .
3
 *(.wall)
4
 .wall          0x00003094       0x19 snake.o
5
                0x000030ae                . = ALIGN (0x2)
6
 *fill*         0x000030ad        0x1 00
7
                0x000030ae                WALL = .

Wieso steht hier WALL bei 30ae und nicht ab 3094?
Es ist das einzige Objekt in .wall.

Im .lst stehen diese Daten dann dann doch ab 3094. Da ist doch noch was 
faul?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> Erstens interessiert mich wie das geht. In meiner judendlichen
> Baläugigkeit dachte ich, sowas wäre per __attribute__((align(.)))
> machbar.

Du meinst __attribute__((aligned(2)))?

Das bringt bei mir eine Warnung, die auch letztlich erklärt, warum
es nicht funktioniert:
1
foo.c:5: warning: alignment of 'z' is greater than maximum object file alignment.  Using 1

> Kannst du das bestätigen?

Hab gerade keine rechte Zeit, mich da rein zu vertiefen.

> Wieso steht hier WALL bei 30ae und nicht ab 3094?

Ich habe immer den Eindruck, dass GNU ld linker maps zu den am besten
verschlüsselten Dateien gehören. :-/

von Peter D. (peda)


Lesenswert?

Johann L. wrote:
> gibt es eine Möglichkeit, in avr-gcc Daten, die im Flash stehen, auf
> gerade Adressen zu alignen?

Wozu?

Der LPM-Befehl kann doch nur 8-bittig lesen, also ist das aufm AVR 
vollkommen wurscht, der Code- und Zeitverbrauch ändert sich nicht.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Wozu?

Hatte ich ober erkläutert...

Jörg Wunsch wrote:
> Du meinst __attribute__((aligned(2)))?

Ja :-)

> Das bringt bei mir eine Warnung, die auch letztlich erklärt, warum
> es nicht funktioniert:
>
>
1
> foo.c:5: warning: alignment of 'z' is greater than maximum object file
2
> alignment.  Using 1
3
>

Versteh ich net. Funktionen werden doch auch aligned und landen in text. 
Woher weiß der Linker das eigentlich? Von .type @funktion oder @object?

>> Kannst du das bestätigen?
>
> Hab gerade keine rechte Zeit, mich da rein zu vertiefen.

Ok, sorry. Ich dachte du weisst das ausm Stegreif ;-)

> Ich habe immer den Eindruck, dass GNU ld linker maps zu den am besten
> verschlüsselten Dateien gehören. :-/

Yupp, dito für ld-Scrips. Nur TeX und Intercal sind besser.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> Versteh ich net. Funktionen werden doch auch aligned und landen in text.
> Woher weiß der Linker das eigentlich?

Noch schlimmer: der Compiler weiß das schon!  Das war eine reine
Compilerwarnung, ich habe mit -S direkt Assemblercode generiert.

Die Ausrichtung der Befehle ist automatisch, da alle Befehle in der
Länge durch 2 teilbar sind.  Lediglich nach .progmem ist ein separates
ALIGN notwendig (da es ja eine ungerade Anzahl von Bytes sein können),
das steht im Linkerscript:
1
...
2
    *(.vectors)
3
    KEEP(*(.vectors))
4
    /* For data that needs to reside in the lower 64k of progmem.  */
5
    *(.progmem.gcc*)
6
    *(.progmem*)
7
    . = ALIGN(2);
8
     __trampolines_start = . ;
9
...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ok hab's jetzt so, damit ist alles wie gewünscht, und die Info im .map 
ist konsistent mit dem .hex :-)
1
SECTIONS 
2
{
3
    .text : 
4
    {
5
        . = ALIGN(2); 
6
        *(.wall) 
7
        . = ALIGN(2); 
8
    }  > text
9
}

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.