mikrocontroller.net

Forum: Compiler & IDEs avr-as: buffer im RAM page wrap verhindern (align)


Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich lege auf einem Mega8 in Assembler einen RAM-Buffer der Größe SIZE an 
mit
  .section .bss
buffer: .skip SIZE

Um die Pointer-Berechnungen zu vereinfachen (nur im Register ZL und 
nicht im Register ZH), würde ich gern sicherstellen, dass der gesamte 
Buffer im Adressraum einer Seite liegt, d.h. hi8(buffer) und 
hi8(buffer+SIZE-1) sollen gleich sein.

Wenn diese Bedingung nicht erfüllt ist, dann kann ich sie erzwingen, 
indem ich die vorhandenen Variablen entsprechend manuell umstelle.

Wie kann ich aber beim Assemblieren/Linken mit avr-as automatisch 
diese Bedingung überprüfen? Mein erster Ansatz war
  .if (buffer/256) - ((buffer+SIZE-1)/256)
  .error "Pagewrap in Bufferadressen"
  .endif

Dies wird mit dem Fehler "non-constant expression in .if statement" 
quittiert, vermutlich weil die Festlegung der Adressen später erfolgt 
als das .if ausgewertet wird.

Wo kann ich da ansetzen? Kann nicht sein, dass ich mit "avr-objdump -t" 
und "grep" basteln muss?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.balign kenne ich, das funktioniert hier aber nicht:

(1) ich brauche nur eine Überprüfung zur Compilezeit; wenn die 
fehlschlägt, würde ich die Bereiche von Hand vertauschen

(2) balign kann bestenfalls auf Vielfache von 8 alignen; um einen 
Überlauf ins Hi-Byte sicher zu verhindern, müsste ich aber auf 256 
alignen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird sinnvoller sein, diesen Kampf mit dem Linker auszufechten. Mach 
eine eigene Section für den Puffer und sorge dafür, das die entsprechend 
liegt. Richtig gemacht spart das ausserdem Platz.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>.balign kenne ich, das funktioniert hier aber nicht:
So? Wieso nicht?

>(1) ich brauche nur eine Überprüfung zur Compilezeit; wenn die >fehlschlägt, 
würde ich die Bereiche von Hand vertauschen
Wozu denn? Soweit ich Dich verstanden habe, möchtest Du, das der Bereich 
aligned ist Mit balign erreichst Du das. Dann ist er auch aligned. 
Du brauchst das nicht nochmal zu überprüfen (Wenn as an sich korrekt 
arbeitet).

>(2) balign kann bestenfalls auf Vielfache von 8 alignen; um einen
>Überlauf ins Hi-Byte sicher zu verhindern, müsste ich aber auf 256
>alignen.
Das ist durchaus nicht der Fall. Lies noch mal nach.

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmmh schrieb:

> Wozu denn? Soweit ich Dich verstanden habe, möchtest Du, das der Bereich
> aligned ist Mit balign erreichst Du das.

Nein, ich möchte nur einen Übertrag im Hi-Byte der Adressen in diesem 
Bereich ausschließen. Beispiel: ist der Bereich 0x40 Bytes lang, so sind 
die Möglichkeiten

0x0200..0x023f erlaubt
0x0201..0x0240 erlaubt
...
0x02c0..0x02ff erlaubt
0x02c1..0x0300 nicht erlaubt
0x02c2..0x0301 nicht erlaubt
...
0x02ff..0x033e nicht erlaubt
0x0300..0x033f erlaubt
0x0301..0x0340 erlaubt

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nein, ich möchte nur einen Übertrag im Hi-Byte der Adressen in diesem
Bereich ausschließen

Häh? In Deinen Beispielen bewertest Du doch bestimmte Alignments. Das 
heisst jedes Argument von 0 bis 0xC0 würde das von Dir geforderte 
Alignment ergeben, da es keinen Überlauf in das High-Byte ergäbe. Ergo 
brauchst Du das Alignment nicht zu prüfen, sondern dieses eben nur mit 
balign zu erzwingen. Worauf bezieht sich dann das "nein"?

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du bist doch mit balign dem Compiler insofern eben nicht ausgeliefert, 
so das Du das Alignment nur prüfen könntest! Du kannst es ja erzwingen. 
Also brauchst Du nicht zu prüfen!

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmmh schrieb:

> Worauf bezieht sich dann das "nein"?

Auf "möchtest Du, dass der Bereich aligned ist".

> Häh? In Deinen Beispielen bewertest Du doch bestimmte Alignments. Das
> heisst jedes Argument von 0 bis 0xC0 würde das von Dir geforderte
> Alignment ergeben, da es keinen Überlauf in das High-Byte ergäbe. Ergo
> brauchst Du das Alignment nicht zu prüfen, sondern dieses eben nur mit
> balign zu erzwingen.

Wenn ich "balign N" verwende, dann werden 0  bis N-1 bytes eingefügt, 
damit anschließend die nachfolgende Adresse kongruent 0 modulo N ist. 
(Soweit ich das verstehe.)

