Полезные инструкции
Даже если вы не пишете на языке ассемблера, просматривайте иногда инструкции ядра: среди них можно отыскать интересные. При этом не все эти инструкции доступны напрямую синтаксисом Си, но их можно вызывать как intrinsic-функции (эти обертки содержаться в библиотеке CMSIS). Такие функции могут быть полезны при обработке данных и заменять целые участки кода. Рассмотрим реализацию алгоритма изменения порядка следования битов справа налево на языке Си.
// Bit Twiddling Hacks, https://graphics.stanford.edu/~seander/bithacks.html
uint32_t swap_word(uint32_t word) {
// swap odd and even bits
word = ((word >> 1) & 0x55555555) | ((word & 0x55555555) << 1);
// swap consecutive pairs
word = ((word >> 2) & 0x33333333) | ((word & 0x33333333) << 2);
// swap nibbles ...
word = ((word >> 4) & 0x0F0F0F0F) | ((word & 0x0F0F0F0F) << 4);
// swap bytes
word = ((word >> 8) & 0x00FF00FF) | ((word & 0x00FF00FF) << 8);
// swap 2-byte long pairs
word = ( word >> 16 ) | ( word << 16);
return word;
}
Здесь выполняется много операций — компилятор создаст целую портянку ассемблер-команд. Когда потребуется перевернуть сотни или тысячи чисел, выполнение займет изрядное количество времени. В действительности достаточно воспользоваться одной инструкцией процессора, имеющейся в ядре Cortex-M3, которая обернута в функцию __RBIT
в файле core_cmInstr.h
:
a = __RBIT(a);
Список подобных инструкций можно найти в документации ARM.