сдвиг влево, а затем сразу сдвиг вправо в асм? - PullRequest
1 голос
/ 16 августа 2010

отказ от ответственности: я новичок в ассм.Мне, вероятно, нужно пересмотреть мое дополнение 2s или что-то, чтобы полностью понять: (

Я запутался в отношении цели следующего:

....
BL some_func
MOV R3, R0,LSL#16
MOVS R3, R3,LSR#16
....

почему сдвиг назад??

Ответы [ 2 ]

3 голосов
/ 16 августа 2010

требуется три инструкции для 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, который, скорее всего, был ветвью, если равен, или ветвью, если не равен. Как выглядел ваш исходный код, который сгенерировал это?

2 голосов
/ 16 августа 2010

При сдвиге влево переполненные биты будут потеряны. Поэтому все биты выше 32-16 = 16-ая цифра будут обнуляться после сдвига вправо.

     r0 =                   aaaabbbbccccdddd eeeeffffgggghhhh
lsl, 16 -> aaaabbbbccccdddd eeeeffffgggghhhh 0000000000000000
             (overflowed)
        ->                  eeeeffffgggghhhh 0000000000000000
lsr, 16 ->                                   eeeeffffgggghhhh

Инструкция эквивалентна

r3 = r0 & 0xffff;
...