Das hat mit obiger Anforderung nichts zu tun, weil die gewünschte 
Adresse nicht mit einer modulo-Operation beschrieben werden kann.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wenn ich "balign N" verwende, dann werden 0  bis N-1 bytes eingefügt,
>damit anschließend die nachfolgende Adresse kongruent 0 modulo N ist.
>(Soweit ich das verstehe.)
Das sehe ich auch so.
Was ich da geschrieben habe ist falsch:
> Das heisst jedes Argument von 0 bis 0xC0 würde das von Dir geforderte
> Alignment ergeben
Nicht jedes Argument würde passen.
Man müsste 0x40 als Argument nehmen.
Das könnte dann 0, 0x40, 0x80 oder 0xC0 als effektive Adresse ergeben. 
In keinem Fall gäbe es einen Überlauf in das High-Byte.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das hat mit obiger Anforderung nichts zu tun, weil die gewünschte
>Adresse nicht mit einer modulo-Operation beschrieben werden kann.
Wie man sieht geht das doch. Denn wenn die Adresse kongruent der Länge 
ist, gilt das die Differenz zum Übertrag max der Länge entspricht. Was 
klar ist, weil das ja gleichzeitig ein weiteres Vielfaches ergibt.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz allgemein muss für das Argument von balign entweder die Länge 
selbst, sofern diese eine Zweierpotenz ist oder die nächstgrösser 
Zweierpotenz gewählt werden, wobei diese kleiner oder gleich der 
Wertigkeit des Bits sein muss, in das die Addition (der Adresse) nicht 
überlaufen darf.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut. Du hast nicht_ geschrieben das die Adresse aligned sein _soll . 
Das war vielmehr ein Vorschlag um zu erreichen das die Adresse 
garantiert nicht überläuft.
Da Du aber sonst keine Möglichkeit hast (ich weiss jedenfalls keine) 
dies zu verhindern...

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ähm, ich kann deinen Monolog nocht ganz folgen...

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ähm, ich kann deinen Monolog nocht ganz folgen...
Ach was! Und wer will das über Dich wissen, Klaus?

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmmh schrieb:
> Ganz allgemein muss für das Argument von balign entweder die Länge
> selbst, sofern diese eine Zweierpotenz ist oder die nächstgrösser
> Zweierpotenz gewählt werden, wobei diese kleiner oder gleich der
> Wertigkeit des Bits sein muss, in das die Addition (der Adresse) _nicht_
> überlaufen darf.

Das wäre theoretisch eine Möglichkeit, die aber aus zwei Gründen nicht 
praktikabel ist: (1) avr-as erlaubt bei .align nur Argumente <= 8 und
(2) es entstehen durch das Alignment Lücken im Adressraum, die sich 
nicht für andere Daten nutzen lassen.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>(1) avr-as erlaubt bei .align nur Argumente <= 8
Oh, verdammt.

>(2) es entstehen durch das Alignment Lücken im Adressraum, die sich
>nicht für andere Daten nutzen lassen.
Ja klar. Hättest Du vielleicht einen Tick früher schreiben sollen, dass 
da noch eine Nebenbedingung ist. ;-)

Also muss man etwas direkter ran. Mit "." und if-endif selbst das 
Alignment erzwingen. In dem Zuge dann nachher restliche Variablen in den 
aufgefüllten Bereich setzen.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im übrigen kannst Du natürlich, in dem Du "." überprüfst, Deinem 
Ansatz folgen, falls Dir meiner zu kompliziert ist.

Ich habe das auf meinem Weg halt schon angewendet um gewisse 
Ausrichtungen zu erwzingen. Z.B. ungeradzahlige, oder Positionen von 
Variablen entsprechend ihrer Grösse zu bestimmen.

Autor: Ulf Rolf (roolf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmmh schrieb:
> Im übrigen kannst Du natürlich, in dem Du "." überprüfst, _Deinem_
> Ansatz folgen, falls Dir meiner zu kompliziert ist.
>
> Ich habe das auf meinem Weg halt schon angewendet um gewisse
> Ausrichtungen zu erwzingen. Z.B. ungeradzahlige, oder Positionen von
> Variablen entsprechend ihrer Grösse zu bestimmen.

Ein Beispiel für eine Überprüfung von . wäre sehr hilfreich.  Ich habe 
nach diesem Vorschlag
.if (. & 0xff) < 0xc0

versucht und bekomme wieder die Fehlermeldung
Error: non-constant expression in ".if" statement

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dies wird mit dem Fehler "non-constant expression in .if statement"
> quittiert, vermutlich weil die Festlegung der Adressen später erfolgt
> als das .if ausgewertet wird.

Ja, und zwar erst beim Linken. Deshalb mach das was A. K. gesagt hat:

> Wird sinnvoller sein, diesen Kampf mit dem Linker auszufechten. Mach
> eine eigene Section für den Puffer und sorge dafür, das die entsprechend
> liegt. Richtig gemacht spart das ausserdem Platz.

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ja, und zwar erst beim Linken. Deshalb mach das was A. K. gesagt hat:

>> Wird sinnvoller sein, diesen Kampf mit dem Linker auszufechten. Mach
>> eine eigene Section für den Puffer und sorge dafür, das die entsprechend
>> liegt. Richtig gemacht spart das ausserdem Platz.

Das wird dann tatsächlich über den Linker-Script laufen müssen.

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. Ist aber für solche Probleme wirklich das einzig vernünftige wenn 
ein Linker am Ende der Toolchain sitzt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.