Hallo,
ich habe einen Code vor mit, den ich nicht selbstgeschrieben habe,
eigentlich wollte ich den nur kurz compilen und flashen. Der Code ist ca
10 Jahre alt und ich habe schon einige Fehler behoben, aber ich bekomme
bei mehreren Inline-Assembler Blöcken Probleme.
1
uint64_t *__a, *__b; \
2
__a = ((uint64_t *) a); \
3
__b = ((uint64_t *) b); \
4
uint8_t __res,__tmp1, __tmp2; \
5
asm volatile("ldi %0, 0x08" "\n" \
6
".L%_1:" "\n\t" \
7
"ld %1, X+" "\n\t" \
8
"ld %2, Z+" "\n\t" \
9
"cp %1, %2" "\n\t" \
10
"brcs .L%_2" "\n\t" \
11
"dec %1" "\n\t" \
12
"brne .L%_1" "\n\t" \
13
"ldi %0, 0x01" "\n\t" \
14
"rjmp .L%_3" "\n\t" \
15
".L%_2:" "\n\t" \
16
"clr %0" "\n\t" \
17
: "=d" (__res) \
18
: "r" (__tmp1), "r" (__tmp2), "x" (__b), "z" (__a));
Dabei bekomme ich eben den Fehler "invalid 'asm': invalid %-code".
Ich bin mir recht sicher, dass es den .L%_1 liegt, denn wenn ich die "_"
(underscore) durch "A" ersetzte funktioniert es. Wenn man sich die
Zeilen so angucke, dann sieht man das die .L%_n immer als Label
verwendet werden.
Wenn ich das richtig verstanden habe, weist .L auf ein lokales Symbol
hin. Dann müsste das mit %_1 irgendwie einen Namen aus den Inputs unten
(__tmp2) ableiten.
Also dann zu meiner Frage: was bedeutet der "_" und warum sollte jemand
die Labels nicht einfach fest vergeben?
Danke im voraus und viele Grüße,
Marc
Marc L. schrieb:> aber ich bekomme> bei mehreren Inline-Assembler Blöcken Probleme.
Dann laß den Assemblerquatsch und schreib es einfach in C hin.
Ältere AVR-GCC hatten Probleme mit 64Bit und haben dann riesen und
schnarchlahmen Code erzeugt.
Nimm einen aktuellen AVR-GCC.
Würde ich gerne, aber wie schon geschrieben, es ist nicht mein eigener
Code und ich habe auch nicht so recht ne ahnung, was dort passiert.
Coderaten finde ich gerade bei Asm Code sehr schwer und da sind auch
noch ein paar Blöcke drin, die wesentlich länger sind.
Marc L. schrieb:> und warum sollte jemand> die Labels nicht einfach fest vergeben?
vermutlich weil sie im gesamten code eindeutig sein müssen. Man müsste
also selber den überblick behalten welches Label wo ist.
> Wo ist .L%_03? Ganz hinten?
Keine Ahnung, es ist einfach nicht da. Das Fehlt in einem andern Block
auch.
> vermutlich weil sie im gesamten code eindeutig sein müssen. Man müsste
also selber den überblick behalten welches Label wo ist.
Aber stellt nicht .L sicher, dass das Label nur lokal ist?
Eigentlich würde ich den _ nur gerne durch irgendetwas anders ersetzen,
aber ich bekomme einfach nicht heraus, was _ als "Modifier" mal gemacht
hat.
> 64-Bit-Vergleich.
Danke, das ist schonmal nen guter Anfang :)
Marc L. schrieb:> Aber stellt nicht .L sicher, dass das Label nur lokal ist?
Nein.
Mach' es so, wie von denial oben vorgeschlagen.
Die Labels werden nummeriert und dort, wo sie referenziert werden, wird
ein "b" (für "back") oder "f" (für "forward") angehängt. Benutzt wird
dann jeweils das nächstgelegene Label mit derselben Nummer in der
angegebenen Richtung.
Das ist die Standardvorgehensweise für lokale Labels bei gas.
Einigermaßen seltsam, aber funktioniert.
Marc L. schrieb:> Aber stellt nicht .L sicher, dass das Label nur lokal ist?
Lokal schon, aber nur lokal zur Übersetzungseinheit (also das, was bei
C ein „static“ bewirkt).
Aber die Labels müssen innerhalb der Übersetzungseinheit dennoch
eindeutig sein, also irgendwie hochgezählt. Wie sollte der
Assembler denn sonst wissen, zu welchem .L_42 er springen soll, wenn
es deren mehrere gäbe?
Ich würde mich Peters Ratschlag anschließen: hau den Mist raus. „Ich
verstehe nicht, was der Code macht und will ihn daher nicht anfassen.“
ist ja eine tickende Zeitbombe, die kann morgen schon hochgehen oder
in einem Jahr, aber in jedem Falle gefährlich.
Wenn du die Zeitbombe wirklich weiter ticken lassen willst, dann nimm
den Ratschlag mit den local labels an:
Beitrag "Re: Inline Assembler: invalid 'asm': invalid %-code"
Die Affinität einiger Leute zu diesen .L_xx-Labels habe ich ohnehin
nie verstehen können. Dass der Compiler in seinem automatisch
generierten Code sowas benutzt, geht ja noch an (der nummeriert den
Salat halt stur durch), aber für handgeschriebenen Code sind doch
die local labels an dieser Stelle ganz genau das, was man braucht.
Markus F. schrieb:> Das ist die Standardvorgehensweise für lokale Labels bei gas.
Nicht nur da übrigens; das Konzept entstammt meines Wissens den
alten Unix-Assemblern.
ich habe es jetzt einfach durchnummeriert und das funktioniert (wie von
denial oben vorgeschlagen)
> Hat der Autor wirklich nichts kommentiert?
Ja wirklich, außer gelegentlich einem Datei Header leider nichts.
> Wenn du die Zeitbombe wirklich weiter ticken lassen willst, dann nimm
den Ratschlag mit den local labels an:
Ich habe mit dem Code eigentlich nichts zu tun, ich versuche das TTPA
Protokoll auf einer Bit-Seriellen Architektur auf einem FPGA zu
implementieren (im Rahmen meiner Masterarbeit) aber vielleicht verstehe
ich ja, wenns dann läuft was die ASM Blöcke eigentlich machen und
überführe sie dann in C.
Ich dachte das der "_" einfach irgendwie deprecated wär :D unter
http://rn-wissen.de/wiki/index.php/Inline-Assembler_in_avr-gcc#Assembler-Template
konnte ich jedenfalls kein _ bei den % Platzhaltern finden.
Danke an alle
Marc L. schrieb:> ich habe es jetzt einfach durchnummeriert und das funktioniert (wie von> denial oben vorgeschlagen)>>> Hat der Autor wirklich nichts kommentiert?> Ja wirklich, außer gelegentlich einem Datei Header leider nichts.>>> Wenn du die Zeitbombe wirklich weiter ticken lassen willst, dann nimm> den Ratschlag mit den local labels an:> Ich habe mit dem Code eigentlich nichts zu tun, ich versuche das TTPA> Protokoll auf einer Bit-Seriellen Architektur auf einem FPGA zu> implementieren (im Rahmen meiner Masterarbeit) aber vielleicht verstehe> ich ja, wenns dann läuft was die ASM Blöcke eigentlich machen und> überführe sie dann in C.
Wie schon gesagt, da steht nichts weiter als
1
if(a<=b)
wobei ich mir mit dem 'gleich' nicht ganz sicher bin.
Analysier mit dem Hintergrund an der verwendenden Stelle, wie das ins
Bild passt, und wenn du die Richtung hast, wer mit wem in welcher
Relation verglichen wird, dann schmeiss den Assembler Teil raus. Denn so
wie dir jetzt, geht es dann auch dem nächsten, der den Code studiert.
Verschwendete Zeit, das nicht ein für alle mal durch C Code zu ersetzen.
Und jetzt komm mir keiner damit, dass Assembler ja sooooo viel schneller
wäre.