Forum: Compiler & IDEs Problem mit Stackptr und sbic bei GCC-Inline-ASM


von David Reis (Gast)


Lesenswert?

Salute,

hab hier momentan ein Problem mit dem AVR-GCC 3.4.1 und der inline
ASM-Funktion, genauer gesagt mit dem Schreiben von Registern. Zwei
Codestellen erzeugen Fehler:

asm("ldi R16, 0x5F"
"out SPL, R16"
"ldi R16, 0x08"
"out SPH, R16"::)

( wobei 0x5F == LOW(RAMEND) und 0x08 == HIGH(RAMEND); Einsatz der
beiden Konstanten ebenfalls Fehler. Das Ganze laesst sich mit SPH =
0x08; SPL = 0x5F; in C loesen, ist aber trotzdem nicht normal - oder?
)

ebenso:
asm("sbic PORTB, data"::)

( wobei .equ data, 1 und im Funktionsaufruf davor ein sbic PORTB, clock
einwandfrei funktioniert; am .equ oder dem Namen liegts ebenfalls nicht
)

erzeugen

<linInASM>: Error: Constant value required

Jemand eine Idee? uC ATMega32, WinAVR von gestern unter Windwos 2000.

Danke,
David

PS: ".def" ergibt "unknown pseudo-op: .def". Evtl. ein Hinweis? Und
wie krieg ich .def zum Laufen?

von Rufus T. Firefly (Gast)


Lesenswert?

Verstehe ich das richtig, daß Du den Stackpointer verändern möchtest?

Ist dafür nicht der Startup-Code verantwortlich, der eh' zum Programm
gelinkt wird?

von David Reis (Gast)


Lesenswert?

Hm, sicher? In saemtlichen Tutorials steht, dass vor der Verwendung von
Unterprogrammen manuell der Stack-Ptr initialisiert werden muss. Mir
gings aber auch eher darum, dass nicht geht, was eigentlich gehen
sollte. Ebenso grade passiert:

sbi PORTD, 2
...
cbi PORTD, 2

Error: Constant value required

Kryptisch...

Danke,
David

von Matthias (Gast)


Lesenswert?

Hi

Inline-ASM und GCC ist etwas, naja, gewöhnungsbedürftig. Ließ dazu
bitte in der AVRLibc Doku den entsprechenden Abschnitt.

Aber am SP mußt du nicht (und sollst auch nicht) manuell rumhantieren.
Das macht der Compiler bzw. der Start-Up Code für dich.

Und du setzt nicht zufällig einen Mega128 ein und Unterprogramme
funktionieren nicht?

Matthias

von David Reis (Gast)


Lesenswert?

Hi,

ist ein Atmega32, wie gesagt, und der Code nicht arg kompliziert. Werd
mir jedenfalls mal die Libc-Doku ansehen, danke...

David

von David Reis (Gast)


Lesenswert?

Grade nachgesehen, war bereits bekannt und so implementiert. Nur nicht
gewusst, dass das Dokument offiziell ist. Mir gefaellts jedenfalls :)

David

von David Reis (Gast)


Lesenswert?

Sorry fuer TP, aber:

in R21, PORTB

Error: constant value required

Keiner eine Idee? :/

David

von Andreas W. (Gast)


Lesenswert?

Hallo,

schau mal in die docu der avrlib-c:

asm("in r21, %0" : : "I"(_SFR_IO_ADDR(PORTB)));


Gruß
Andreas

von David Reis (Gast)


Lesenswert?

Ach, das muss so? blush
Sorry fuer die Vergeudung eurer Zeit, hatte ich wohl nicht richtig
gelesen...

duck,
David

von Peter D. (peda)


Lesenswert?

Alles, was Du da schreibst, geht doch viel einfacher in C.

Man fängt sich mit Assembler immer Portabilitätsprobleme ein, sollte
ihn daher nur dann benutzen, wenn es auch wirklich notwendig ist.

Und einfach so auf Register zu schreiben ist in der Regel tödlich, wenn
man sie vorher nicht gepusht hat.
Der Compiler sichert nur die Register, die er auch selber verwendet.


Die einzige Notwendigkeit für Assembler sind eigentlich nur
superschnelle Interrupts, wo das unsägliche R0,R1-Geraffel zu lange
dauert (9 unnütze Zyklen).


Peter

von David Reis (Gast)


Lesenswert?

Das, was ich schrieb, waren natuerlich nur Teile von ASM-Code, an
Stellen, wo ich die Struktur nicht durch C aufbrechen wollte.
Inzwischen allerdings ist das Programm auf C umgebaut, mit ASM-Includes
und Unterfunktionen, das funtioniert viel besser. Sind jetzt nur noch
Dinge wie Shifts u ae in ASM, auf der Ebene einfacher zu verstehen und
wohl auch schneller.
Zugegebenermaszen versuche ich grade ein Problem mit der
Ueberschreibung von Registern zu loesen :) Ist auch eher ein
Lernprojekt fuer mich.

David

von peter dannegger (Gast)


Lesenswert?

Schieben kann man auch in C, sogar mit mehreren Schreibweisen und auch
16 oder 32 Bit.

nach links:

i <<= 1;
i += i;
i *= 2;

nach rechts:

i >>= 1;
i /= 2;

Such Dir eine aus.
Beim Rechtsschieben Typ (signed/unsigned) beachten !


Das mit den Registern ist alles andere als trivial.
Mit etwas Glück faßt der Compiler R2...R11 nicht an, die kannst Du dann
selber verwenden.

Aber es gibt keinen Mechanismus, es dem Compiler zu verbieten oder ihm
wenigtens ne Warnung zu entlocken, falls er es doch versucht.

Es bleibt also nur, im gesamten Programmlisting danach zu suchen, ob
die Register wirklich nur an den gewünschten Stellen verwendet werden.


Peter

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.