Переменный битовый сдвиг
Я ищу сдвинуть бит регистра n раз влево, указанный другим регистром. Например, что-то вроде этого
shl eax, ebx
Единственная проблема заключается в том, что второй операнд не может быть регистром, он должен быть непосредственным значением. Как бы я мог сдвинуть регистр на значение, не известное во время сборки?
1 ответ
В x86 вы можете указать количество смен в реестре cl
, Так shl eax, cl
является действительным.
mov ecx, ebx
shl eax, cl
Обратите внимание, что вы можете использовать только cl
зарегистрироваться, а не eax
или любой другой регистр.
Кроме того, счетчик сдвигов больше 31 выполняется по модулю 32. (Не по модулю размера операнда, поэтому такие узкие сдвиги как shl ax, 20
может сдвинуть все биты и оставить нулевой пункт назначения. 64-битные сдвиги маскируют счет с & 63
Впрочем, так shl rax, 32
(или с 32 в кл) возможно. Смотрите инструкцию Intel дляshl
).
Расширение набора команд BMI2 поддерживает сдвиги со счетчиком в любом регистре, которые не обновляют EFLAGS, поэтому они более эффективны для подсчета переменных:
; if BMI2 is supported
shlx edx, eax, ebx ; edx = eax << (ebx&31)
Он доступен только на некоторых процессорах Haswell+ и процессорах Excavator / Ryzen, поэтому его нельзя использовать в полностью переносимом коде.