Operacje bitowe są absolutnie niezbędne podczas programowania rejestrów sprzętowych w systemach wbudowanych. Na przykład każdy procesor, którego kiedykolwiek używałem, ma jeden lub więcej rejestrów (zazwyczaj określony adres pamięci), które kontrolują, czy przerwanie jest włączone, czy wyłączone. Aby zezwolić na uruchomienie przerwania, zwykłym procesem jest ustawienie bitu aktywacji dla tego rodzaju przerwania, a co najważniejsze, nie modyfikowanie żadnego z pozostałych bitów w rejestrze.
Kiedy następuje przerwanie, zwykle ustawia się nieco w rejestrze statusu, aby pojedyncza procedura serwisowa mogła określić dokładną przyczynę przerwania. Testowanie poszczególnych bitów pozwala na szybkie dekodowanie źródła przerwań.
W wielu systemach wbudowanych całkowita dostępna pamięć RAM może wynosić 64, 128 lub 256 BYTES (czyli bajtów, a nie kilobajtów lub megabajtów). W tym środowisku często stosuje się jeden bajt do przechowywania wielu elementów danych, flag boolowskich itp., A następnie używa się operacji bitowych ustawić i przeczytać.
Od wielu lat pracuję z systemem łączności satelitarnej, w którym ładowność wiadomości wynosi 10,5 bajta. Aby jak najlepiej wykorzystać ten pakiet danych, informacje muszą być spakowane do bloku danych bez pozostawiania niewykorzystanych bitów między polami. Oznacza to szerokie wykorzystanie operatorów bitowych i shift, aby pobrać wartości informacji i zapakować je w przesyłany ładunek.
Zasadniczo używasz ich ze względu na rozmiar i szybkość. Operacje bitowe są niezwykle proste, a zatem zwykle szybsze niż operacje arytmetyczne. Na przykład, aby uzyskać zieloną część wartości rgb, podejście arytmetyczne to
(rgb / 256) % 256
. W przypadku operacji bitowych zrobiłbyś coś takiego(rgb >> 8) & 0xFF
. Ta ostatnia jest znacznie szybsza, a gdy już się do tego przyzwyczaisz, jest również łatwiejsza. Zasadniczo bardzo często pojawiają się operacje bitowe, gdy trzeba kodować / dekodować dane w zwarty i szybki sposób.źródło
BYTE g1 = (rgb / 256) % 256;
00E51013...C1 E9 08...shr ecx,8
00E51016...88 0C 24...mov byte ptr [esp],cl
Tego rodzaju operacje są często używane podczas pisania w systemach osadzonych, w których moc pamięci lub procesora jest ograniczona.
Na przykład, aby zaoszczędzić miejsce, możesz przechowywać wiele zmiennych w pojedynczej 8-bitowej zmiennej int, używając każdego bitu do reprezentowania wartości logicznej. Następnie potrzebujesz szybkiego sposobu ustawienia określonego bitu lub odzyskania wartości bitu.
Ogólnie rzecz biorąc, programując w językach wyższego poziomu, takich jak C # na komputerze stacjonarnym z gigabajtami pamięci, tak naprawdę nie przejmujesz się, że każdy z nich
bool
zajmuje cały bajt . Ale jeśli programujesz mikrokontroler w C z 2kb pamięci, liczy się każdy bit, więc zdolność spakowania 8 booli w jednym bajcie może być krytyczna.źródło
[Flags]
atrybut, który pozwala na użycieEnum
pola bitowego. Na przykładFont
maStyle
właściwość, która jest bitowym polem zawierającym pogrubienie, kursywę, podkreślenie i przekreślenie.Operacje bitowe są również często stosowane w kodekach wideo i audio z tego samego powodu, co we wbudowanej elektronice; możliwość spakowania pięciu flag i 11-bitowego timera w pół int jest bardzo przydatna, gdy chcesz stworzyć super wydajny kodek wideo.
W rzeczywistości MPEG 4 używa nawet wykładniczego kodowania Golomb dla pól o zmiennej długości bitów. Wartość, która miała 17 lub 19 bitów szerokości ostatniego pakietu, może mieć tylko trzy lub pięć bitów szerokości tego pakietu - i można to wszystko zrozumieć przy operacjach bitowych.
źródło
Sztuczki, które łączą bitowe operacje logiczne, operacje przesunięcia bitowego i operacje arytmetyczne, mogą zrozumieć osoby, które badały budowę sumatora binarnego za pomocą bramek logicznych (i, lub nie). Poza tym kręgiem bardzo trudno jest zrozumieć bez szczegółowego komentarza.
Jest to przydatne podczas programowania jednostek SIMD , szczególnie jeśli architektura procesora celowo pominęła niektóre instrukcje SIMD, ponieważ mogą być one emulowane przez kilka innych.
Na przykład architektura może nie definiować żadnych instrukcji dotyczących pobierania wartości ujemnych z grupy 16 bajtów, ale które mogą być emulowane przez bitowe negowanie, a następnie dodawanie 1. Podobnie, odejmowanie można również pominąć, ponieważ można je emulować, biorąc negatyw drugiego operandu. Dostępność „alternatywnej trasy” jest powodem pominięcia niektórych instrukcji.
Podobnie, SIMD może obsługiwać tylko równoległe dodawanie 8-bitowe, bez implementowania dodawania dla szerszych elementów, takich jak 16-bit, 32-bit lub 64-bit. Aby je emulować, należy wyodrębnić bit znaku z wyniku obliczenia 8-bitowego, a następnie wykonać operację przenoszenia na następnym elemencie.
źródło
Pakowanie danych, szybsze operacje (mnożenie, dzielenie i moduł są znacznie szybsze, jeśli są dopasowane do potęg 2), odwracanie bitów itp. Naucz się ich i zacznij z nich korzystać, a sam zaczniesz powoli dostrzegać większość zalet.
źródło