Полезные инструкции

Даже если вы не пишете на языке ассемблера, просматривайте иногда инструкции ядра: среди них можно отыскать интересные. При этом не все эти инструкции доступны напрямую синтаксисом Си, но их можно вызывать как 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.


Изменено: