Hi,
ich möchte ein größeres Assemblermodul (avra) in ein gcc-Projekt
einbinden und muss es daher erstmal auf avr-as umschreiben. Soweit, so
nervig.
Bestimmte Teile des Codes müssen innerhalb eines 256 Byte großen Blocks
liegen (der auch auf 256 Bytes ausgerichtet sein muss). Das gilt auch
für einige Tabellen.
Der bisherige Code nutzt
.org (PC + 255) & 0xFF00
und
.if (high(block_end) != high(block_begin))
.error "ERROR: block spans boundary, won't work"
.endif
um das Alignment einzuhalten und auch zur Bauzeit zu prüfen. Innerhalb
eines Object-Files ist die entstehende Adresse aber noch nicht bekannt,
daher geht das dort nicht.
Wie kann ich diese Randbedingungen innerhalb eines Assemblermoduls
sicherstellen? Geht das auch, ohne eigenes Linkerscript bauen zu müssen?
Ein bisschen Flash-Verschwendung wäre kein Problem, eine Implementation
in C ist deutlich zu langsam.
Schönen Gruß
Hallo,
ich habe vor Jahren mal eine AVRASM Implementierung von AES
Verschluesselungsalgorithmen nach GCC portiert.
Alignment ist soweit ich es Erinnere auch dabei.
Beitrag "AES, Rijndael, WinAVR, Library"
S. R. schrieb:> Bestimmte Teile des Codes müssen innerhalb eines 256 Byte großen Blocks> liegen (der auch auf 256 Bytes ausgerichtet sein muss). Das gilt auch> für einige Tabellen.>> Der bisherige Code nutzt> .org (PC + 255) & 0xFF00> und> .if (high(block_end) != high(block_begin))> .error "ERROR: block spans boundary, won't work"> .endif> um das Alignment einzuhalten und auch zur Bauzeit zu prüfen. Innerhalb> eines Object-Files ist die entstehende Adresse aber noch nicht bekannt,> daher geht das dort nicht.
Auf .org verzichten, das hat bei GNU andere Semantik, mit der du
vermutlich nix anfangen kannst.
Stattdessen .balign 256 oder .p2align 8
Der Code beginnt dann bei entsprechendem Alignment. Alternativ kann man
das in ne eigene Section legen und das Alignment im ld-Skript festlegen.
Das .if funktioniert mit gas nicht, da der Assembler die Länge des
Blocks nicht kennt bzw. nicht kennen kann; für eine entsprechende
Assertion muss also ld-Skript her, etwa so:
Wow, danke für die hilfreichen Hinweise!
Ludger schrieb:> Alignment ist soweit ich es Erinnere auch dabei.
Hab ich reingeschaut. Da finden sich zwar Hinweise auf bestimmte
Sections, aber die werden nicht weiter genutzt (zumindest habe ich
nichts gefunden). Dafür waren andere nützliche Dinge drin.
Johann L. schrieb:> Stattdessen .balign 256 oder .p2align 8
Ludgers Code nutzt ".align 8", ist das äquivalent?
Johann L. schrieb:> Alternativ kann man das in ne eigene Section legen und> das Alignment im ld-Skript festlegen.
Ich wusste nicht, dass man LD-Scripte (bzw. Ausschnitte davon) auf der
Kommandozeile mitgeben kann. Das ist natürlich praktisch. Bisher bin ich
davon ausgegangen, dass man immer ein vollständiges Script mitgeben
muss. Hilft mir in diesem Fall zwar nicht, ist aber sehr nützlich.
Johann L. schrieb:> Das .if funktioniert mit gas nicht, da der Assembler die Länge des> Blocks nicht kennt bzw. nicht kennen kann
Hmm, warum eigentlich nicht? Ob Anfang und Ende innerhalb einer Page
liegen, kann er natürlich nicht wissen, aber die Differenz beider
Werte sollte ja konstant sein...
Bis auf die Asserts war das einfacher als gedacht. Immerhin.
S. R. schrieb:> Johann L. schrieb:>> Stattdessen .balign 256 oder .p2align 8>> Ludgers Code nutzt ".align 8", ist das äquivalent?
.align ist Target-abhängig .balign oder .p2align; daher bevorzuge ich
explizit .balign oder .p2align.
> Johann L. schrieb:>> Alternativ kann man das in ne eigene Section legen und>> das Alignment im ld-Skript festlegen.>> Ich wusste nicht, dass man LD-Scripte (bzw. Ausschnitte davon) auf der> Kommandozeile mitgeben kann.
Das Zeug muss schon in ne eigene Datei.
> Bisher bin ich davon ausgegangen, dass man immer ein vollständiges Script
mitgeben muss.
Was der Compilertreiber (also avr-gcc) nicht kennt an Endung fasst er
nicht an und geht davon aus, das es für den Linker ist. Wenn dieser es
auch nicht identifizieren kann wird's als ld-Script "Augmentation"
verstanden und anders behandelt als -T. Wenn man unbekannte Endungen
verwendet wie .asm für Assembly und dem Treiber dies qua -x
assembler-with-cpp mitteilt, muss man etwas aufpassen:
weil ansonsten memory.x als Assembly-Code interpretiert und der
Assembler damit gefüttert wird (du könntest den Schnipsel z.B. auch
assert.text nennen — das ".x" hat keine Funktion außer dass es eine
unbekannte Endung darstellt).
> Hilft mir in diesem Fall zwar nicht, ist aber sehr nützlich.
Hilft schon, da kein komplettes Script gebraucht wird sondern das
vorhandene quasi gepimpt werden kann mit den wenigen Zeilen.
> Johann L. schrieb:>> Das .if funktioniert mit gas nicht, da der Assembler die Länge des>> Blocks nicht kennt bzw. nicht kennen kann>> Hmm, warum eigentlich nicht?
Jump-Relaxing des Linkers: Wenn ein CALL in Quelle zu einem RCALL wird,
kann der Assembler das nicht wissen, und damit auch nicht der Wert von
Label-Differenzen berechnen. Der Assembler sieht den Code der
Input-(Sub)Section schlicht als als Blob. Wie der Assembler mit
Label-Differenzen umgeht ist target- und evtl. auch schalterabhängig.
Johann L. schrieb:>> Ludgers Code nutzt ".align 8", ist das äquivalent?> .align ist Target-abhängig .balign oder .p2align;> daher bevorzuge ich explizit .balign oder .p2align.
Gekauft.
Dann fiel mir gestern noch auf, dass der gleiche Code plötzlich nicht
mehr in den vorgesehenen Platz passte, weil avra natürlich alles in
Flash-Worten rechnet statt in Bytes. Also muss ich die Blöcke auf 512
Bytes ausrichten und bei LPM aufpassen.
Johann L. schrieb:> Hilft schon, da kein komplettes Script gebraucht wird sondern das> vorhandene quasi gepimpt werden kann mit den wenigen Zeilen.
Ja, das ist verdammt nützlich. Danke für die Erklärung!
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