Zamiast pytać o to jak odwołać się do tego rejestru (co prawda można tworząc zmienną przez [register unsigned char jakas_zmienna asm("r16");]), to powinieneś zastanowić się, czy kompilator nie wtrąci instrukcji organizacyjnych pomiędzy wstawki lub czy nie usunie wstawek (brak volatile i powiązania ze zmiennymi). Jeśli już chcesz korzystać z assemblera, to albo robisz cały fragment w asm, albo cały moduł w asm (dla mnie łatwiej jest zrobić cały moduł).
Kod w C po skompilowaniu też może wymagać rejestrów jak i flag, przez co zakłada się, że pomiędzy wstawkami rejestry tracą swoją wartość (chyba, że do wstawki przekazano zmienne bezpośrednio lub pośrednio). Dla przykładu sprawdzenie "PS_WEJ&0x01" wymagać będzie wczytania PS_WEJ do rejestru (nie wiesz którego), maskowania bitu (aktualizacja flagi Z) i skoku (kompilator nie rozwinie tego na sbic/sbis, gdyż nie może nic zakładać co do liczby instrukcji wstawki). Co prawda nie następuje tutaj zmiana flagi C, ale nigdy nie wiadomo do czego kompilator sprowadzi kod. Jeśli jesteś zmuszony do wykorzystania wstawek, to napisz cały fragment, kod będzie pewniejszy. Jeśli nie, to czy wstawki są aż tak bardzo potrzebne? Podany przez Ciebie kod można zapisać tak:
jakas_zmienna >>= 1;
if(PS_WEJ&0x01)
jakas_zmienna |= 0x80;
nie tracąc na szybkości (3 cykle przy rejestrze IO dostępnym przez sbic/sbis, 3 przy innym rejestrze [sbrc/sbrs], 5 przy komórce pamięci). Ze względu na skrajny bit można to zoptymalizować, kiedy zmienna jest w rejestrze, wtedy można zejść do 2 cykli przez wysunięcie bitu do C a potem przesunięcie do właściwego rejestru.
Tak więc albo piszesz całość w C (kiedy kompilator potrafi sobie zoptymalizować kod), albo piszesz całość (większy fragment) w asm, kiedy to Ty sobie optymalizujesz całość. Rama na C i pojedyncze instrukcje w asemblerze to najgorsze co można zrobić, kompilator nie ma jak zoptymalizować kodu w C, jak i nie ma możliwości mu w tym pomóc.
Jeśli korzystasz z gcc:
GCC-AVR Inline Assembler Cookbook