Bit-Copy und freie Register

OP #675398
Aller Anfang ist schwer.

Hallo,

ich arbeite mich gerade in GCCAVR ein und stoße auf zwei Fragen:

1. Bit-Copy:
Ich möchte nacheinander verschiedene Bits aus einer Variable in ein 
IO-Register kopieren.
In ASM würde ich das so machen, wobei in r16 das auszugebende Byte 
steht. Hier wird also erst das entsprechende Bit (6) gelöscht und dann, 
wenn Bit 4 in r16 eins ist wieder gesetzt.
   cbi  PORTB, 6
   sbrc r16, 4
   sbi  PORTB, 6
Wie schreibe ich so etwas in C, damit der Compiler daraus keine 
unnötigen Befehle erzeugt?

2. Wenn ich inline assembly verwenden will, woher weiß ich, welche 
Register ich dann frei verwenden kann?

3. Wo finde ich weitere Informationen darüber, wie man Daten zwischen C 
Funktionen und Inline Assembly austauscht.

Danke,
Bernd
#675400
Bernd M. wrote:

> Wie schreibe ich so etwas in C, damit der Compiler daraus keine
> unnötigen Befehle erzeugt?

if (x&(1<<4))
 PORTB|=(1<<6);
else
 PORTB&=~(1<<6);

> 2. Wenn ich inline assembly verwenden will, woher weiß ich, welche
> Register ich dann frei verwenden kann?

Darum kümmert sich der Compiler. Dazu musst du ihm mitteilen, welche 
Register du verwendest. Siehe Dokumentation. Ich würde dir aber 
empfehlen erstmal kein inline asm zu verwenden, das ganze Zeug mit 
inline asm ist meiner Meinung nach etwas dumm gemacht und sehr 
fehleranfällig wenn man nicht ganz verstanden hat wie das genau 
funktioniert.

> 3. Wo finde ich weitere Informationen darüber, wie man Daten zwischen C
> Funktionen und Inline Assembly austauscht.

Dokumentation die beim Compiler dabei ist.
OP #675416
Mal abgesehen davon, dass die Funktion bei Bit4=0 5 Zyklen und by Bit4=1 
6 Zylken braucht funktionniert es. Allerdings braucht die ASM variante 
jeweils nur 5 Zyklen und besteht nur aus 3 Befehlen.

Die Frage ist allerdings, woher weiß ich, wenn ich Inline Assemble 
programiere, in welchem Register der Compiler die Variable unterbring? 
Ich weiß, die Doku, aber die ist meist nur schwer verständlich.

Grüße,
Bernd

48:       if (b&(1<<4))
+0000007A:   FF84        SBRS    R24,4            Skip if bit in 
register set
+0000007B:   C002        RJMP    PC+0x0003        Relative jump
49:        PORTB|=(1<<6);
+0000007C:   9A2E        SBI     0x05,6           Set bit in I/O 
register
+0000007D:   C001        RJMP    PC+0x0002        Relative jump
51:        PORTB&=~(1<<6);
+0000007E:   982E        CBI     0x05,6           Clear bit in I/O 
register
5
#675423
Bernd M. wrote:
> Mal abgesehen davon, dass die Funktion bei Bit4=0 5 Zyklen und by Bit4=1
> 6 Zylken braucht funktionniert es. Allerdings braucht die ASM variante
> jeweils nur 5 Zyklen und besteht nur aus 3 Befehlen.

Dann versuchs mal so:
PORTB&=~(1<<6);
if (x&(1<<4))
 PORTB|=(1<<6);
Das müsste das gleiche wie die Assembler Lösung erzeugen.


> Die Frage ist allerdings, woher weiß ich, wenn ich Inline Assemble
> programiere, in welchem Register der Compiler die Variable unterbring?

Das weist du nicht, denn der Compiler entscheidet das. Du sagst dem 
Compiler, dass du den Wert der Variable x benötigt, die dann im 
Assembler Coder den Platzhalter 0 bekommt, und du teilst dem Compiler 
mit, dass du das Ergebnis deiner Berechnungen in y haben möchtest, die 
dann den Platzhalter 1 bekommt.
Welche Register am Ende für 0 und 1 verwendet werden, entscheidet der 
Compiler.
OP #675427
Dumme Frage, dann mir jemand einen Link mit Seitenangabe schicken, wo 
das beschreiben ist. Ich weiß nämlich ehrlich gesagt nicht, wo ich 
suchen soll.
Ich habe als Compiler das WinAVR Packet installiert. Da ist auch ein DOC 
Folder, nur dann weiß ich nicht mehr weiter.

Bernd

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.