требуется три инструкции для r0 & = 0xFFFF
mov r3,#0x00FF
orr r3,r3,#0xFF00
and r0,r0,r3
Так что сдвиг назад и вперед более эффективен.
То, что вы, возможно, делаете, связано с 16-битной переменной, поэтому, чтобы быть точным, компилятор должен обрезать верхние биты, чтобы программа работала правильно. если бы вы использовали int или что-то еще, возможно, он этого не сделал, не уверен, что именно так вы спровоцировали эти инструкции.
Иногда вы увидите, что это делается для расширения знака, но это был не арифметический сдвиг, это был логический сдвиг (нули идут не в бите переноса).
Возможно, ваш код сделал что-то вроде if (hello & 0xFFFF) затем.
ARM не обновляет флаги обычным образом, если вы не укажете это, из соображений производительности, если ничего больше не код, подобный этому
if(a&0xFF) b=0x12; else b=0x34;
would be something like:
ands r0,r0,#0xFF
movne r1,#0x12
moveq r1,#0x34
В случае других процессоров флаги и всегда устанавливают флаги, а следующей инструкцией будет ветвь, вызывающая сброс канала.
ands r0,r0,#0xFF
bne notequal
mov r1,#0x12
b wasequal
notequal:
mov r1,#0x34
wasequal:
Гораздо брутальнее при исполнении. Многие процессоры также перезаписывают флаги с немедленным движением, чего не делает рука. (режим большого пальца - другая история).
Вместо только ветвей, имеющих условное поле, каждая инструкция на плече имеет условное поле, ветвь, если она равна, и, если она равна, добавьте, если равен, суб, если равен, ветвь, если установлен перенос, и если перенос установлен, и т. Д. И также инструкции, которые могут изменять флаги, имеют бит кода операции, который включает или отключает обновление флагов. Вы добавляете s к инструкции. и r0, r1, r2 нет, но and0, r1, r2 обновляют флаги.
Итак, ваши две инструкции сделали две вещи: обнулили верхние 16 бит регистра, а затем установили флаги для любого последующего условия. Для mov, который, скорее всего, был ветвью, если равен, или ветвью, если не равен. Как выглядел ваш исходный код, который сгенерировал это?