Das Beispiel ist schlecht gewählt.
Ist mit "Drehen" ein Vertauschen von MSB und LSB gemeint?
Soll aus 10100000
00000101
werden?
Oder --und dann hätte Sven die Lösung bereits genannt--
soll daraus
01011111
werden?
nein aus 10100000 soll 00000101 werden.
ich habe ein display in einer Schlatung falschrum an einen Port
angeschlossen und möchte dies nun im Programm korigieren, indem ich das
Datenwort einfach drehe, wenn das möglich ist.
also aus
abcdefgh -> hgfedcba
das machst vermutlich am schnellsten über eine Lookuptable. Diese muss
im Idealfall die Größe von 256 Bytes haben und da steht schon der fertig
berechnete Wert drin.
Alternativ kannst das auch in 2 Schritten machen, zuerst das Nibble
"abcd" in der Tabelle nachschlagen, dann "efgh" und die entsprechenden
Werte dann eben mit Shifts etc. verodern
also
1
data[0b0000]=0b0000;
2
data[0b0001]=0b1000;
3
data[0b0010]=0b0100;
4
...
5
data[0b1111]=0b1111;
6
7
unsignedcharreverse(unsignedcharinp){
8
return(data[inp&0x0F]<<4)|data[inp>>4];
9
}
Beim AVR data ggf im PROGMEM ablegen und mit enntsprechenden Makrros
zugreifen.
evtl gibt es aber auch noch eine elegantere Lösung, auf die Schnelle bin
ich aber auf keine gkommen die nicht x-tausend shifts benötigt.
Gruß
Roland
>indem ich das Datenwort einfach drehe, wenn das möglich ist.
Aber warum lässt du das nicht einfach weg. die Kommandos kannst du
verher umrechnen. Dann heißen die halt anders und fertig. Bei den
Bitmaps spielt das eh keine Rolle.. Es sei denn, es ist kein
Grafikdisplay...
Hab das mal so gelöst:
for (i=0; i<8; i++){
temp3 |= (((temp2>>i) & 1) << (7-i));
}
temp3 ist dann das gespiegelte von temp2.
Aber denks nochmal durch. Das hat nie jemand richtig getestet.
Aber ich glaub, das von peda ist eh schneller.
Sebastian
Sebastian wrote:
> Hab das mal so gelöst:>> for (i=0; i<8; i++){> temp3 |= (((temp2>>i) & 1) << (7-i));> }
um ehrlich zu sein, das ist so ziemlich das Ineffizienteste, was du
hinlegen kannst :-) Der AVR mag Schiebereien um mehr als ein Bit
(tem2>>i) aber soooowas von ungern... und das gleich noch zweimal, ne,
Fingers wech!
wenn lookuptable zu groß, dann schon lieber so:
out = 0;
for(i=0; i<8; i++)
{
out >>= 1;
out |= in & 0x80;
in <<= 1;
}
ich denke, das meinte spess53 auch mit seinem etwas kryptischen "8x
shr rxy
rol ryx"
Vielleicht doch lieber die 8 Leitungen drehen... ? ;-)
naja, der zeichensatz war ja nicht so das problem... ;-)
interessehalber: schiebt denn "SHR" das unterste bit in irgend ein
"carry" register, das mit "ROL" wieder von unten reingeschoben wird?
wenn ja, dann wäre das ja wesentlich effektiver als jegliche c-lösungen
und wäre nen klarer fall für
#asm
#endasm
Hi
>interessehalber: schiebt denn "SHR" das unterste bit in irgend ein>"carry" register, das mit "ROL" wieder von unten reingeschoben wird?>wenn ja, dann wäre das ja wesentlich effektiver als jegliche c-lösungen>und wäre nen klarer fall für
Genau so ist es!
MfG Spess
Matthias Lipinsky wrote:
>>schiebt denn "SHR" das unterste bit>> Wenn du LSL/LSR meinst, dann nein.> Das machen nur die ROL/ROR.
Bitte? Auch bei LSx kommt das "rausfallende" Bit ins Carry. Der einzige
Unterschied zwischen LSx und ROx besteht darin, was nachgeschoben wird.
Och watt süüüssss,
Wird jetzt wieder lang-und-breit über etwas debattiert, was...
-JEDER asm-programmierer wissen MUSS?
-EIN BLICK ins Datenblatt klärt?
-VÖLLIG indiskutabel ist?
@lippy,
Wenn Dir ASM nicht so geläufig ist, dann ist das ja keine Schande.
Schändlich wird es, wenn man dann lauthals Falschinformationen
verbreitet.
@sternst,
Genau das was Du schreibst stimmt natürlich. Das ist auch weder
verhandlungsfähig noch diskutabel. Es ist so und fertig. Jede
Gegenmeinung ist schlichtweg dummer Unsinn, der niemandem etwas nützt.
@vref,
das Bit wird nicht in IRGENDEIN CARRY geschoben, sondern in DAS
(einzige) CARRY. Diese Präzisierung sollte auch ein C'ler kennen und
beachten!
Jochen Müller
danke, da es sich ja nur um einen Prototyp für mich handelt, denke ich
werde ich einfach einen Adapter bauen, der die Belegung umdreht. Das
macht das Ganze wesentlich einfacher.
Danke trozdem. ich dachte, dass es vielleicht eine Funktion wie
reverse(); gibt. Naja egal. danke nochmal.
> Danke trozdem. ich dachte, dass es vielleicht eine Funktion wie> reverse(); gibt. Naja egal. danke nochmal.
Hmm,
Du hast doch eine mirror Funktion bekommen, wo liegt jetzt das Problem ?
>Bitte? Auch bei LSx kommt das "rausfallende" Bit ins Carry. Der einzige>Unterschied zwischen LSx und ROx besteht darin, was nachgeschoben wird.>Schändlich wird es, wenn man dann lauthals Falschinformationen>verbreitet.
Da ich, zugegebenermaßen, das nicht wusste, habe ich im Datenblatt eines
mega8 nachgeschaut: siehe Anhang.
Dort ist eindeutig zu erkennen, dass ROx durch das Carry schiebt, aber
in der Funtkionsbeschreibung von LSx taucht das C nicht auf.
Da das offenbar eine falsche Information meinerseits war, ziehe ich
diese zurück.
Aber, bitte einen anderen Ton.
Auch ich habe mich kurz gefragt, ob Assemblerprogrammieren irgendwie
aggresiv macht... ;-)
DANKE Jörg!
Ich finde fundierte Codebeispiele und deine Taktzyklenberechnung
wesentlich hilfreicher als Hinweise wie "Datenblatt lesen!".
Nur der Vollständigkeit halber:
Aus der Hilfe im AVR Studio:
"LSL - Logical Shift Left
Description:
Shifts all bits in Rd one place to the left. Bit 0 is cleared. Bit 7 is
loaded into the C flag of the SREG."
Damit wär dann alles geklärt hoffe ich.
Sebastian
Bemerkenswert finde ich den Assemblercode dern "der Compiler" (welcher
war das?) erzeugt.
Insbesondere der Code welcher für die letzte Zeile:
1
n=((n>>4)&0x0f)|((n<<4)&0xf0);
erzeugt wird ist, wenn ich das richtig sehe, eigentlich unnötig lang.
1
MOV R25,R24 ;Copy register
2
SWAP R25 ;Swap nibbles
3
ANDI R25,0xF0 ;Logical AND with immediate
4
SWAP R24 ;Swap nibbles
5
ANDI R24,0x0F ;Logical AND with immediate
6
OR R24,R25 ;Logical OR
7
CLR R25 ;Clear Register
8
RET ;Subroutine return
In der Wirkung vertauscht dieser Code ja die beiden Nibbles.
Tatsächlich aber ist das 1:1 übersetzen der C-Zeile hier unnötig,
da bereits das SWAP auch die Nibbles vertauscht.
Es könnte also
1
SWAP R24 ;Swap nibbles
2
CLR R25 ;Clear Register
3
RET ;Subroutine return
heissen.
Ich wollte nämlich selbst mal nachschauen ob WinAVR das merkt. Leider
habe ich es allerdings nicht installiert.
Daher bitte nochmal die Frage an Matthias Lipinsky welchen Compiler er
verwendet hat.
Hab da mal 'ne Verständnisfrage und zwar kann doch das &0x0f und das
&0xf0 weggelassen werden, weil, wie mir bekannt, doch ursprünglich nicht
vorhandene Bits eh als 0 angenommen werden.
>
@ Sven
Ja, ich denke Du hast Recht. In K&R, Hanser, 1983, S. 50 steht das beim
schieben nach links Nullen nachgeschoben werden und beim schieben nach
rechts eines unsigned auch. (Nur bei signed ist das nachgeschobene Bit
nicht definiert).
Also könnte der Code von Peter Danneger tatsächlich so verbessert
werden.
1
unsignedcharmirror(unsignedcharn)
2
{
3
n=((n>>1)&0x55)|((n<<1)&0xaa);
4
n=((n>>2)&0x33)|((n<<2)&0xcc);
5
n=(n>>4)|(n<<4);
6
returnn;
7
}
Würde mich mal interessieren was da an Asssemblercode rauskommt. Kann
das mal einer durchjagen? (Vor allem wegen dem SWAP interessiert mich
das).
Danke Matthias und Jörg
Witzig finde ich ja, das er aus dem auf C-Ebene "optimierten" Code einen
ASM-Code macht, der drei Register braucht, anstelle von zweien und dann
in der Variante von Jörg mit dem händischem SWAP wieder nur zwei.
Hi
>Nur bei signed ist das nachgeschobene Bit nicht definiert
Für Rechtsschieben von Signed existiert ein eigener Assemblerbefehl:
'asr'.
Dabei wird bei jedem Schieben Bit7 wieder nach Bit7 kopiert. Damit
bleibt das Vorzeichen erhalten.
MfG Spess
@ Spess53
>>Nur bei signed ist das nachgeschobene Bit nicht definiert>Für Rechtsschieben von Signed existiert ein eigener Assemblerbefehl:>'asr'.
Vollständiges Zitat:
>Ja, ich denke Du hast Recht. In K&R, Hanser, 1983, S. 50 steht das beim>schieben nach links Nullen nachgeschoben werden und beim schieben nach>rechts eines unsigned auch. (Nur bei signed ist das nachgeschobene Bit>nicht definiert).
Hi
>In K&R, Hanser, 1983...
Vielleicht nicht mehr 100%-ig Up-To-Date. Bist du sicher, das das auch
für GCC gilt. Das würde mich schwer enttäuschen und wäre ein weitere
Grund nicht auf C umzusteigen.
MfG Spess
P.S. Ich halte den Hanser-Verlag für relativ seriös, aber ich habe auch
gelernt (manchmal schmerzhaft), das man nicht alles glauben soll, was
geschrieben steht.