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


von Ulf R. (roolf)


Lesenswert?

Ich lege auf einem Mega8 in Assembler einen RAM-Buffer der Größe SIZE an 
mit
1
  .section .bss
2
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
1
  .if (buffer/256) - ((buffer+SIZE-1)/256)
2
  .error "Pagewrap in Bufferadressen"
3
  .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?

von Stefan E. (sternst)


Lesenswert?


von Ulf R. (roolf)


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.

von (prx) A. K. (prx)


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.

von Mmmh (Gast)


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.

von Ulf R. (roolf)


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

von Mmmh (Gast)


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"?

von Mmmh (Gast)


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!

von Ulf R. (roolf)


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.

von Mmmh (Gast)


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.

von Mmmh (Gast)


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.

von Mmmh (Gast)


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.

von Mmmh (Gast)


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

von Klaus (Gast)


Lesenswert?

ähm, ich kann deinen Monolog nocht ganz folgen...

von Mmmh (Gast)


Lesenswert?

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

von Ulf R. (roolf)


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.

von Mmmh (Gast)


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.

von Mmmh (Gast)


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.

von Ulf R. (roolf)


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
1
.if (. & 0xff) < 0xc0

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

von Bartli (Gast)


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.

von Mmmh (Gast)


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.

von Bartli (Gast)


Lesenswert?

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

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.