Forum: Compiler & IDEs Atmega Indexregister mit Inline Assembler (Arduino) setzen


von Andreas R. (andreasr2)


Lesenswert?

Guten Abend Programmiergemeinde,

ich möchte auf einem Arduino nano ein zeitkritisches Programmteil
mittels inline Assembler realisieren. Bei dem Versuch das X Register zu
laden, bekomme ich eine mir nicht verständliche Fehlermeldung.

Was mache ich falsch?

Quellcode:

void setup() {
  // put your setup code here, to run once:

}

int wert;
int *p_wert = &wert;

void loop() {
  // put your main code here, to run repeatedly:

  asm volatile(
    "ldi r26, LOW(p_wert)\n\t"
    "ldi r27, HIGH(p_wert)\n\t");

    // ... hier dann weiterer code
}

Und hier die Fehlermeldungen:

Arduino: 1.6.9 (Windows 7), Board: "Arduino Nano, ATmega328"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs
-logger=machine -hardware "C:\Program Files (x86)\Arduino\hardware"
-hardware "C:\Users\Andi\AppData\Local\Arduino15\packages" -hardware
"C:\Users\Andi\Documents\Arduino\hardware" -tools "C:\Program Files
(x86)\Arduino\tools-builder" -tools "C:\Program Files
(x86)\Arduino\hardware\tools\avr" -tools
"C:\Users\Andi\AppData\Local\Arduino15\packages" -built-in-libraries
"C:\Program Files (x86)\Arduino\libraries" -libraries
"C:\Users\Andi\Documents\Arduino\libraries"
-fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10609 -build-path
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp"  -warnings=none -prefs=build.warn_data_percentage=75 -verbose
"C:\Users\Andi\Documents\Arduino\InlineAssembler\InlineAssembler.ino"
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine
-hardware "C:\Program Files (x86)\Arduino\hardware" -hardware
"C:\Users\Andi\AppData\Local\Arduino15\packages" -hardware
"C:\Users\Andi\Documents\Arduino\hardware" -tools "C:\Program Files
(x86)\Arduino\tools-builder" -tools "C:\Program Files
(x86)\Arduino\hardware\tools\avr" -tools
"C:\Users\Andi\AppData\Local\Arduino15\packages" -built-in-libraries
"C:\Program Files (x86)\Arduino\libraries" -libraries
"C:\Users\Andi\Documents\Arduino\libraries"
-fqbn=arduino:avr:nano:cpu=atmega328 -ide-version=10609 -build-path
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp"  -warnings=none -prefs=build.warn_data_percentage=75 -verbose
"C:\Users\Andi\Documents\Arduino\InlineAssembler\InlineAssembler.ino"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g
-Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections
-fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega328p
-DF_CPU=16000000L -DARDUINO=10609 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR
"-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino"
"-IC:\Program Files
(x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs"
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\sketch\InlineAssembler.ino.cpp"  -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g
-Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections
-fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega328p
-DF_CPU=16000000L -DARDUINO=10609 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR
"-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino"
"-IC:\Program Files
(x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs"
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\sketch\InlineAssembler.ino.cpp"  -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g
-Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections
-fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega328p
-DF_CPU=16000000L -DARDUINO=10609 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR
"-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino"
"-IC:\Program Files
(x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs"
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\sketch\InlineAssembler.ino.cpp"  -o
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino10/ctags"
-u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns
--line-directives
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g
-Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections
-fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L
-DARDUINO=10609 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR   "-IC:\Program
Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program
Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs"
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\sketch\InlineAssembler.ino.cpp"  -o
"C:\Users\Andi\AppData\Local\Temp\build7277334a56787ac19e2e500382681313.
tmp\sketch\InlineAssembler.ino.cpp.o"
C:\Users\Andi\AppData\Local\Temp\ccurZb2d.s: Assembler messages:

C:\Users\Andi\AppData\Local\Temp\ccurZb2d.s:40: Error: garbage at end of
line

C:\Users\Andi\AppData\Local\Temp\ccurZb2d.s:41: Error: garbage at end of
line

exit status 1
Fehler beim Kompilieren für das Board Arduino Nano.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Du musst GNU-Assembler verwenden; LOW und HIGH gehören nicht dazu.

Ich würd's so hinschreiben:
1
void loop()
2
{
3
    unsigned reg_x;
4
    asm ("ldi %A0, lo8(%1)"   "\n\t"
5
         "ldi %B0, hi8(%1)"
6
         : "=x" (reg_x) : "i" (&p_wert));
7
}

aber keine Ahnung, was du damit erreichen willst.  Damit bekommst du die 
Adresse von p_wert ins X-Register, oder willst du den Inhalt von 
p_wert im X-Register haben?

von Andreas R. (andreasr2)


Lesenswert?

Danke für die schnelle Antwort.

Hatte ich vergessen, zu sagen: Ich möchte die Adresse der Variablen wert 
im X-Register haben. Also den Inhalt von p_wert.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was jetzt? Die Adresse von wert oder der Inhalt von p_wert?  Das ist 
nicht das gleiche.

von Andreas R. (andreasr2)


Lesenswert?

In p_wert steht doch die Adresse von wert, deshalb gehe ich davon aus, 
das die Adresse von wert und der Inhalt von p_wert identisch sind, wegen 
der zuweisung

p_wert = &wert.

oder täusche ich mich da?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Der Wert mag der gleiche sein, der Assembler-Code für "Inhalt von 
p_wert" und "Adresse von Wert" ist es nicht.

Außerdem kann sich p_wert im Programmverlauf ändern; &wert wird sich 
nicht ändern.

von Andreas R. (andreasr2)


Lesenswert?

Das sehe ich ein. p_wert war auch nur ein Hilfskonstrukt von mir. Im 
Grunde soll die Adresse von wert in das X-Register geschrieben werden.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Dann nimm den Code von oben, d.h.
1
void loop()
2
{
3
    int *reg_x;
4
    asm ("ldi %A0, lo8(%1)"   "\n\t"
5
         "ldi %B0, hi8(%1)"
6
         : "=x" (reg_x) : "i" (&wert));
7
}

Sonderlich sinnig ist das aber nicht, das kannst auch mit Vanilla C++ 
hinschreiben...

von Andreas R. (andreasr2)


Lesenswert?

Danke für das Code Beispiel. So richitg hab ich es noch nicht 
verstanden, werde mich mal bei der Syntax einlesen. Die Definition von 
int* reg_x verstehe ich nicht. Mit X-Register meinte ich r27:r26 vom 
Atmega328.

Trotzdem Danke :)

: Bearbeitet durch User
von Walter S. (avatar)


Lesenswert?

Andreas R. schrieb:
> ich möchte auf einem Arduino nano ein zeitkritisches Programmteil
> mittels inline Assembler realisieren.

loop und zeitkritisch passen nicht zusammen,
und ich traue mich zu wetten dass inline Assembler nicht notwendig ist

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas R. schrieb:
> int* reg_x verstehe ich nicht. Mit X-Register meinte ich r27:r26 vom
> Atmega328.

Es ist das, was mein Beispiel macht.  Die Registerbelegung ist mir 
bekannt.

Wenn du sehen willst, was der Compiler daraus macht, gib ein -save-temps 
zu dessen Optionen und schau in die erzeugte s-Datei.  Weil "X mit &wert 
laden" keine Nebeneffekte auf Hochsprachenebene hat, wird der Compiler 
das wegoptimieren.  Zu Debug-Zwecken kann ein volatile zum asm gegeben 
werden, aber die Aktion "X = &wert" selbst ist eben nicht volatile, und 
daher hat mein Beispiel eben kein volatile drinne.

: Bearbeitet durch User
von Andreas R. (andreasr2)


Lesenswert?

Das habe ich verstanden. Ich danke Dir für Deine Geduld.

von Andreas R. (andreasr2)


Lesenswert?

Ich muß nochmal nerven ....

habe jetzt 2 Stunden gesucht, wo ich diese -save-temps option 
unterbringen kann. Ich finde das makefile bzw. die Compileroptionen 
einfach nicht ... :(

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Keine Ahnung, vielleicht in einem Arduino-Forum fragen?

Der Code von oben lässt sich übrigens noch vereinfachen zu
1
void loop()
2
{
3
    asm ("" :: "x" (&wert));
4
}

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.