Forum: Compiler & IDEs risc-c .hex Datei Konstanten / Initialisierungswerte werden nicht auf 32bit vergrößert


von Christian G. (Gast)


Angehängte Dateien:

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

von MaWin (Gast)


Lesenswert?

Christian G. schrieb:
> jeweils als ein byte
> abgespeichert werden und nicht wie es für mich richtg wäre jeweils
> erweitert als 4 bytes 32bit word).

Warum sollte das richtig sein?
Warum gibst du sie als byte an, wenn du sie als Wort abgespeichert haben 
möchtest?

von B. W. (yesitsme)


Lesenswert?

Hmm...

Strings funktionieren so schlecht, wenn die einzelnen Zeichen auf 4-Byte 
aligned sind...

von Christian G. (Gast)


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.

von Strategic Head of Lunch Planning (Gast)


Lesenswert?

> Strings funktionieren so schlecht, wenn die einzelnen Zeichen auf 4-Byte
> aligned sind...

UTF-32.

von Yalu X. (yalu) (Moderator)


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.

: Bearbeitet durch Moderator
von MaWin (Gast)


Lesenswert?

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

In der Regel aus dem opcode.

von Markus F. (mfro)


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.

von A. S. (Gast)


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

von Nop (Gast)


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).

von Andi (Gast)


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.

von Christian G. (Gast)


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!

von S. R. (svenska)


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.

von Christian G. (Gast)


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.

von Andi (Gast)


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.

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.