Hallo Joachim,
was dir der Bastian geschrieben hat, ist schon eine übersichtliche Lösung. Ob's mit Maschinensprache schneller/"besser" geht, kann ich nicht sagen - kommt darauf an, wie Bastian's Lösung vom Bascom-Compiler umgesetzt wird.
Die (oder besser EINE) Lösung in Assembler zeichnet sich allerdings durch eine "gewisse Eleganz und Allgemeingültigkeit" aus.
Praktisch jeder Prozessor, also auch der AVR, besitzt Befehle zum Verschieben der Bits innerhalb eines Registers um eine Position. Beim AVR heißt der Befehl "ROR" (ROtate (through Carry) Right) für eine Position nach rechts und "ROL" (ROtate (through Carry) Left) für die Verschiebung um eine Position nach links. Praktisch wird im ersten Fall der Wert im Register halbiert, im zweiten Fall verdoppelt. Was man allerdings noch zu beachten hat, ist, dass z.B. beim Rechtsschieben das unterste Bit ja "herausfällt" (ähnliches gilt beim Linksschieben). Um diesen "Übertrag" zu berücksichtigen, hat der Prozessor ein sogenanntes Übertragsbit (neudeutsch: Carryflag) im Statusregister. Falls also das unterste Bit gesetzt war, ist es nach dem "rotieren" im Carryflag gelandet.
Den Zustand des Statusregisters kann man natürlich abfragen und entsprechend den Flags Verzweigen (auf neudeutsch: conditional branches). Die Sprungbefehle, die hioer relevant sind, betreffen natürlich das Carry-Flag:
BRCC = BRanch Carry Clear (=verzweige bei gelöschtem Carry Flag) und
BRCS = BRanch Carry Set (=verzweige bei gesetztem Carry Flag).
Genau das können wir ausnutzen. Dein Code könnte also folgendermaßen aussehen:
Code:
LDS R1,{Test} ' (Byte-)Variable Test in's Register "R1" laden
ROR R1 ' unterstes Bit in's Carry schieben
BRCC CheckBit1 ' Sprung, falls nicht gesetzt
PUSH R1 ' aktuellen Wert (Test DIV 2) merken
CALL RoutineBit0 ' Routine für gesetztes Bit "0" aufrufen
POP R1 ' gemerkten Wert zurückholen und
CheckBit1: ' mit nächstem Bit weiter machen
ROR R1
BRCC CheckBit2
PUSH R1
CALL RoutineBit1
POP R1
......
'.....................................................................
RoutineBit0:
......
RETURN
'.....................................................................
RoutineBit1:
......
RETURN
'.....................................................................
Die zugehörigen Unterprogramme brauchst du auch nicht irgendwie deklarieren - die Angabe eines Labels reicht völlig. Abschließen mußt du es mit einem "RETURN" (der Maschinensprachebefehl "CALL" ist identisch zum Basic-"GOSUB").
Grüße
Werner