avr-as: buffer im RAM page wrap verhindern (align)

OP #1525296
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?
OP #1525560
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.
Gast #1525564
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.
OP #1525720
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
Gast #1525724
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"?
OP #1525730
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.
Gast #1525736
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.
Gast #1525738
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.
Gast #1525742
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.
Gast #1525744
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...
OP #1526697
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.
Gast #1527855
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.
Gast #1527865
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.
OP #1527934
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
Gast #1528095
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.
Gast #1528100
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.

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