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

Gast #6258881
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 #6258898
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?
Gast #6258939
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
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
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
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
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
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.