Простой пример. Мы хотим записать биты «01» в самые правые биты регистра. Должны ли мы сбросить бит «0» и установить бит «1» отдельно? Есть ли способ сделать это в одной инструкции?
Например, если регистр имеет значение 0x11000002: самые правые биты — «10», а в конце должно быть 0x11000001: самые правые биты — «01», остальные биты остаются неизменными.
Я не думаю, что вы можете сделать это лучше, чем три инструкции:
@ set least 3 bits of R0 to 01
movs r1, #3
bics r0, r1 @ clear least two bits of R0
adds r0, #1 @ set LSB of R0
Если вы сделаете это в цикле, вы сможете вывести из цикла постоянную нагрузку для выполнения двух инструкций на итерацию.
Если у вас нет запасного регистра, вы также можете сделать
lsrs r0, #2 @ shift out least two bits of R0
lsls r0, #2 @ shift remaining bits back into position
adds r0, #1 @ set LSB of R0
Это занимает те же 3 цикла, что и описанный выше подход, но для этого не требуется отдельный регистр. Медленнее, если вы можете поднять постоянный груз из петли.
На Cortex-M3 или лучше вы действительно можете сделать это всего за две инструкции:
movs r1, #1
bfi r0, r1, #0, #2 @ insert least two bits of R1 into R0
Есть и другие варианты, например
bic r0, #3
adds r0, #1
если вы не хотите использовать дополнительный регистр, но лучше всего использовать приведенный выше регистр, если вы можете вывести постоянную загрузку из цикла.
godbolt использует
bic
для очистки одного, а затемorr
для установки другого.