mikrocontroller.net

Forum: Compiler & IDEs Bit-Copy und freie Register


Autor: Be Mi (bemi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Be Mi (bemi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Be Mi (bemi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
Das ganze sollte sich aber auch irgendwo auf deiner Festplatte befinden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.