Forum: Mikrocontroller und Digitale Elektronik Inlineassembler für ARV-GCC: Habe Schwierigkeiten mit den "Constraint Modifiers"


von Drago (Gast)


Lesenswert?

Hallo zusammen,

ich habe folgendes Problem:
ich möchte jedes 2. Bit aus einem 16-Bit-integer (unsigned) in einen 
8-Bit-integer (unsigned) schreiben. Da dies sehr sehr häufig gemacht 
werden muss habe ich mir ein paar Gedanken gemacht wie man hier etwas 
"tunen" könnte.

Mein bisheriger Code erledigt das recht zuverlässig, nur leider recht 
langsam.
1
uint16_t in;
2
uint8_t out;
3
for( uint8_t i=0; i<8; i++ )
4
{
5
  if( in & (1<<14) )
6
    out++;
7
  out<<1;
8
  in<<2;
9
}

Mein vielleicht schnellerer Ansatz sieht folgendermaßen aus:
1
uint16_t in;
2
uint8_t out=0, out2;
3
for( uint8_t i=0; i<4; i++ )
4
{
5
  __asm(  "LSL  %1  \n\t"
6
          "LSL  %1  \n\t"
7
          "ROL  %0  \n\t"
8
          : "+r" (out)
9
          : "+r" (in&0xFF) );
10
11
  __asm(  "LSL  %1  \n\t"
12
          "LSL  %1  \n\t"
13
          "ROL  %0  \n\t"
14
          : "=r" (out2)
15
          : "+r" (in>>8) );
16
  out = out | (out2<<4);
17
}
Und auch wenn ich mir mittlerweile nicht wirklich sicher bin ob der Code 
effizienter ist (ein genauer Vergleich steht noch aus) stelle ich mich 
wirklich doof mit den Constraints und den Constraint Modifiers an.
Ich werde gerade nicht schlau was Output, was Input und was wie wer sein 
muss. Und genau das ist mein Problem, nicht die ursprüngliche Aufgabe, 
sondern mein Unverständnis was was ist und warum ein Register Output ist 
und das andere nicht.
Für meine Begriffe ist ja das "out"-Register sowohl Output als auch 
Input (muss ja zuvor 0x00 sein). "out2" ist nur Output. "in" ist 
eigentlich nur Input, wird aber verändert, also auch muss es auch Output 
sein?

Wäre schön wenn mir jemand da mal ein Lichtlein einschalten könnte. Ich 
glaube ich stehe gerade vollkommen auf dem Schlauch.

Vielen Dank
Drago

von Peter D. (peda)


Lesenswert?

Drago schrieb:
> Da dies sehr sehr häufig gemacht
> werden muss

Wie häufig?
Und wie lang ist die Dauer im Verhältnis zum restlichen Code der Task?

Anfänger unterliegen oft dem Irrtum, daß sie meinen, etwas optimieren zu 
müssen, was fast keinen Einfluß auf die Gesamtperformance hat.


Assembler ist nichts, was man ohne Notwendigkeit im Code haben möchte.
Es macht den Code schlechter lesbar, wartbar und unportabel, falls man 
den MC oder Compiler wechseln möchte.

von Drago (Gast)


Lesenswert?

Ich hab mit meinem Oszi und einem Debug-Pin mal gemessen wie lange er wo 
braucht und für die Konvertierung des Manchester-Codes zu nutzbaren 
Daten (genau das ist das hier) benötigt der µC 40% der Zeit. weitere 50% 
gehen für alle möglichen anderen Aufgaben drauf. 10% sind noch frei.
Das spielt aber nicht ganz die große Rolle, mich ärgert mehr, dass ich 
das gerade nicht kapier welcher Contraint Modifier wann genommen werden 
muss und wann ein Register also output oder input zählt.

von Ralf G. (ralg)


Lesenswert?

Drago schrieb:
> Ich werde gerade nicht schlau was Output, was Input und was wie wer sein
> muss.
[... Ich auch nicht, aber das ist nicht der Maßstab. :) ]

Dein Assemblerschnipsel schiebt 4x was hin- und her. Dein C-Code schiebt 
8x was anderes und vergleicht und rechnet noch. Das soll dasselbe 
Ergebnis bringen?

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


Lesenswert?

Drago schrieb:

>   out<<1;
>   in<<2;

Das sind übrigens zwei Anweisungen, die keinen Effekt haben.

> Ich werde gerade nicht schlau was Output, was Input und was wie wer sein
> muss.

“input” = „Was geht aus der (C-)Umgebung in die inline-asm-Anweisung
hinein?“

“output” = „Was bekommt die C-Umgebung aus der inline-asm-Anweisung
zurück?“

von Stefan E. (sternst)


Lesenswert?

Drago schrieb:
> Und auch wenn ich mir mittlerweile nicht wirklich sicher bin ob der Code
> effizienter ist

Deutlich effizienter, als das ganze Geschiebe in einer Schleife, sind 
jedenfalls 8 BST/BLD-Pärchen. Und es befreit dich auch gleich von einem 
großen Teil deiner Kopfschmerzen:
> Für meine Begriffe ist ja das "out"-Register sowohl Output als auch
> Input (muss ja zuvor 0x00 sein). "out2" ist nur Output. "in" ist
> eigentlich nur Input, wird aber verändert, also auch muss es auch Output
> sein?
Man hat dann nur ein "out", das eindeutig nur Output ist, und "in" wird 
nicht verändert, ist also eindeutig nur Input.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Da es bereits Probleme mit der Formulierung einer C-Lösung gibt, würde 
ich hier von Inline-Assembler abraten.  Mit
1
#include <stdint.h>
2
3
uint8_t func (uint16_t in)
4
{
5
    uint8_t out = in & (1 << 0);
6
    
7
    if (in & (1 <<  2))  out |= 1 << 1;
8
    if (in & (1 <<  4))  out |= 1 << 2;
9
    if (in & (1 <<  6))  out |= 1 << 3;
10
    if (in & (1 <<  8))  out |= 1 << 4;
11
    if (in & (1 << 10))  out |= 1 << 5;
12
    if (in & (1 << 12))  out |= 1 << 6;
13
    if (in & (1 << 14))  out |= 1 << 7;
14
    
15
    return out;
16
}
erhältst du eine Lösung, die nichts hinter Assembler zurücksteht.

von c-hater (Gast)


Lesenswert?

Peter Dannegger schrieb:

> Anfänger unterliegen oft dem Irrtum, daß sie meinen, etwas optimieren zu
> müssen, was fast keinen Einfluß auf die Gesamtperformance hat.

Das ist wahr.

> Assembler ist nichts, was man ohne Notwendigkeit im Code haben möchte.
> Es macht den Code schlechter lesbar

Das ist ABSOLUTER SCHWACHSINN. Die unleserlichste aller Sprachen ist und 
bleibt C. Nur C-Junkies, die diesen Scheiß gewohnheitsmäßig nehmen, 
empfinden das anders. Typischer Gewohnheits-Drogeneffekt, bloß ohne 
wirklich angenehme Empfindung, wie er bei richtigen Drogen wenigstens 
gelegentlich rauskommt.

> unportabel

Blah, bläh.

Ja klar, Asm ist tatsächlich praktisch nicht architekturübergreifend 
portabel.

Allerdings ist der allermeiste C-Code, das genausowenig. Und falls doch, 
ist er wiederum kaum noch les- oder wartbar, denn "Portabilität" wird 
überwiegend durch endlose #ifdef-Orgien erreicht.

Denn der harte Kern der vielgelobten Portabilität von C ist: Es gibt sie 
garnicht, jedenfalls nicht als Eigenschaft der Sprache selber, sondern 
nur als Ergebnis der Tatsache, daß sie einen Präprozessor beschäftigt.

Das tun allerdings auch (Macro-)Assembler...

Sprich: Man braucht eigentlich nur Assembler für verschiedene 
Zielsysteme, die einen gemeinsamen Satz an Präprozessor-Anweisungen 
haben, um genauso "portable" Programme wie in C schreiben zu können.

Lustig: Genauso ist C entstanden. Der Dreck ist letztlich nicht mehr als 
ein aufgedonnerter Macroassembler mit völlig kruder Syntax.

von holger (Gast)


Lesenswert?

>Da es bereits Probleme mit der Formulierung einer C-Lösung gibt

Oder besser gesagt einen Code zeigt der gar nicht funktionieren kann.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mann, mann. Bin ich froh, daß ichnicht mit so nem neutotischen Nörgler 
wie c-hater zusammen arbeiten muß!

von holger (Gast)


Lesenswert?

>Mann, mann. Bin ich froh, daß ichnicht mit so nem neutotischen Nörgler
>wie c-hater zusammen arbeiten muß!

Den nimmt doch hier sowieso keiner ernst.
Ist halt der Pausenclown;)

von AVR (Gast)


Lesenswert?

Wenn man bedenkt, wie direkt PDP11 Assembler C Konstrukte abbilden kann, 
dann fragt man sich, warum die ihr Unix nicht weiter in ASM11 schreiben 
wollten und eine dermaßen unbeliebte Sprache erfinden mußten.
(wer Ironie findet, darf sie behalten!)

von Argus (Gast)


Lesenswert?

Johann L. schrieb:
> Mann, mann. Bin ich froh, daß ichnicht mit so nem neutotischen
> Nörgler
> wie c-hater zusammen arbeiten muß!

mag sein, jedoch wo er Recht hat, hat er Recht.
Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer 
Makroassembler mit gleicher Syntax nicht auch könnte, mit Ausnahme der 
tollen Optimierung die in einigen Fällen aber auch gerne Murks 
produziert.

Die Sprache C bietet auf Compilerebene ohne Präprozessor semantisch 
nichts weiter als ein paar Fallunterscheidungen, Pseudoschleifen, 
Funktionsgerüste, wilde Datentypen und Argumentkonventionen. Das ist auf 
der einen Seite die Stärke, jedoch hat sich auf der Anderen Seite ein 
Crack-Junkie diese krude, unleserliche Syntax ausgedacht.

C++ wäre eine Chance gewesen damit aufzuräumen, denn die eigentlichen 
Mängel hat man versucht durch eine neue Implementation auszubügeln, aber 
nein man konnte es ja nicht lassen eine Abwärtskompatibilität einzubauen 
und damit dem Crack-Junkie die Möglichkeit geben sich wieder so 
auszutoben, wie er es seit Jahr und Tag gemacht hat.

einfach widerlich

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


Lesenswert?

Argus schrieb:
> mag sein, jedoch wo er Recht hat, hat er Recht.

Allerdings hat er selten Recht.  Pausenclown eben.

von Bastler (Gast)


Lesenswert?

Die C Entwickler hatten kein Crack, nur LSD.
Crack ist dazu da die wahrhaft grauslichen Sprachen der Script-Kiddies 
zu ertragen.

von holger (Gast)


Lesenswert?

>mag sein, jedoch wo er Recht hat, hat er Recht.
>Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer
>Makroassembler mit gleicher Syntax nicht auch könnte

Aufgrund deines Posts werden jetzt natürlich
1000ende C Programmierer zu Assembler Programmierern
konvertieren.

Was hat dein Post jetzt gebracht?
Nichts. Er war überflüssig.

von Maxim (Gast)


Lesenswert?

holger schrieb:
>>mag sein, jedoch wo er Recht hat, hat er Recht.
>>Die Sprache C kann nichts, aber auch gar nichts was ein aufgebohrer
>>Makroassembler mit gleicher Syntax nicht auch könnte
>
> Aufgrund deines Posts werden jetzt natürlich
> 1000ende C Programmierer zu Assembler Programmierern
> konvertieren.
>
> Was hat dein Post jetzt gebracht?
> Nichts. Er war überflüssig.

nun, er hat in einem Forum auf einen Beitrag seine Sichtweise dargelegt. 
Einen "Aufruf an alle C-Programmierer die Sprache zu wechseln" kann ich 
beim Besten Willen nicht erkennen. Das bleibt deiner Phantasie 
geschuldet.

Ich neige ihm zuzustimmen, auch wenn es mein täglich Brot ist. Modula 
halte ich für die bessere Alternative, aber es ist nicht gewollt 
(zumindest bei uns). Man beugt sich dem Markt und den etablierten 
Systemen. Das ist mit Windows vergleichbar: hoher Verbreitungsgrad, 
unzählige Anwendungen, sogutwie Jeder hat es. Deswegen ist Windows noch 
lange nicht der Weisheit letzter Schluss.

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.