risc-c .hex Datei Konstanten / Initialisierungswerte werden nicht auf 32bit vergrößert

Gast #6258881
Lesenswert?

Hallo,

ich bin auf ein Problem mit den .hex files gestoßen die mir der GNU 
RISC-V CrossCompiler 8.3.0 (riscv-none-embed) mit eclipse unter windows 
erzeugt.
Die Programme sollen auf einer risc-v 32bit SOC Eigenentwicklung laufen.
Das Problem ist das Konstanten wie z.B. const char values[15] = { 128, 
64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex 
file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte 
abgespeichert werden und nicht wie es für mich richtg wäre jeweils 
erweitert als 4 bytes 32bit word). Mit int oder long funktioniert es 
wieder, die werden jeweils als 4 bytes gespeichert. Optionen wie z.B. 
mstrict-align oder malign-data ändern leider nichts.
Wenn irgendwie im .hex file gekennzeichnet wäre das jetzt bytes folgen 
und kein word wäre das super aber ist nicht der Fall.

Wie kann ich das hinbekommen?

Im Anhang ist mein linker script (denke dort habe ich überall das 
alignment auf 4 gesetzt).
Die Konstanten stehen am Ende von .text und werden vom startup-code in 
.data kopiert.


Danke
Christian
Angehängte Dateien:
Gast #6258939
Lesenswert?

MaWin schrieb:
> Warum sollte das richtig sein?
... weil es kein erkennbare Unterscheidung zwischen instructions und den 
values selber gibt, instructions sind 32bit breit, Datenbus und der 
Speicher auch.
Woher soll der loader sonst wissen ob er jetzt gerade ein byte oder ein 
word kopieren soll?

> Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben
> möchtest?
... eigentlich habe ich das so verstanden das egal welcher Datentyp 
dieser immer als 32bit word gespeichert wird, was aber anscheinend nicht 
stimmt, das erzeugte .hex file ist ja korrekt wenn der Speicher auch als 
bytes organisiert ist.
Moderator #6258954
Lesenswert?

Christian G. schrieb:
>> Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben
>> möchtest?
> ... eigentlich habe ich das so verstanden das egal welcher Datentyp
> dieser immer als 32bit word gespeichert wird

Das hast du falsch verstanden.

Der Sinn der verschieden großen Integertypen liegt ja u.a. darin, die
Speicherplatzbelegung größerer Arrays jeweils auf das Notwendige
reduzieren zu können.
#6259758
Lesenswert?

Christian G. schrieb:
> Das Problem ist das Konstanten wie z.B. const char values[15] = { 128,
> 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex
> file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte
> abgespeichert werden und nicht wie es für mich richtg wäre jeweils
> erweitert als 4 bytes 32bit word).

Wenn Du ein char-Array anlegst, hast Du ein char-Array. Genau das, was 
man erwarten würde.

Wenn Du was anderes haben willst, solltest Du das hinschreiben.
Gast #6259790
Lesenswert?

Christian G. schrieb:
> Woher soll der loader sonst wissen ob er jetzt gerade ein byte oder ein
> word kopieren soll?

Der loader kopiert einfach X Bytes, mit X Z.b. 1643. Den kümmert die 
Organisation nicht. Einmal X Bytes von Adresse Y im Rom nach Z im RAM.

Wobei .... Das gilt für initialisierte Variablen, Konstanten eigentlich 
nur, wenn der Prozessor nicht einfach aus dem Rom lesen kann.

Von daher, ... was möchtest Du?

Oder verwechselst Du das mit Parametern einer Funktion, die wirklich 
mindestens int-Breite haben
Gast #6259796
Lesenswert?

A. S. schrieb:

> Oder verwechselst Du das mit Parametern einer Funktion, die wirklich
> mindestens int-Breite haben

Haben sie IMO nicht. Das ist allenfalls üblicherweise so auf CPUs mit 
mindestens 16 bit und wenn nicht mehr Parameter übergeben werden, als 
Register dafür im ABI vorhanden sind (Rest über den Stack).
Gast #6259814
Lesenswert?

Christian G. schrieb:
> Die Programme sollen auf einer risc-v 32bit SOC Eigenentwicklung laufen.
> Das Problem ist das Konstanten wie z.B. const char values[15] = { 128,
> 64, 32, 16, 8, 4, 2, 1, 2, 4, 8, 16, 32, 64, 128 }; im erzeugten .hex
> file in ihrer "nativen" Größe in diesem Fall jeweils als ein byte
> abgespeichert werden und nicht wie es für mich richtg wäre jeweils
> erweitert als 4 bytes 32bit word). Mit int oder long funktioniert es
> wieder, die werden jeweils als 4 bytes gespeichert. Optionen wie z.B.
> mstrict-align oder malign-data ändern leider nichts.
> Wenn irgendwie im .hex file gekennzeichnet wäre das jetzt bytes folgen
> und kein word wäre das super aber ist nicht der Fall.
>
> Wie kann ich das hinbekommen?

Kennt deine RISC-V Eigenentwicklung denn die Assemblerbefehle:
LB, LH, LBU und LBH?
Die sind zuständig um Bytes und Halfwords (16bit) Daten zu laden, und 
auf 32 Bits zu erweitern. Der Compiler wird sicher solche Befehle 
verwenden, wenn du auf Byte Arrays zugreifst.

Beim laden des Hexfiles die Daten zu ändern, ist keine gute Idee, dann 
stimmt ja die nachfolgenden Adressen nicht mehr überein, mit dem was der 
Kompiler angenommen hat.
Gast #6260136
Lesenswert?

Danke für die ganzen Antworten, ich hatte das echt falsch verstanden, 
klar sind die Befehle um bytes / half words zu laden/schreiben 
implementiert aber die operieren auf einem 32bit word, ich werde den 
Speicherzugriff ändern.

Danke!
#6260571
Lesenswert?

Christian G. schrieb:
> aber die operieren auf einem 32bit word, ich werde den
> Speicherzugriff ändern.

Ich sehe da keinen Widerspruch. Wenn du ein Byte lesen willst, dann 
liest du halt 32 Bit, nimmst davon dann die richtigen 8 Bits und wirfst 
den Rest weg. Für Halfwords das gleiche.

Es hängt vom Speichersystem ab, ob das fies werden kann (z.B. weil 
Adressen 0x2002 noch existiert, aber 0x2003 nicht), aber das kann man ja 
per Architekturdekret verbieten.

Ich glaube, das richtige Stichwort ist "alignment": Ein Byte hat ein 
Alignment von 1, ein Halfword von 2, ein Word von 4 und so weiter.
Gast #6260634
Lesenswert?

S. R. schrieb:
> Es hängt vom Speichersystem ab, ob das fies werden kann (z.B. weil
> Adressen 0x2002 noch existiert, aber 0x2003 nicht), aber das kann man ja
> per Architekturdekret verbieten.

genau das ist das Problem, es wird versucht von einer Adresse zu lesen 
die nicht 32bit aligned ist, keine Ahnung ob ich dem compiler das 
irgendwie per Parameter etc. verbieten kann, denke die einfachere 
Variante ist das ändern meiner CPU da die sich eh im Entwicklungs- 
/Test-Stadium befindet.

Glaube das Thema ist damit erledigt, Danke an alle.
Gast #6260836
Lesenswert?

RISC-V erwartet, dass du words und halfwords auch von 'unaligned' 
Adressen lesen kannst (beim Schreiben dasselbe).
Bei einfachen RISC-V Implementationen wird bei unaligned Zugriff oft 
einfach ein Interrupt ausgelöst, und das Ganze dann in Software richtig 
behandelt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren