Forum: Compiler & IDEs Inline-Assembler: 16bit variable speichern


von Oz z. (ozzy)


Lesenswert?

Moin,

ich probiere mich gerade an etwas Codekorrektur mit Inline-Assembler, da 
ich gesehen habe, dass man ein paar Kleinigkeiten schöner machen kann. 
Aber jetzt komme ich gerade nicht weiter: ich habe eine 16bit Variable 
(int16_t sample) und 2 Register (r24, r25). Wie kann ich jetzt die Daten 
aus dem Register in die variable schreiben???

MfG, und vielen Dank, Ozzy

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Die Kristallkugel sagt: Es geht um avr-gcc.
1
asm volatile ("mov %A0, r24" "\n\t"
2
              "mov %B0, r25"
3
                 : "=r" (sample)
4
             );

Müsste gehen

Je nach Maschine auch
1
asm volatile ("movw %0, r24"
2
                 : "=r" (sample)
3
             );

Aber woher willst Du wissen, daß die Werte in r24/r25 sind? Das ist 
selbst nach einem Funktionsaufruf nicht unbedingt gegeben (Auf asm-Ebene 
ja, auf C-Ebene kann der Compiler aber an den GPR-Inhalten gedreht 
haben.)

von Oz z. (ozzy)


Lesenswert?

Hi,

ich habe mir den Assembler-code durchgelesen, und auf die register 
angepasst (mit inline assembler) und hoffe deshalb, dass er auch das 
macht, was da drin steht... Oder kann man davon nicht ausgehen???

Habe aber Deinen Code mal einprogrammiert, aber glücklich bin ich damit 
immer noch nicht:
1
  __asm__ __volatile__ (  "subi  r25, 0x0c"        "\n\t" \
2
              "sbci  r24, 0x08"        "\n\t" \
3
              "mov  %A0, r24"        "\n\t" \
4
              "mov  %B0, r25"        "\n\t" \
5
              : "=r" (sample) );

ergibt:
1
     204:  9c 50         subi  r25, 0x0C  ; 12
2
     206:  88 40         sbci  r24, 0x08  ; 8
3
     208:  88 2f         mov  r24, r24
4
     20a:  99 2f         mov  r25, r25
5
     20c:  90 93 57 02   sts  0x0257, r25
6
     210:  80 93 56 02   sts  0x0256, r24
Kann man sich nicht 208 und 20a irgendwie sparen?

MfG, Ozzy

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Christoph O. wrote:

> Kann man sich nicht 208 und 20a irgendwie sparen?

Kann man, aber du hast es ja explizit so hingeschrieben.

Der inline-Assembler ist ein mächtiges Werkzeug.  Seine Stärke gibt
vor allem den erfahrenen Anwendern und den Entwicklern von
Bibliotheken sehr viel Spielraum, Spezialfunktionalität zu
implementieren, die sich sinnvoll mit dem normalen Compiler
integriert.

Deine Fragen lassen die Vermutung zu, dass du nicht zum genannten
Personenkreis gehörst.  Tu dir einen Gefallen, und lass den
inline-Assembler erstmal links liegen: du brauchst ihn nicht wirklich.
Entweder kannst du die Aufgabe ohnehin mit einem ordentlichen
C-Programm lösen (das ist der einfachste Weg, und nur ganz selten
kommt es wirklich auf die paar Takte extra an), und wenn nicht, dann
greif bitte gleich zu einer richtigen separaten Assemblerdatei, die
deine ISR(s) enthält.  Dann sparst du dir all die Verrenkungen (und
impliziten Grundkurse in Compiler-Technologie), die du für den
inline-Assembler benötigst.

Ein Beispiel für eine separate Assemblerdatei, die just dein Anliegen
erledigt, gibt's in den Beispielen der avr-libc:

http://www.nongnu.org/avr-libc/user-manual/group__asmdemo.html

Dort wird übrigens auch die Begründung geliefert, warum diese
Vorgehensweise für die Erfüllung der Aufgabe notwendig war, und
du siehst ganz nebenbei, dass sich die gleiche Aufgabe durch Wahl
eines moderneren Controllers wiederum mit sehr viel weniger
Aufwand auch in C hätte lösen lassen.  (In der Tat war die
Implementierung auf dem ATtiny45 in C meine Referenz für die
Funktionalität, und an Hand dieser habe ich dann die gemischte
Assembler+C-Implementierung für den ATtiny13 verifiziert.)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Christoph O. wrote:
> Hi,
>
> ich habe mir den Assembler-code durchgelesen, und auf die register
> angepasst (mit inline assembler) und hoffe deshalb, dass er auch das
> macht, was da drin steht... Oder kann man davon nicht ausgehen???
>
> Habe aber Deinen Code mal einprogrammiert, aber glücklich bin ich damit
> immer noch nicht:
>
>
1
>   __asm__ __volatile__ (  "subi  r25, 0x0c"        "\n\t" \
2
>               "sbci  r24, 0x08"        "\n\t" \
3
>               "mov  %A0, r24"        "\n\t" \
4
>               "mov  %B0, r25"        "\n\t" \
5
>               : "=r" (sample) );
6
>
>

Sag doch einfach, was Du haben willst. ;-)
Ich kann ja nicht wissen, daß es sich dabei nicht um ne lokale Variable 
handelt...
1
  __asm__ __volatile__ (  "subi  r25, 0x0c"        "\n\t"
2
              "sbci  r24, 0x08"        "\n\t"
3
              "sts  sample  , r24"        "\n\t"
4
              "sts  sample+1, r25"
5
              :: "memory");

Evtl noch Clobbers für r24/r25

von Oz z. (ozzy)


Lesenswert?

@Johann: vielen Dank für Deine Antwort, dann werde ich das gleich einmal 
ausprobieren...

@Jörg: Du hast natürlich recht! Alles in c ist zu schlecht (mir geht es 
in der ISR wirklich um jeden Takt), und eigentlich wäre assembler auch 
dafür das richtige! Aber ich möchte dieses Projekt dafür nutzen, auch 
ein wenig in inline-Assembler einzusteigen. Aber trotzdem danke für den 
Link, gebrauchen kann ich das auf jeden Fall!!!

MfG, und vielen Dank noch einmal, Ozzy

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.