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
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.
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
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.
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
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html Das ganze sollte sich aber auch irgendwo auf deiner Festplatte befinden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.